hibernate使用视图
- 格式:wps
- 大小:42.00 KB
- 文档页数:7
SpringMVC+Spring+Hibernate框架整合原理,作⽤及使⽤⽅法SSM框架是spring MVC ,spring和mybatis框架的整合,是标准的MVC模式,将整个系统划分为表现层,controller层,service层,DAO层四层使⽤spring MVC负责请求的转发和视图管理spring实现业务对象管理,mybatis作为数据对象的持久化引擎原理:SpringMVC:1.客户端发送请求到DispacherServlet(分发器)2.由DispacherServlet控制器查询HanderMapping,找到处理请求的Controller3.Controller调⽤业务逻辑处理后,返回ModelAndView4.DispacherSerclet查询视图解析器,找到ModelAndView指定的视图5.视图负责将结果显⽰到客户端Spring:我们平时开发接触最多的估计就是IOC容器,它可以装载bean(也就是我们中的类,当然也包括service dao⾥⾯的),有了这个机制,我们就不⽤在每次使⽤这个类的时候为它初始化,很少看到关键字new。
另外spring的aop,事务管理等等都是我们经常⽤到的。
Mybatis:mybatis是对jdbc的封装,它让数据库底层操作变的透明。
mybatis的操作都是围绕⼀个sqlSessionFactory实例展开的。
mybatis通过配置⽂件关联到各实体类的Mapper⽂件,Mapper⽂件中配置了每个类对数据库所需进⾏的sql语句映射。
在每次与数据库交互时,通过sqlSessionFactory拿到⼀个sqlSession,再执⾏sql命令。
使⽤⽅法:要完成⼀个功能:1. 先写实体类entity,定义对象的属性,(可以参照数据库中表的字段来设置,数据库的设计应该在所有编码开始之前)。
2. 写Mapper.xml(Mybatis),其中定义你的功能,对应要对数据库进⾏的那些操作,⽐如 insert、selectAll、selectByKey、delete、update等。
hibernate的基本用法Hibernate是一个开源的Java框架,用于简化数据库操作。
它为开发人员提供了一个更加简单、直观的方式来管理数据库,同时也提高了应用程序的性能和可维护性。
本文将逐步介绍Hibernate的基本用法,包括配置、实体映射、数据操作等。
一、配置Hibernate1. 下载和安装Hibernate:首先,我们需要下载Hibernate的压缩包并解压。
然后将解压后的文件夹添加到Java项目的构建路径中。
2. 创建Hibernate配置文件:在解压后的文件夹中,可以找到一个名为"hibernate.cfg.xml"的文件。
这是Hibernate的主要配置文件,我们需要在其中指定数据库连接信息和其他相关配置。
3. 配置数据库连接:在"hibernate.cfg.xml"文件中,我们可以添加一个名为"hibernate.connection.url"的属性,用于指定数据库的连接URL。
除此之外,还需要指定数据库的用户名和密码等信息。
4. 配置实体映射:Hibernate使用对象关系映射(ORM)来将Java类映射到数据库表。
我们需要在配置文件中使用"mapping"元素来指定实体类的映射文件。
这个映射文件描述了实体类与数据库表之间的对应关系。
二、实体映射1. 创建实体类:我们需要创建一个Java类,用于表示数据库中的一行数据。
这个类的字段通常与数据库表的列对应。
同时,我们可以使用Hibernate提供的注解或XML文件来配置实体的映射关系。
2. 创建映射文件:可以根据个人喜好选择使用注解还是XML文件来配置实体类的映射关系。
如果使用XML文件,需要创建一个与实体类同名的XML文件,并在其中定义实体类与数据库表之间的映射关系。
3. 配置实体映射:在配置文件中,我们需要使用"mapping"元素来指定实体类的映射文件。
Struts的原理和优点.Struts工作原理MVC即Model—View—Controller的缩写,是一种常用的设计模式。
MVC 减弱了业务逻辑接口和数据接口之间的耦合,以及让视图层更富于变化。
MVC的工作原理,如下图1所示:Struts 是MVC的一种实现,它将Servlet和JSP 标记(属于J2EE 规范)用作实现的一部分。
Struts继承了MVC的各项特性,并根据J2EE的特点,做了相应的变化与扩展.Struts的工作原理,视图:主要由JSP生成页面完成视图,Struts提供丰富的JSP 标签库: Html,Bean,Logic,Template等,这有利于分开表现逻辑和程序逻辑。
控制:在Struts中,承担MVC中Controller角色的是一个Servlet,叫ActionServlet。
ActionServlet是一个通用的控制组件。
这个控制组件提供了处理所有发送到Struts的HTTP请求的入口点。
它截取和分发这些请求到相应的动作类(这些动作类都是Action类的子类)。
另外控制组件也负责用相应的请求参数填充Action From(通常称之为FromBean),并传给动作类(通常称之为ActionBean)。
动作类实现核心商业逻辑,它可以访问java bean 或调用EJB。
最后动作类把控制权传给后续的JSP 文件,后者生成视图。
所有这些控制逻辑利用Struts-config.xml文件来配置。
模型:模型以一个或多个java bean的形式存在。
这些bean分为三类:Action Form、Action、JavaBean or EJB.Action Form通常称之为FormBean,封装了来自于Client的用户请求信息,如表单信息。
Action通常称之为ActionBean,获取从ActionSevlet传来的FormBean,取出FormBean中的相关信息,并做出相关的处理,一般是调用Java Bean或EJB等。
简述hibernate查询数据库的步骤Hibernate是一个开源的Java持久化框架,它可以帮助开发者简化数据库操作,提高开发效率。
在Hibernate中,查询数据库是非常常见的操作,本文将以标题的方式,简述Hibernate查询数据库的步骤。
一、配置Hibernate在开始使用Hibernate查询数据库之前,首先需要进行Hibernate 的配置工作。
包括创建Hibernate配置文件(hibernate.cfg.xml),配置数据库连接信息、数据库方言等。
同时,还需要配置实体类与数据库表之间的映射关系(Hibernate映射文件)。
二、创建SessionFactorySessionFactory是Hibernate的核心接口之一,它负责创建Session对象,是实现Hibernate查询的基础。
在Hibernate中,SessionFactory是线程安全的,通常一个应用程序只需要一个SessionFactory实例。
三、打开Session在进行数据库查询之前,需要先打开一个Session。
Session是Hibernate中的一个重要概念,它代表一个与数据库的会话。
可以通过SessionFactory的openSession方法来打开一个Session。
四、开始事务在进行数据库查询操作之前,通常需要开启一个事务。
通过调用Session的beginTransaction方法,开始一个事务。
事务的开启可以保证数据的一致性和完整性。
五、执行查询操作在Hibernate中,有多种查询方式可以选择。
常见的查询方式包括HQL查询、QBC查询和Native SQL查询。
HQL(Hibernate Query Language)是Hibernate提供的一种面向对象的查询语言,类似于SQL语句。
QBC(Criteria Query)是一种基于Criteria的查询方式,可以通过CriteriaBuilder来构建查询条件。
谈谈你对mvc的理解MVC是Model—View—Controler的简称。
即模型—视图—控制器。
MVC是一种设计模式,它强制性的把应用程序的输入、处理和输出分开。
MVC中的模型、视图、控制器它们分别担负着不同的任务。
视图: 视图是用户看到并与之交互的界面。
视图向用户显示相关的数据,并接受用户的输入。
视图不进行任何业务逻辑处理。
模型: 模型表示业务数据和业务处理。
相当于JavaBean。
一个模型能为多个视图提供数据。
这提高了应用程序的重用性控制器: 当用户单击Web页面中的提交按钮时,控制器接受请求并调用相应的模型去处理请求。
然后根据处理的结果调用相应的视图来显示处理的结果。
MVC的处理过程:首先控制器接受用户的请求,调用相应的模型来进行业务处理,并返回数据给控制器。
控制器调用相应的视图来显示处理的结果。
并通过视图呈现给用户。
项目中为什么使用SSH1. 使用Struts是因为struts是基于MVC模式的,很好的将应用程序进行了分层,使开发者更关注于业务逻辑的实现;第二,struts有着丰富的taglib,如能灵活运用,则能大大提高开发效率。
2. 使用Hibernate:因为hibernate为Java应用提供了一个易用的、高效率的对象关系映射框架。
hibernate 是个轻量级的持久性框架,功能丰富。
3. 使用Spring:因为spring基于IoC(Inversion of Control,反向控制)和AOP构架多层j2ee系统的框架,但它不强迫你必须在每一层中必须使用Spring,因为它模块化的很好,允许你根据自己的需要选择使用它的某一个模块;采用IoC使得可以很容易的实现bean的装配,提供了简洁的AOP并据此实现事务管理(Transcation Managment),等等struts如何实现国际化以下以两国语言(中文,英文)为例:1. 在工程中加入Struts支持2. 编辑ApplicationResource.properties文件,在其中加入要使用国际化的信息, 例如: lable.welcome.china=Welcome!!!3. 创建英文资源文件ApplicationResource_en.properites4. 创建临时中文资源文件ApplicationResource_temp.properites 例如:lable.welcom.china=中国欢迎您!5. 对临时中文资源文件进行编码转换。
SpringMVC的搭建一直以来接触到的都是SSH的框架,形成了MVC模式,本来并没有想着去弄另一个MVC模式,但现在springMVC模式很热,所以我也学习一下,首先我声明一下,这个框架我也是在网上找了一些资料才完成的,源文件等也是利用的网上的现成的,但是有对其进行修改。
下面来详细的说一说这个模式的搭建。
首先在spring中是以controller来作为控制器(相当于SSH中的action),其他的和SSH框架没有区别。
因为Spring是基于注解的,所以在整个的模式中都是采用注解的方式来处理,这个项目是用springMVC+hibernate一起来搭建的。
这个项目的搭建我花了很久的时间,也弄了蛮久才成功,希望日后能更加完善!理解更加的深入。
一:整体框架的结构图以及所需的jar包。
这里spring是3.0.1,hibernate是用的3.6,数据库是用的mysql 5.6 ,前提工作是要建立好一个数据库,我这里是名为springmvc的数据库来进行操作,这里是采用的hibernate自动更新的方式,所以可以不需要建表只需要建立起数据库就好。
项目框架的代码结构:二:开始搭建环境。
1,首先把上面所需的包添加进来后,我们要在/WEB-INF目录下的web.xml里面添加spring的监听器,以及相关的配置。
源码如下:<?xml version="1.0"encoding="UTF-8"?><web-app version="2.5"xmlns="/xml/ns/javaee"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/xml/ns/javaee/xml/ns/javaee/web-app_2_5.xsd"><display-name>s3h3</display-name><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext*.xml</param-value> </context-param><listener><listener-class>org.springframework.web.context.ContextLoaderList ener</listener-class></listener><servlet><servlet-name>spring</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</se rvlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring-servlet.xml</param-value> </init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>spring</servlet-name><!-- 这里在配成spring,下边也要写一个名为spring-servlet.xml的文件,主要用来配置它的controller --> <url-pattern>*.do</url-pattern></servlet-mapping><welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file><welcome-file>default.html</welcome-file><welcome-file>default.htm</welcome-file><welcome-file>default.jsp</welcome-file></welcome-file-list></web-app>2,接下来可以编写spring的配置文件,来整合hibernate,主要的配置写在一个专门存放配置文件的源码目录下config文件夹下,这里的applicationContext.xml是spring的主要配置文件,包括数据源等的配置。
Hibernate工作原理及为什么要用?一原理:1.读取并解析配置文件2.读取并解析映射信息,创建SessionFactory3.打开Sesssion4.创建事务Transaction5.持久化操作6.提交事务7.关闭Session。
8.关闭SessionFactory为什么要用:1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。
他很大程度的简化DAO层的编码工作3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。
4. hibernate的性能非常好,因为它是个轻量级框架。
映射的灵活性很出色。
它支持各种关系数据库,从一对一到多对多的各种复杂关系。
二Hibernate 的核心接口及其作用1 Configuration类:配置Hibernate启动Hibernate创建SessionFactory对象2 SessionFactory:初始化Hibernate创建Session对象线程安全—同一实例被多个线程共享重量级:代表一个数据库内部维护一个连接池2.1 openSession():总是创建新的session,需要手动close()2.2 getCurrentSession() : 必须在hibernate.cfg.xml设置session 上下文事务自动提交并且自动关闭session.从上下文环境中获得session,如果当时环境中不存就创建新的.如果环境中存在就使用环境中的,而且每次得到的都是同一个session (在session提交之前,提交之后就是新的了) 应用在一个session中有多个不同DAO操作处于一个事务时3 Session:负责保存、更新、删除、加载和查询对象轻量级--可以经常创建或销毁3.1 Load与get方法的区别:简单理解:load是懒加载,get是立即加载.load方法当使用查出来的对象时并且session未关闭,才会向数据库发sql, get会立即向数据库发sql返回对象3.3 merge(); 合并对象更新前会先select 再更新3.4clear()清空缓存,flush()将session中的数据同步到数据库两者组合使用于批量数据处理3.4Transaction commit() rollback()JPA: java persistence API 提供了一组操作实体bean的注解和API规范SchemaExporthiberante的生成数据库表(及其他ddl)的工具类可以通过这个工具类完成一些ddl四Hibernate查询查询语言主要有:HQL 、QBC (Query By Criteria条件查询) 、 Native SQLHql:1、属性查询2、参数查询、命名参数查询3、关联查询4、分页查询5、统计函数五优化抓取策略连接抓取(Join fetching)使用 OUTER JOIN(外连接)来获得对象的关联实例或者关联集合查询抓取(Select fetching)另外发送一条 SELECT 语句抓取当前对象的关联实体或集合另外可以配置hibernate抓取数量限制批量抓取(Batch fetching)另外可以通过集合过滤来限制集合中的数据量使用session.createFilter(topic.getReplies(),queryString).list();检索策略延迟检索和立即检索(优先考虑延迟检索)N+1问题指hibernate在查询当前对象时查询相关联的对象查询一端时会查询关联的多端集合对象解决方案:延迟加载连接抓取策略二级缓存集合过滤 BatchSize限制记录数量映射建议使用双向一对多关联,不使用单向一对多灵活使用单向一对多关联不用一对一,用多对一取代配置对象缓存,不使用集合缓存一对多集合使用Bag,多对多集合使用Set继承类使用显式多态表字段要少,表关联不要怕多,有二级缓存撑腰Hibernbate缓存机制性能提升的主要手段Hibernate进行查询时总是先在缓存中进行查询,如缓存中没有所需数据才进行数据库的查询.Hibernbate缓存:一级缓存 (Session级别)二级缓存(SessionFactory级别)查询缓存 (基于二级缓存存储相同参数的sql查询结果集)一级缓存(session缓存)Session缓存可以理解为session中的一个map成员, key为OID ,value为持久化对象的引用在session关闭前,如果要获取记录,hiberntae先在session缓存中查找,找到后直接返回,缓存中没有才向数据库发送sql三种状态的区别在于:对象在内存、数据库、session缓存三者中是否有OID临时状态内存中的对象没有OID, 缓存中没有OID,数据库中也没有OID 执行new或delete()后持久化状态内存中的对象有OID, 缓存中有OID,数据库中有OIDsave() load() get() update() saveOrUpdate() Query对象返回的集合游离(脱管)状态内存中的对象有OID, 缓存中没有OID,数据库中可能有OIDflush() close()后使用session缓存涉及三个操作:1将数据放入缓存2从缓存中获取数据3缓存的数据清理4二级缓存SessionFactory级别SessionFactory级别的缓存,它允许多个Session间共享缓存一般需要使用第三方的缓存组件,如: Ehcache Oscache、JbossCache等二级缓存的工作原理:在执行各种条件查询时,如果所获得的结果集为实体对象的集合,那么就会把所有的数据对象根据OID放入到二级缓存中。
Hibernate基础知识详解<hibernate-mapping><class name="*.*.*" table="t_customer" catalog="***"><id name="id" column="c_id"><generator class="identity"/></id><property name="name" column="c_name" length="20"/><set name="orders" inverse="false" cascade="save-update"><key column="c_customer_id"/></set></class></hibernate-mapping>(1)统⼀声明包名,这样在<class>中就不需要写类的全名。
(2)关于<class>标签配置name 属性:类的全名称table 表的名称,可以省略,这时表的名称就与类名⼀致catalog 属性:数据库名称可以省略.如果省略,参考核⼼配置⽂件中 url 路径中的库名称(3)关于<id>标签,<id>是⽤于建⽴类中的属性与表中的主键映射。
name 类中的属性名称column 表中的主键名称 column 它也可以省略,这时列名就与类中属性名称⼀致length 字段长度type 属性指定类型<generator>它主要是描述主键⽣成策略。
springboot使⽤视图modelandview1:springboot使⽤视图解析器,添加依赖<!-- freemarker模板引擎视图 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><!-- 热部署,不⽤重启,这个在这⾥不需要--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><!-- jsp解析器 --><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId><scope>provided</scope></dependency>2:主函数需要继承SpringBootServletInitializer,并覆盖其⽅法。
package com.liyafei;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.builder.SpringApplicationBuilder;import org.springframework.boot.web.support.SpringBootServletInitializer;@EnableAutoConfiguration@SpringBootApplication//返回jsp页⾯必须继承SpringBootServletInitializer类重写⾥⾯的⽅法public class Main extends SpringBootServletInitializer{public static void main(String[] args) {SpringApplication.run(Main.class, args);}protected SpringApplicationBuilder config(SpringApplicationBuilder applicationBuilder){return applicationBuilder.sources(Main.class);}}3:配置⽂件中添加spring.mvc.view配置,配置了视图解析器之后,controlller返回的String,View等就会先找视图解析器spring:datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/demousername: rootpassword: 1367356mvc:view:prefix: /WEB-INF/suffix: .jspmybatis:config-location: classpath:mybatis-config.xml4:controller映射package com.liyafei.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.view.json.MappingJackson2JsonView;import er;//这个注解不能使⽤RestController,不然会返回模板类型的页⾯@Controllerpublic class MyController {User user=new User();@RequestMapping("/my")public ModelAndView test(){ModelAndView mv=new ModelAndView();mv.setViewName("modelandview");mv.addObject("name", "liyafei");user.setAge(20);user.setName("wangwu");mv.addObject("user", user);//设置返回的数据为json类型,也可以不设置,返回对象 //mv.setView(new MappingJackson2JsonView());return mv;}@RequestMapping("index")public String index(){return "index";}}5:测试成功:6:⽬录结构。
②hibernate逆向生成之后的代码如下:CountView.java1. package com.yaxing.entity;2.3. /**4. * CountView entity. @author MyEclipse Persistence Tools5. */6.7. public class CountView implements java.io.Serializable {8.9. // Fields10.11. private CountViewId id;12.13. // Constructors14.15. /** default constructor */16. public CountView() {17. }18.19. /** full constructor */20. public CountView(CountViewId id) {21. this.id = id;22. }23.24. // Property accessors25.26. public CountViewId getId() {27. return this.id;28. }29.30. public void setId(CountViewId id) {31. this.id = id;32. }33.34. }CountViewId.java1. package com.yaxing.entity;2.3. /**4. * CountViewId entity. @author MyEclipse Persistence Tools5. */6.7. public class CountViewId implements java.io.Serializable {8.9. // Fields10.11. private Integer countAthlete;12. private Integer countTeam;13. private long eveId;14. private String race;15. private long userId;16. private long id;17.18. // Constructors19.20. /** default constructor */21. public CountViewId() {22. }23.24. /** minimal constructor */25. public CountViewId(long id) {26. this.id = id;27. }28.29. /** full constructor */30. public CountViewId(Integer countAthlete, Integer countTeam, long eveId,31. String race, long userId, long id) {32. this.countAthlete = countAthlete;33. this.countTeam = countTeam;34. this.eveId = eveId;35. this.race = race;36. erId = userId;37. this.id = id;38. }39.40. // Property accessors41.42. public Integer getCountAthlete() {43. return this.countAthlete;44. }45.46. public void setCountAthlete(Integer countAthlete) {47. this.countAthlete = countAthlete;48. }49.50. public Integer getCountTeam() {51. return this.countTeam;52. }53.54. public void setCountTeam(Integer countTeam) {55. this.countTeam = countTeam;56. }57.58. public long getEveId() {59. return this.eveId;60. }61.62. public void setEveId(long eveId) {63. this.eveId = eveId;64. }65.66. public String getRace() {67. return this.race;68. }69.70. public void setRace(String race) {71. this.race = race;72. }73.74. public long getUserId() {75. return erId;76. }77.78. public void setUserId(long userId) {79. erId = userId;80. }81.82. public long getId() {83. return this.id;84. }85.86. public void setId(long id) {87. this.id = id;88. }89.90. public boolean equals(Object other) {91. if ((this == other))92. return true;93. if ((other == null))94. return false;95. if (!(other instanceof CountViewId))96. return false;97. CountViewId castOther = (CountViewId) other;98.99. return ((this.getCountAthlete() == castOther.getCountAthlete()) || (this100. .getCountAthlete() != null101. && castOther.getCountAthlete() != null && this 102. .getCountAthlete().equals(castOther.getCountAthl ete())))103. && ((this.getCountTeam() == castOther.getCountTeam()) || (this104. .getCountTeam() != null105. && castOther.getCountTeam() != null && this106. .getCountTeam().equals(castOther.getCoun tTeam())))107. && (this.getEveId() == castOther.getEveId()) 108. && ((this.getRace() == castOther.getRace()) || (this.getRace() != null109. && castOther.getRace() != null && this.getRace()110. .equals(castOther.getRace())))111. && (this.getUserId() == castOther.getUserId()) 112. && (this.getId() == castOther.getId());113. }114.115. public int hashCode() {116. int result = 17;117.118. result = 37119. * result120. + (getCountAthlete() == null ? 0 : this.getCountAthlete()121. .hashCode());122. result = 37 * result123. + (getCountTeam() == null ? 0 : this.getCountTeam().hashCode());124. result = 37 * result + (int) this.getEveId();125. result = 37 * result126. + (getRace() == null ? 0 : this.getRace().hashCode());127. result = 37 * result + (int) this.getUserId();128. result = 37 * result + (int) this.getId();129. return result;130. }131.132. }我们知道,视图是没有主键的,视图就是一张虚拟表。
hibernate对没有主键的表逆向生成的时候,是会生成CountView.javaCountViewId.java两个类的,XxxId.java这个类里面的属性才是我们需要的数据.③映射文件如下:CountView.hbm.xml1. <?xml version="1.0" encoding="utf-8"?>2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD3.0//EN"3. "/hibernate-mapping-3.0.dtd">4. <!--5. Mapping file autogenerated by MyEclipse Persistence Tools6. -->7. <hibernate-mapping>8. <class name="com.yaxing.entity.CountView" table="countView" schema="dbo" catalog="sportSys">9. <composite-id name="id" class="com.yaxing.entity.CountViewId">10. <key-property name="countAthlete" type="integer">11. <column name="countAthlete" />12. </key-property>13. <key-property name="countTeam" type="integer">14. <column name="countTeam" />15. </key-property>16. <key-property name="eveId" type="long">17. <column name="eve_id" precision="18" scale="0" />18. </key-property>19. <key-property name="race" type="string">20. <column name="race" length="50" />21. </key-property>22. <key-property name="userId" type="long">23. <column name="userId" precision="18" scale="0" />24. </key-property>25. <key-property name="id" type="long">26. <column name="id" precision="18" scale="0" />27. </key-property>28. </composite-id>29. </class>30. </hibernate-mapping>④CountViewDaoImpl .java如下:1. package com.yaxing.daoImpl;2.3. import java.util.List;4.5. import org.hibernate.Query;6. import org.springframework.orm.hibernate3.support.HibernateDaoSupport;7.8. import com.yaxing.dao.CountViewDao;9. import com.yaxing.entity.CountView;10. import com.yaxing.util.PageModel;11.12. public class CountViewDaoImpl extends HibernateDaoSupport implements CountViewDao {13.14. @Override15. public List<CountView> listCountView() {16. // TODO Auto-generated method stub17. return this.getHibernateTemplate().find("select id.countAthlete,id.countTeam,id.race,id.eveId from CountView");18. }19.20. }可以看到第17行:1. return this.getHibernateTemplate().find("select id.countAthlete,id.countTeam,id.race,id.eveId from CountView");字段是id.countAthlete这种,因为CountView.java的11行1. private CountViewId id;我们这只有一个返回所有的List集合⑤Action中如下:1. public String listCountView() throws Exception {2. try {3. List allValue = this.countViewService.listCountView();4. listCountView = new ArrayList();5. Iterator it = allValue.iterator();6. while (it.hasNext()) {7. Object[] all = (Object[]) it.next();8. CountViewId countViewId = new CountViewId();9. countViewId.setCountAthlete((Integer) all[0]);10. countViewId.setCountTeam((Integer) all[1]);11. countViewId.setRace((String) all[2]);12. countViewId.setEveId( (Long)all[3]);13.14. listCountView.add(countViewId);15. }16.17. } catch (Exception e) {18. e.printStackTrace();19. return INPUT;20. }21. return SUCCESS;22.23. }第3行,如果直接写成1. listCountView = this.countViewService.listCountView();这个页面查询的是没有结果的!是因为:Hibernate 映射视图会生成联合主键.在查询时,如果联合主键里有一项值为null,则整个结果返回null。