**************第一章************ Hibernate是一个优秀的持久化框架 什么是持久化? 只有数据保存到数据库中 这个对象才称为 持久化对象 瞬时状态:保存在内存的程序数据,程序退出后,数据就消失了,称为瞬时状态 持久化:将程序数据在瞬时状态和持久状态之间转换的机制 持久状态:
保存在磁盘上的程序数据,程序退出后依然存在,称为程序数据的持久状态 什么是ORM? ORM(对象-关系映射): 完成对象数据到关系型数据映射的机制称为对象-关系映射,简称ORM。 是一个主流的持久化框架 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC46.tmp.png 在JDBC基础上进行分装 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC56.tmp.png 只需要少量代码就可以完成持久化工作 是一个优秀的ORM(对象-关系映射)机制 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC57.tmp.png 通过映射文件保存映射信息 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC58.tmp.png 在业务层以面向对象的方式编程,不用考虑数据保存形式 手工搭建Hibernate框架: 1. 导包最少依赖的 jar包) l 下载地址http://www.hibernate.org,本教程使用3.2.5。 l 将下载目录/hibernate3.jar和/lib下的hibernate运行时必须的包加入classpath中: antlr.jar,cglib.jar,asm.jar,commons-collections.jar,commons-logging.jar,jta.jar,dom4j.jar 2.添加Hibernate配置文件 hibernate.cfg.xml(模板 源代码/etc下) 打开 源代码 下 etc/ hibernate.cfg.xml 复制到 src路劲下 (注意:默认hibernate会在src下读取名称为hibernate.cfg.xml文件,这与Ibatis中SqlMapConfig.xml文件一样,主要配置数据库连接方式,打开数据库连接) <property name="dialect"> //表示数据库方言 不同数据库 方言不同 org.hibernate.dialect.MySQL5Dialect </property> // 表示是否显示 sql语句 <property name="show_sql">true</property> // 表示通过实体类映射 创建 数据库表 update/create <property name="hbm2ddl.auto">update</property> 3.添加实体类(例如:User类) com.hibernate.user.bean.User: public class User { private int uid; private String userName; private String password; public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } 4.实体类目录中添加 User.hbm.xml(模板在 源代码eg\org\hibernate\auction) <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping > <class name="com.hibernate.user.bean.User" table="t_user" > <id name="uid" type="int"> <column name="uid"></column> <!-- generator 主键生成器 Increment 表示 mysql 主键 并增长 Identity 表示 sqlserver 主键 并增长 Sequence 表示 oracle 主键 并增长 Native 表示兼容所有数据库 由hibernate 判断 --> <generator class="increment"></generator> </id> <property name="userName" type="java.lang.String"></property> <property name="password" type="java.lang.String"></property> </class> </hibernate-mapping> 5. hibernate.cfg.xml文件中添加 User..hbm.xml <mapping resource="com/hibernate/user/bean/User.hbm.xml" /> 6.创建UserDao 类 public class UserDao implements IUserDao { private static Session session; static { // 1.读取hibernate.cfg.xml文件 Configuration cfg=new Configuration().configure(); //2.创建sessionFactory SessionFactory sessionFactory= cfg.buildSessionFactory(); //3.打开session session=sessionFactory.openSession(); } } 1 .添加 (查看主键值是否返回) (User类) <property name="connection.autocommit">true</property> Hibernate开启自动提交功能 public void addUser(User user) {// 此时 为瞬时状态 //4.开启事物 Transaction tx= session.beginTransaction(); try { // 5.持久化到数据库 // session.save(user); session.persist(user);//持久化状态 //6. 提交事物 tx.commit(); } catch (HibernateException e) { e.printStackTrace(); tx.rollback(); }finally { //7. 关闭session session.close(); // 脱管状态 } } 测试: UserDao userDao=new UserDao(); User user =new User(); user.setPassword("zhangsan"); user.setUserName("张三"); userDao.addUser(user); 2.删除 public void deleteUser(int uid) { Transaction tr=session.beginTransaction(); try { User user=new User(); user.setUid(uid); session.delete(user); tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: userDao.deleteUser(1); 3.修改 public void updateUser(User user) { Transaction tr=session.beginTransaction(); try { session.update(user); //或者 //session.merge(user); tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: User user=new User(); user.setUid(2); user.setPassword("lisi"); user.setUserName("李四"); userDao.updateUser(user); 4.查询(查询单个对象) public User findUserByUid(int uid) { User user=(User) session.get(User.class, uid); session.close(); return user; } 测试: User user=userDao.findUserByUid(2); System.out.println(user.getUserName()+","+user.getPassword()); 5. load方法(懒加载)代理 public User findUserByUid1(int uid) { //注意 :我们的实体类不能加上 final 关键字 是因为 懒加载 会通过通过这个实体类 派生一个子类出来 实现懒加载(提供一个无参构造函数) //所以上面的user这个对象 永远不可能为null 如果没有查到懒加载也会生成一个子类对象 User user=(User)session.load(User.class, uid); System.out.println(user.getClass().getName()); //System.out.println(user.getPassword()); //Hibernate.initialize(user); session.close(); return user; } 测试: User user=userDao.findUserByUid1(2); System.out.println(user.getUserName()+","+user.getPassword()); 6. 更新或者保存 public void saveOrUpdateUser(User user) { Transaction tr=session.beginTransaction(); try { session.saveOrUpdate(user); tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: User user=new User(); user.setPassword("王五"); user.setUserName("wangwu1"); user.setUid(6); userDao.saveOrUpdateUser(user); 7.对象的状态(三个状态:瞬时状态,持久化状态,脱管状态) 8.如何动态生成表 领域模型 (oop思想 --->创建数据库表)(Teacher类) Teacher类:1.创建实体类 2. 创建 teacher.hbm.xml 3.hibernate.cfg.xml配置 在hibernate.cfg.xml 文件中添加如下内容: <property name="hbm2ddl.auto">update</property> 如何用Xdoclet+ant 生成映射文件: 如何开始使用Xdoclet?Xdoclet不是单独可以运行的工具(不像Ant工具),它可以与其它工具一起配合运行,如Ant。我们下面的例子就是基于Ant和xdoclet的。 1、 首先需要保证ant是可用的 2、 下载并解压xdoclet的包(我们现在使用的是xdoclet2,具体版本是xdoclet-plugins-1.0.3)。 3、 在ant构建工具中定义xdoclet任务,并使用: 如何开始使用Ant?1、 确保你的机器已经安装了JDK,确保你的path环境变量中包含有java虚拟机的运行程序,确保你的环境变量中有JAVA_HOME变量 2、 下载ant并解压 3、 设置ANT_HOME环境变量,指向ant解压根目录 4、 在path环境变量中,添加ANT_HOME\bin目录 5、 打开控制台,运行:ant 6、 如果能够运行ant(忽略这些异常:Buildfile: build.xml does not exist!),而不是出现诸如命令无法解释的错误,那么你的ant就安装成功了 1.创建com.hibernate.ant.bean包: Test类: /** * @hibernate.class * table="t_test" * @author Administrator * */ public class Test { /** * @hibernate.id * generator-class="native" */ private int id; /** * @hibernate.property */ private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } 2.Src下 放入build.xml文件: <?xml version="1.0" encoding="GBK"?> <project name="OA系统构建脚本" default="生成hibernate映射文件" basedir="."> <property name="src.dir" value="${basedir}/src"/> <property name="build.dir" value="${basedir}/bin"/> <property name="xdoclet.home" value="C:\xdoclet-plugins-1.0.3\xdoclet-plugins-1.0.3"/> <!-- Build classpath --> <path id="xdoclet.task.classpath"> <fileset dir="${xdoclet.home}/lib"> <include name="**/*.jar"/> </fileset> <fileset dir="${xdoclet.home}/plugins"> <include name="**/*.jar"/> </fileset> </path> <taskdef name="xdoclet" classname="org.xdoclet.ant.XDocletTask" classpathref="xdoclet.task.classpath" /> <target name="生成hibernate映射文件"> <xdoclet> <fileset dir="${src.dir}/com/hibernate/ant/bean"> <include name="**/*.java"/> </fileset> <component classname="org.xdoclet.plugin.hibernate.HibernateMappingPlugin" version="3.0" destdir="${src.dir}" /> </xdoclet> </target> </project> 3.MyEclipse-Window-show View –other –Ant-Add Buildfiles –run as –Ant build 9.传统模型 (表生成 实体类)(Student类) 用MyEclipse向导 (MyEclipse DB Brower) *************第二章*************** 1. 一对多, 多对一(Emp表,Dept表) Dept实体类: /** * 一对多 * @author Administrator * */ public class Dept { private int deptId; private String deptName;//部门名称 private Set<Emp> emps; public Dept(int deptId, String deptName, Set<Emp> emps) { this.deptId = deptId; this.deptName = deptName; this.emps = emps; } public Dept() { } public int getDeptId() { return deptId; } public void setDeptId(int deptId) { this.deptId = deptId; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } public Set<Emp> getEmps() { return emps; } public void setEmps(Set<Emp> emps) { this.emps = emps; } } Dept.hbm.xml文件: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping > <class name="com.hibernate.dept.bean.Dept" table="t_dept" > <id name="deptId" type="int"> <column name="deptId"></column> <generator class="native"></generator> </id> <property name="deptName" type="java.lang.String"></property> <set name="emps" inverse="true" cascade="delete,save-update" lazy="false"> <key column="dept_Id"></key> <one-to-many class="com.hibernate.emp.bean.Emp" /> </set> </class> </hibernate-mapping> Emp实体类: /** * 多对一 * @author Administrator * */ public class Emp { private int empId; private String empName; private Dept dept; public Emp(int empId, String empName, Dept dept) { this.empId = empId; this.empName = empName; this.dept = dept; } public Emp() { } public String getEmpName() { return empName; } public void setEmpName(String empName) { this.empName = empName; } public int getEmpId() { return empId; } public void setEmpId(int empId) { this.empId = empId; } public Dept getDept() { return dept; } public void setDept(Dept dept) { this.dept = dept; } } Emp.hbm.xml文件: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping > <class name="com.hibernate.emp.bean.Emp" table="t_emp" > <id name="empId" type="int"> <column name="empId"></column> <generator class="native"></generator> </id> <property name="empName" type="java.lang.String"></property> <many-to-one name="dept" column="dept_id" not-null="true"></many-to-one> </class> </hibernate-mapping> 实例: 1.一对多 添加Dept部门 DeptDao类: private static Session session; static{ //1.读取hibernate.cfg.xml文件 Configuration cfg=new Configuration().configure(); //2.绑定sessionFactoru SessionFactory sessionFactory= cfg.buildSessionFactory(); //3.打开 session session= sessionFactory.openSession(); } public void addDept(Dept dept) { //4. 开启事物 Transaction tr=session.beginTransaction(); try { //5. 持久化 session.persist(dept); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: DeptDao dd=new DeptDao(); Dept dept=new Dept(); dept.setDeptName("研发一部"); dd.addDept(dept); 2.多对一 添加Emp表 EmpDao类: private static Session session; static{ //1.读取hibernate.cfg.xml文件 Configuration cfg=new Configuration().configure(); //2.绑定sessionFactoru SessionFactory sessionFactory= cfg.buildSessionFactory(); //3.打开 session session= sessionFactory.openSession(); } public void addEmp(Emp emp) { Transaction tr=session.beginTransaction(); try { //5. 持久化 session.persist(emp); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: Emp emp=new Emp(); emp.setEmpName("李四"); Dept dept=new Dept(); dept.setDeptId(1); dept.setDeptName("研发一部"); emp.setDept(dept); ed.addEmp(emp); 3. 删除一个Dept部门 (同时删除部门下的人员) public void deleteDept(int deptId) { //4. 开启事物 Transaction tr=session.beginTransaction(); try { //5. 持久化 session.delete(session.get(Dept.class, deptId)); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } Dept.hbm.xml文件修改: <set name="emps" inverse="true" cascade="delete,save-update" lazy="false"> <key column="dept_Id"></key> <one-to-many class="com.hibernate.emp.bean.Emp" /> </set> 解释: inverse="true" inverse是“反转”的意思,表示关联关系的控制权。为true,表示由对方负责关联关系的添加和删除;为false,表示由自己负责维护关联关系。(是否放弃维护关联关系 true 放弃关系) cascade级联 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC7B.tmp.png all : 对所有操作都进行级联 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC7C.tmp.png none : 对所有操作都不进行级联 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC7D.tmp.png save-update : 执行添加更新操作时级联 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC7E.tmp.png delete : 执行删除操作时级联 lazy 表示懒加载 为false 关闭懒加载 为true 开启懒加载(默认) 4. 一对多添加Dept部门 同时添加人员 测试: Dept dept=new Dept(); dept.setDeptName("研发一部"); Emp emp1=new Emp(); emp1.setDept(dept); emp1.setEmpName("孙十"); Emp emp2=new Emp(); emp2.setDept(dept); emp2.setEmpName("钱九"); Set<Emp> emps=new HashSet<Emp>(); emps.add(emp1); emps.add(emp2); dept.setEmps(emps); dd.addDept(dept); 注意: cascade=”save-update”加上 5. 修改 人员 对应的部门 钱九 孙十 原来部门是 研发一部 现在 将钱九 孙十调到研发三部 public void updateDept(Dept dept) { //4. 开启事物 Transaction tr=session.beginTransaction(); try { //5. 持久化 session.update(dept); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: Dept dept=new Dept(); dept.setDeptId(3); dept.setDeptName("研发三部"); Emp emp=new Emp(); emp.setEmpId(7); emp.setEmpName("钱九"); emp.setDept(dept); Emp emp1=new Emp(); emp1.setEmpId(8); emp1.setEmpName("孙十"); emp1.setDept(dept); Set<Emp> emps=new HashSet<Emp>(); emps.add(emp); emps.add(emp1); dept.setEmps(emps); dd.updateDept(dept); 注意: cascade=”save-update”加上 6. 查询一个部门 并查询出当前部门所有人员 public Dept findDeptByDeptId(int deptId) { Dept dept=(Dept)session.get(Dept.class, deptId); session.close(); return dept; } 测试: Dept dept= dd.findDeptByDeptId(3); System.out.println("部门名称:"+dept.getDeptName()); System.out.println("部门人员:"); for(Emp emp : dept.getEmps()) { System.out.print(emp.getEmpName()+" "); } 以上针对 Demp表进行 增删改查操作 7. 多对一(Emp表) 删除(删除一个员工) 添加Emp 案例2已实现 EmpDao类: public void deleteEmp(Emp emp) { Transaction tr=session.beginTransaction(); try { //5. 持久化 session.delete(session.get(Emp.class, emp.getEmpId())); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: Emp emp=new Emp(); emp.setEmpId(2); ed.deleteEmp(emp); 8. 修改一个员工和部门 public void updateEmp(Emp emp) { Transaction tr=session.beginTransaction(); try { //5. 持久化 session.merge(emp); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: Emp emp=new Emp(); emp.setEmpId(6); emp.setEmpName("张三"); Dept dept=new Dept(); dept.setDeptId(3); dept.setDeptName("研发三部"); emp.setDept(dept); ed.updateEmp(emp); 9. 查询一个员工信息 并显示对应部门 public Emp findEmpByEmpId(int empId) { Emp emp=(Emp) session.get(Emp.class, empId); Hibernate.initialize(emp.getDept()); session.close(); return emp; } Emp emp=ed.findEmpByEmpId(6); System.out.println("员工:"+emp.getEmpName()); System.out.println("所在部门:"+emp.getDept().getDeptName()); 以上是Emp表 增删改查操作 2. 多对多(Student表,Teacher表)
1.创建Teacher,Student实体类 和 teacher.hbm.xml,student.hbm.xml com.hibernate.student.bean包: Student类: /** * 一对多 * @author Administrator * */ public class Student { private int studetnId; private String studentName; private Set<Teacher> teachers; public int getStudetnId() { return studetnId; } public void setStudetnId(int studetnId) { this.studetnId = studetnId; } public String getStudentName() { return studentName; } public void setStudentName(String studentName) { this.studentName = studentName; } public Set<Teacher> getTeachers() { return teachers; } public void setTeachers(Set<Teacher> teachers) { this.teachers = teachers; } } Student.hbm.xml文件: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping > <class name="com.hibernate.student.bean.Student" table="t_student" > <id name="studetnId" type="int"> <column name="studetnId"></column> <generator class="native"></generator> </id> <property name="studentName" type="java.lang.String"></property> <!—级联 添加学生允许添加/修改/删除老师 --> <set name="teachers" table="t_student_teacher" cascade="save-update,delete"> <!—t_student_teacher 表中 那个外键 与student 表studentId主键对应 --> <key column="student_id"></key> <many-to-many class="com.hibernate.teacher.bean.Teacher" column="teacher_id"></many-to-many> </set> </class> </hibernate-mapping> Teacher类: /** * 一对多 * @author Administrator * */ public class Teacher { private int teacherId; private String teacherName; private Set<Student> students; public int getTeacherId() { return teacherId; } public void setTeacherId(int teacherId) { this.teacherId = teacherId; } public String getTeacherName() { return teacherName; } public void setTeacherName(String teacherName) { this.teacherName = teacherName; } public Set<Student> getStudents() { return students; } public void setStudents(Set<Student> students) { this.students = students; } } Teacher.hbm.xml文件: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping > <class name="com.hibernate.teacher.bean.Teacher" table="t_teacher" > <id name="teacherId" type="int"> <column name="teacherId"></column> <generator class="native"></generator> </id> <property name="teacherName" type="java.lang.String"></property> <!—老师放弃维护关系 由学生维护 这时学生 才有权限t_student_teacher 表添加 修改权限 --> <set name="students" table="t_student_teacher" inverse="true" cascade="save-update,delete"> <key column="teacher_id"></key> <many-to-many class="com.hibernate.student.bean.Student" column="student_id"></many-to-many> </set> </class> </hibernate-mapping> 实例: 1. 添加一个学生 StudentDao类: private static Session session; static{ //1.读取hibernate.cfg.xml文件 Configuration cfg=new Configuration().configure(); //2.绑定sessionFactoru SessionFactory sessionFactory= cfg.buildSessionFactory(); //3.打开 session session= sessionFactory.openSession(); } public void addStudent(Student student) { //4. 开启事物 Transaction tr=session.beginTransaction(); try { //5. 持久化 session.persist(student); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: StudentDao sd=new StudentDao(); Student student =new Student(); student.setStudentName("张三"); sd.addStudent(student); 2.添加老师 TeacherDao类: private static Session session; static{ //1.读取hibernate.cfg.xml文件 Configuration cfg=new Configuration().configure(); //2.绑定sessionFactoru SessionFactory sessionFactory= cfg.buildSessionFactory(); //3.打开 session session= sessionFactory.openSession(); } public void addTeacher(Teacher teacher) { //4. 开启事物 Transaction tr=session.beginTransaction(); try { //5. 持久化 session.persist(teacher); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试 : TeacherDao td=new TeacherDao(); Teacher teacher=new Teacher(); teacher.setTeacherName("刘老师"); td.addTeacher(teacher); 3. 添加一个学生和老师 但是两者没有关系 如何建立关系呢? 设置 学生为 维护端(由于操作学生) teacher.hbm.xml set标签中添加 inverse="true" (老师放弃维护端 由学生来维护) public void update(Student student) { //4. 开启事物 Transaction tr=session.beginTransaction(); try { //5. 持久化 session.update(student); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: Student student=new Student(); student.setStudetnId(1); student.setStudentName("张三"); Teacher teacher=new Teacher(); teacher.setTeacherId(1); teacher.setTeacherName("刘老师"); HashSet<Teacher> teachers=new HashSet<Teacher>(); teachers.add(teacher); student.setTeachers(teachers); HashSet<Student> students=new HashSet<Student>(); students.add(student); teacher.setStudents(students); sd.update(student); 4.添加学生 ,老师建立两者关系 (级联添加 student 添加 cascade="save-update,delete") 添加学生同时 允许 同时添加老师 测试: Student student =new Student(); student.setStudentName("李四"); Teacher teacher=new Teacher(); teacher.setTeacherName("赵老师"); HashSet<Student> students=new HashSet<Student>(); students.add(student); teacher.setStudents(students); HashSet<Teacher> teachers=new HashSet<Teacher>(); teachers.add(teacher); student.setTeachers(teachers); sd.addStudent(student); 5. 添加一个学生 分配给xx老师 测试: Student student =new Student(); student.setStudentName("孙十1"); Teacher teacher =new Teacher(); teacher.setTeacherId(2); teacher.setTeacherName("赵老师"); //老师端 添加学生集合 HashSet<Student> students=new HashSet<Student>(); students.add(student); teacher.setStudents(students); //学生端 添加老师集合 HashSet<Teacher> teachers=new HashSet<Teacher>(); teachers.add(teacher); student.setTeachers(teachers); sd.addStudent(student); 6. 删除 (删除同学 不应该同时删除老师吧 所以 学生端 级联 不应该 加上 delete) 由于由 student维护关系 所以学生可以操作t_student_teacher表 public void deleteStudent(Student student) { //4. 开启事物 Transaction tr=session.beginTransaction(); try { //5. 持久化 session.delete(student); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: Student student=new Student(); student.setStudentName("张三"); student.setStudetnId(1); sd.deleteStudent(student); 7. 修改 将xx同学 更换成xx老师 (老师换了) 测试: Student student=new Student(); student.setStudentName("李四"); student.setStudetnId(2); Teacher teacher=new Teacher(); teacher.setTeacherId(1); teacher.setTeacherName("刘老师"); HashSet<Teacher> teachers=new HashSet<Teacher>(); teachers.add(teacher); HashSet<Student> students=new HashSet<Student>(); students.add(student); teacher.setStudents(students); student.setTeachers(teachers); sd.update(student); 8. 查询 xx同学 对应的老师 public Student findStudentByStudentId(int studentId) { Student student=(Student)session.get(Student.class, studentId); Hibernate.initialize(student.getTeachers()); session.close(); return student; } 测试: Student student= sd.findStudentByStudentId(2); System.out.println("学生:"+student.getStudentName()); System.out.println("对应老师:"); for(Teacher teacher : student.getTeachers()) { System.out.println(teacher.getTeacherName()); } 3. 一对一(Person表,IdCard表) Person类: public class Person { private int id; private String personName; private IdCard idCard; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getPersonName() { return personName; } public void setPersonName(String personName) { this.personName = personName; } public IdCard getIdCard() { return idCard; } public void setIdCard(IdCard idCard) { this.idCard = idCard; } } Person.hbm.xml文件: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping > <class name="com.hibernate.person.bean.Person" table="t_person" > <id name="id" type="int"> <column name="id"></column> <generator class="native"></generator> </id> <property name="personName" type="java.lang.String"></property> <!-- 默认去找 idCard表中主键 将值赋给idcard 主键--> <one-to-one name="idCard" cascade="save-update,delete"></one-to-one> </class> </hibernate-mapping> IdCard类: public class IdCard { private int id; private String cardNumber; private Person person; public int getId() { return id; } public void setId(int id) { this.id = id; } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public String getCardNumber() { return cardNumber; } public void setCardNumber(String cardNumber) { this.cardNumber = cardNumber; } } Idcard.html.xml文件: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping > <class name="com.hibernate.idcard.bean.IdCard" table="t_idcard" > <id name="id" type="int"> <column name="id"></column> <!-- 当前主键 作为 一对一的外键 --> <generator class="foreign"> <!-- property是foreign类的一个属性变量 告诉hibernate idcard的主键由 person的主键给值 --> <param name="property">person</param> </generator> </id> <property name="cardNumber" type="java.lang.String"></property> <!-- 默认去找 person表中主键值 --> <one-to-one name="person"></one-to-one> </class> </hibernate-mapping> 实例: PersonDao类: 一对一 主键对主键 1. 添加 一个人 并且分配一个身份证: private static Session session; static{ //1.读取hibernate.cfg.xml文件 Configuration cfg=new Configuration().configure(); //2.绑定sessionFactoru SessionFactory sessionFactory= cfg.buildSessionFactory(); //3.打开 session session= sessionFactory.openSession(); } public void addPerson(Person person) { //4. 开启事物 Transaction tr=session.beginTransaction(); try { //5. 持久化 session.persist(person); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: PersonDao pd=new PersonDao(); Person person =new Person(); person.setPersonName("张三"); IdCard idCard=new IdCard(); idCard.setCardNumber("123456789012345678"); //双向关联 idCard.setPerson(person); person.setIdCard(idCard); pd.addPerson(person); 2. 删除一个人 (当前是主键 看对idcard id外键是否有影响) constrained="true" 表示存在一个主外键约束 public void deletePerson(Person person) { //4. 开启事物 Transaction tr=session.beginTransaction(); try { //5. 持久化 session.delete(person); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: Person person =new Person(); person.setPersonName("张三"); person.setId(1); pd.deletePerson(person); 结果: 对idcard表没有影响 ,因为person 表 与 idcard表没有建立主外键关系 3. 删除一个人 身份证也删除 测试: Person person =new Person(); person.setPersonName("张三"); person.setId(1); IdCard idCard=new IdCard(); idCard.setId(1); idCard.setCardNumber("11111111111111111111"); person.setIdCard(idCard); pd.deletePerson(person); 4. 修改一个人 身份证号码 public void updateIdCard(IdCard idCard) { //4. 开启事物 Transaction tr=session.beginTransaction(); try { //5. 持久化 session.update(idCard); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: IdCard idCard=new IdCard(); idCard.setId(2); idCard.setCardNumber("1111111111"); pd.updateIdCard(idCard); 5. 查询一个人并且显示身份证号: public Person findPersonById(int id) { Person person=(Person)session.get(Person.class, id); session.close(); return person; } 测试: Person person= pd.findPersonById(2); System.out.println("人:"+person.getPersonName()); System.out.println( "身份证:"+person.getIdCard().getCardNumber()); 一对一 主键对外键 com.hibernate.person.other.bean包: PersonOther类: public class PersonOther { private int personId; private String personName; private IdCardOther idCardOther; public int getPersonId() { return personId; } public void setPersonId(int personId) { this.personId = personId; } public String getPersonName() { return personName; } public void setPersonName(String personName) { this.personName = personName; } public IdCardOther getIdCardOther() { return idCardOther; } public void setIdCardOther(IdCardOther idCardOther) { this.idCardOther = idCardOther; } } Personother.hbm.xml文件: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping > <class name="com.hibernate.person.other.bean.PersonOther" table="t_personother" > <id name="personId" type="int"> <column name="personId"></column> <generator class="native"></generator> </id> <property name="personName" type="java.lang.String"></property> <one-to-one name="idCardOther" property-ref="personOther" cascade="save-update,delete"></one-to-one> </class> </hibernate-mapping> com.hibernate.idcard.other.bean包: IdCardOther类: public class IdCardOther { private int cardId; private String cardNumber; private PersonOther personOther; public int getCardId() { return cardId; } public void setCardId(int cardId) { this.cardId = cardId; } public String getCardNumber() { return cardNumber; } public void setCardNumber(String cardNumber) { this.cardNumber = cardNumber; } public PersonOther getPersonOther() { return personOther; } public void setPersonOther(PersonOther personOther) { this.personOther = personOther; } } Idcardother.hbm.xml文件: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping > <class name="com.hibernate.idcard.other.bean.IdCardOther" table="t_idcardother" > <id name="cardId" type="int"> <column name="cardId"></column> <generator class="native"></generator> </id> <property name="cardNumber" type="java.lang.String"></property> <many-to-one name="personOther" column="person_id" unique="true" not-null="true"></many-to-one> </class> </hibernate-mapping> 实例: PersonOtherDao类: 1.添加 一个人 并且分配一个身份证 private static Session session; static{ //1.读取hibernate.cfg.xml文件 Configuration cfg=new Configuration().configure(); //2.绑定sessionFactoru SessionFactory sessionFactory= cfg.buildSessionFactory(); //3.打开 session session= sessionFactory.openSession(); } public void addPerson(PersonOther personOther) { //4. 开启事物 Transaction tr=session.beginTransaction(); try { //5. 持久化 session.persist(personOther); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: PersonOtherDao pod=new PersonOtherDao(); PersonOther personOther=new PersonOther(); personOther.setPersonName("张三"); IdCardOther idCardOther=new IdCardOther(); idCardOther.setCardNumber("112233445566778899"); //配置双向 idCardOther.setPersonOther(personOther); personOther.setIdCardOther(idCardOther); pod.addPerson(personOther); 2. 删除一个人 身份证也删除 public void deletePerson(PersonOther person) { //4. 开启事物 Transaction tr=session.beginTransaction(); try { //5. 持久化 session.delete(person); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: PersonOther personOther=new PersonOther(); personOther.setPersonId(1); personOther.setPersonName("张三"); IdCardOther idCardOther=new IdCardOther(); idCardOther.setCardId(1); idCardOther.setCardNumber("112233445566778899"); idCardOther.setPersonOther(personOther); personOther.setIdCardOther(idCardOther); pod.deletePerson(personOther); 3. 修改一个人 身份证号码 public void updateIdCard(IdCardOther idCard) { //4. 开启事物 Transaction tr=session.beginTransaction(); try { //5. 持久化 session.update(idCard); //6.提交 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); tr.rollback(); }finally { session.close(); } } 测试: IdCardOther idCard=new IdCardOther(); idCard.setCardId(2); idCard.setCardNumber("1111111111"); PersonOther personOther=new PersonOther(); personOther.setPersonId(2); personOther.setPersonName("张三"); idCard.setPersonOther(personOther); pod.updateIdCard(idCard); 4. 查询一个人并且显示身份证号 public PersonOther findPersonById(int id) { PersonOther person=(PersonOther)session.get(PersonOther.class, id); session.close(); return person; } 测试: PersonOther person= pod.findPersonById(2); System.out.println("人:"+person.getPersonName()); System.out.println("身份证:"+person.getIdCardOther().getCardNumber()); 一对一主键对主键,主键对外键关联结束 **************第三章************ 1. HQL语句: Hibernate Query Lanuage Hibernate查询语言 HQL是面向对象的查询语言 实例: Fwxx类: public class Fwxx { private int fwid; private int uid; private int jdid; private int lxid; private int shi; private int ting; private String fwxx; private float zj; private String title; private String date; private String telephone; private String lxr; public int getFwid() { return fwid; } public void setFwid(int fwid) { this.fwid = fwid; } public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } public int getJdid() { return jdid; } public void setJdid(int jdid) { this.jdid = jdid; } public int getLxid() { return lxid; } public void setLxid(int lxid) { this.lxid = lxid; } public int getShi() { return shi; } public void setShi(int shi) { this.shi = shi; } public int getTing() { return ting; } public void setTing(int ting) { this.ting = ting; } public String getFwxx() { return fwxx; } public void setFwxx(String fwxx) { this.fwxx = fwxx; } public float getZj() { return zj; } public void setZj(float zj) { this.zj = zj; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getTelephone() { return telephone; } public void setTelephone(String telephone) { this.telephone = telephone; } public String getLxr() { return lxr; } public void setLxr(String lxr) { this.lxr = lxr; } } Fwxx.hbm.xml文件: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping > <class name="com.hibernate.fwxx.bean.Fwxx" table="tbl_fwxx" > <id name="fwid" type="int"> <column name="fwid"></column> <generator class="native"></generator> </id> <property name="uid" type="int"></property> <property name="jdid" type="int"></property> <property name="lxid" type="int"></property> <property name="shi" type="int"></property> <property name="ting" type="int"></property> <property name="fwxx" type="java.lang.String"></property> <property name="zj" type="float"></property> <property name="title" type="java.lang.String"></property> <property name="date" type="java.lang.String"></property> <property name="telephone" type="java.lang.String"></property> <property name="lxr" type="java.lang.String"></property> </class> <query name="findFwxxByFwid" > <![CDATA[select fwxx from Fwxx as fwxx where fwxx.fwid= :fwid]]> </query> <sql-query name="findFwxxByFwidForSql"> <return class="com.hibernate.fwxx.bean.Fwxx"></return> <![CDATA[select * from tbl_fwxx where fwid=:fwid]]> </sql-query> </hibernate-mapping> 1. 创建表 //创建表 public void createTable() { Configuration cfg=new Configuration().configure(); new SchemaExport(cfg).create(true, true); } 测试: FwxxDao fd=new FwxxDao(); fd.createTable(); 2. 查询所有房屋信息并且按照发布时间排序 public List<Fwxx> findAllFwxx() { String hql="select fwxx from Fwxx as fwxx order by fwxx.date desc"; Query query= session.createQuery(hql); List<Fwxx> fwxxList= query.list(); session.close(); return fwxxList; } 测试: List<Fwxx> fwxxList=fd.findAllFwxx(); for(Fwxx fwxx : fwxxList) { System.out.println(fwxx.getLxr()+ ","+fwxx.getDate()+","+fwxx.getFwxx()+","+fwxx.getTitle()); } 3. 只查询 fwxx表 title信息 public List<String> findAllFwxx1() { String hql="select fwxx.title from Fwxx as fwxx order by fwxx.date desc"; Query query= session.createQuery(hql); List<String> fwxxList= query.list(); session.close(); return fwxxList; } 测试: List<String> titleList= fd.findAllFwxx1(); for(String title : titleList) { System.out.println(title); } 4. 只查询 fwxx表 date 和title这两列(为性能考虑) public List findAllFwxx2() { String hql="select fwxx.date,fwxx.title from Fwxx as fwxx order by fwxx.date desc"; Query query=session.createQuery(hql); List<Fwxx> fwxxList= query.list(); session.close(); return fwxxList; } 测试: List fwxxList=fd.findAllFwxx2(); for(int i=0;i<fwxxList.size();i++) { Object[] fwxxs=(Object[])fwxxList.get(i); System.out.println(fwxxs[0]+","+fwxxs[1]); } 5. 根据title模糊查询房屋信息 public List<Fwxx> findFwxxByTitle(String title) { String hql="select fwxx from Fwxx as fwxx where fwxx.title like '%"+title+"%'"; Query query=session.createQuery(hql); List<Fwxx> fwxxList= query.list(); session.close(); return fwxxList; } 测试: List<Fwxx> fwxxList= fd.findFwxxByTitle("二居"); for(Fwxx fwxx : fwxxList){ System.out.println(fwxx.getLxr()+","+fwxx.getDate() +","+fwxx.getFwxx()+","+fwxx.getTitle()); } 6. 使用 ? 占位符title模糊查询房屋信息 Query提供setLong,setDouble,setDate等方法用于设置不同类型的参数值 注意: 1. 必须保证:query设置参数的数目 == hql语句中占位符的数目 2. 占位符下标从 0 开始。 public List<Fwxx> findFwxxByTitle1(String title) { String hql="select fwxx from Fwxx as fwxx where fwxx.title like ?"; Query query=session.createQuery(hql); query.setString(0, "%"+title+"%"); List<Fwxx> fwxxList= query.list(); session.close(); return fwxxList; } 测试: List<Fwxx> fwxxList= fd.findFwxxByTitle1("二居"); for(Fwxx fwxx : fwxxList){ System.out.println(fwxx.getLxr()+","+fwxx.getDate() +","+fwxx.getFwxx()+","+fwxx.getTitle()); } 7. 查询租金在zj1到zj2范围内的租房信息 支持: >、< 、 = 、 >= 、 <= 、<>(不等于) 和is null;and、or、not和括号;in和between public List<Fwxx> findFwxxByZj(int zj1,int zj2) { String hql="select fwxx from Fwxx as fwxx where fwxx.zj>? and fwxx.zj<?"; Query query=session.createQuery(hql); query.setInteger(0, zj1); query.setInteger(1, zj2); List<Fwxx> fwxxList= query.list(); session.close(); return fwxxList; } 测试: List<Fwxx> fwxxList= fd.findFwxxByZj(200, 1000); for(Fwxx fwxx : fwxxList) { System.out.println(fwxx.getZj()+","+fwxx.getDate() +","+fwxx.getFwxx()+","+fwxx.getTitle()); } 8. 当参数数目增多时,代码可读性下降;将下标顺序硬编码,参数顺序有调整则代码也要调整 使用“:参数名”的格式定义命名参数 public List<Fwxx> findFwxxByZj1(int zj1,int zj2) { String hql="select fwxx from Fwxx as fwxx where fwxx.zj> :zj1 and fwxx.zj< :zj2"; Query query=session.createQuery(hql); // query.setInteger(0, zj1); // query.setInteger(1, zj2); query.setInteger("zj2", zj2); query.setInteger("zj1", zj1); List<Fwxx> fwxxList= query.list(); session.close(); return fwxxList; } 测试: List<Fwxx> fwxxList= fd.findFwxxByZj1(200, 1000); for(Fwxx fwxx : fwxxList) { System.out.println(fwxx.getZj()+"," +fwxx.getDate()+","+fwxx.getFwxx()+","+fwxx.getTitle()); } 9. 如何 两张表关联查询 fwxx表 jd表 例如:联系人为“王先生”的房屋信息都分布在哪些街道 com.hibernate.jd.bean包: Jd类: public class Jd { private int jdId; private String jd; private int qxid; public int getJdId() { return jdId; } public void setJdId(int jdId) { this.jdId = jdId; } public String getJd() { return jd; } public void setJd(String jd) { this.jd = jd; } public int getQxid() { return qxid; } public void setQxid(int qxid) { this.qxid = qxid; } } Jd.hbm.xml文件: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping > <class name="com.hibernate.jd.bean.Jd" table="tbl_jd" > <id name="jdId" type="int"> <column name="jdId"></column> <generator class="native"></generator> </id> <property name="jd" type="java.lang.String"></property> <property name="qxid" type="int"></property> </class> </hibernate-mapping> public List findFwxxBylxr(String lxr) { String hql="select fwxx.title,jd.jd from Fwxx as fwxx,Jd as jd where fwxx.jdid=jd.jdId and fwxx.lxr=:lxr"; Query query=session.createQuery(hql); query.setString("lxr", lxr); List list=query.list(); session.close(); return list; } 测试: List list= fd.findFwxxBylxr("王先生"); for(int i=0;i<list.size();i++) { Object[] fwxxs=(Object[])list.get(i); System.out.println(fwxxs[0]+","+fwxxs[1]); } 10. 分页查询fwxx public List<Fwxx> findFwxxForPage(int start,int pageSize) { String hql="select fwxx from Fwxx as fwxx "; Query query= session.createQuery(hql); query.setFirstResult(start);//开始条数 query.setMaxResults(pageSize);//每页最大显示条数 List list=query.list(); session.close(); return list; } 测试: List<Fwxx> fwxxList = fd.findFwxxForPage(2, 2); for(Fwxx fwxx : fwxxList){ System.out.println(fwxx.getLxr()+"," +fwxx.getDate()+","+fwxx.getFwxx()+","+fwxx.getTitle()); } 统计函数count() ,min()、max()、avg() 11. 在实现分页功能时,我们需要知道总记录数以便计算总页数 public long findFwxxTotalCount() { String hql="select count(fwxx) from Fwxx as fwxx"; Query query=session.createQuery(hql); // 返回单个 对象 可以用uniqueResult方法 long totalCount=(Long)query.uniqueResult(); session.close(); return totalCount; } 测试: System.out.println("总条数:"+fd.findFwxxTotalCount()); 12. 查询 所有住房的平均租金 public Double findFwxxZJAvg() { String hql="select avg(fwxx.zj) from Fwxx as fwxx"; Query query=session.createQuery(hql); // 返回单个 对象 可以用uniqueResult方法 Double zj=(Double)query.uniqueResult(); session.close(); return zj; } 测试: System.out.println("平均租金:"+fd.findFwxxZJAvg()); 13. hql 语句 与代码分离 public Fwxx findFwxxByFwidForHql(int fwid) { Query query= session.getNamedQuery("findFwxxByFwid"); query.setInteger("fwid", fwid); Fwxx fwxx=(Fwxx)query.uniqueResult(); session.close(); return fwxx; } Fwxx.hbm.xml文件加入 : <query name="findFwxxByFwid" > <![CDATA[select fwxx from Fwxx as fwxx where fwxx.fwid= :fwid]]> </query> 测试: Fwxx fwxx= fd.findFwxxByFwidForHql(1); System.out.println(fwxx.getTitle()+" "+fwxx.getFwxx()); 14. 写sql语句查询 public Fwxx findFwxxByFwidForSql(int fwid) { String sql="select * from tbl_fwxx where fwid=:fwid"; SQLQuery sqlQuery= session.createSQLQuery(sql); sqlQuery.setInteger("fwid",fwid); Fwxx fwxx=(Fwxx)sqlQuery.addEntity(Fwxx.class).uniqueResult(); session.close(); return fwxx; } 测试: Fwxx fwxx=fd.findFwxxByFwidForSql(1); System.out.println(fwxx.getTitle()+" "+fwxx.getFwxx()); 15. 写sql语句查询与代码分离 public Fwxx findFwxxByFwidForSql1(int fwid) { Query Query= session.getNamedQuery("findFwxxByFwidForSql"); Query.setInteger("fwid",fwid); Fwxx fwxx=(Fwxx)Query.uniqueResult(); session.close(); return fwxx; } Fwxx.hbm.xml文件: <sql-query name="findFwxxByFwidForSql"> <return class="com.hibernate.fwxx.bean.Fwxx"></return> <![CDATA[select * from tbl_fwxx where fwid=:fwid]]> </sql-query> 测试: Fwxx fwxx=fd.findFwxxByFwidForSql1(1); System.out.println(fwxx.getTitle()+" "+fwxx.getFwxx()); 使用 Criteria对象查询 16. 基于Criteria对象查询所有房屋信息 public List<Fwxx> findAllFwxxForCriteria() { Criteria criteria= session.createCriteria(Fwxx.class); criteria.addOrder(Order.desc("date")); List<Fwxx> fwxxList= criteria.list(); session.close(); return fwxxList; } 测试: List<Fwxx> fwxxList= fd.findAllFwxxForCriteria(); for(Fwxx fwxx : fwxxList) { System.out.println(fwxx.getLxr()+"," +fwxx.getDate()+","+fwxx.getFwxx()+","+fwxx.getTitle()); } 17. 基于Criteria对象 模糊查询title public List<Fwxx> findFwxxTitleForCriteria(String title) { Criteria criteria= session.createCriteria(Fwxx.class); criteria.add(Restrictions.ilike("title", title,MatchMode.ANYWHERE)); criteria.addOrder(Order.desc("date")); List<Fwxx> fwxxList=criteria.list(); session.close(); return fwxxList; } 测试: List<Fwxx> fwxxList= fd.findFwxxTitleForCriteria("二居"); for(Fwxx fwxx : fwxxList) { System.out.println(fwxx.getLxr()+","+fwxx.getDate()+"," +fwxx.getFwxx()+","+fwxx.getTitle()); } 18. 基于Criteria对象 查询 租金范围 public List<Fwxx> findFwxxZjForCriteria(float zj1,float zj2) { Criteria criteria= session.createCriteria(Fwxx.class); // criteria.add(Restrictions.between("zj", zj1, zj2)); criteria.add(Restrictions.ge("zj", zj1)); //ge >= gt > criteria.add(Restrictions.le("zj", zj2));// le <= lt < criteria.addOrder(Order.desc("date")); List<Fwxx> fwxxList=criteria.list(); session.close(); return fwxxList; } 测试: List<Fwxx> fwxxList= fd.findFwxxZjForCriteria(400f, 1000f); for(Fwxx fwxx : fwxxList) { System.out.println(fwxx.getZj()+","+fwxx.getLxr()+ ","+fwxx.getDate()+","+fwxx.getFwxx()+","+fwxx.getTitle()); } 19. 基于Criteria对象查询单个 Fwxx对象 public Fwxx findFwxxByFwidForCriteria(int fwid) { Criteria criteria= session.createCriteria(Fwxx.class); criteria.add(Restrictions.eq("fwid", fwid)); Fwxx fwxx= (Fwxx) criteria.uniqueResult(); session.close(); return fwxx; } 测试: Fwxx fwxx= fd.findFwxxByFwidForCriteria(1); System.out.println(fwxx.getZj()+","+fwxx.getLxr()+"," +fwxx.getDate()+","+fwxx.getFwxx()+","+fwxx.getTitle()); 20. 基于Criteria对象分页 public List<Fwxx> findFwxxPageForCriteria(int start,int pageSize) { Criteria criteria= session.createCriteria(Fwxx.class); criteria.addOrder(Order.desc("date")); criteria.setFirstResult(start); criteria.setMaxResults(pageSize); List<Fwxx> fwxxList=criteria.list(); session.close(); return fwxxList; } 测试: List<Fwxx> fwxxList= fd.findFwxxPageForCriteria(0, 2); for(Fwxx fwxx : fwxxList) { System.out.println(fwxx.getZj()+","+fwxx.getLxr()+ ","+fwxx.getDate()+","+fwxx.getFwxx() +","+fwxx.getTitle()); } 缓存 缓存的作用主要用来提高性能,可以简单的理解成一个Map;使用缓存涉及到三个操作:把数据放入缓存、从缓存中获取数据、删除缓存中的无效数据。 一级缓存,Session级共享。 save,update,saveOrUpdate,load,get,list,iterate这些方法都会将对象放在一级缓存中,一级缓存不能控制缓存的数量,所以要注意大批量操作数据时可能造成内存溢出;可以用evict,clear方法清除缓存中的内容 实例: com.hibernate.cache.dao包: UserCacheDao类: private static Session session; static{ //1.读取hibernate.cfg.xml文件 Configuration cfg=new Configuration().configure(); //2.绑定sessionFactoru SessionFactory sessionFactory= cfg.buildSessionFactory(); //3.打开 session session= sessionFactory.openSession(); } public User findUserByUid(int uid) { System.out.println("没有开始缓存"); User user=(User)session.get(User.class, uid); System.out.println("将User对象缓存到session中"); System.out.println("用户名:"+user.getUserName()); System.out.println("关闭数据库....."); try { Thread.sleep(1000*15);//休息15秒 } catch (Exception e) { // TODO: handle exception } // session.clear(); System.out.println("数据库已经关闭...."); User userCache= (User) session.get(User.class, uid);// 从缓存中获取 System.out.println("缓存数据 用户名:"+userCache.getUserName()); session.close(); return user; } 测试: //1. 一级session 缓存测试 UserCacheDao ucd=new UserCacheDao(); ucd.findUserByUid(1); 二级缓存,SessionFactory级共享。 l hibernate内置了对EhCache,OSCache,TreeCache,SwarmCache的支持 这里 使用 EhCache为例: 1. 导包 : ehcache-1.2.3.jar 2. 开启二级缓存 : Hibernate.cfg.xml文件中添加: <property name="cache.use_second_level_cache">true</property> 3. 添加hibernate缓存入口类(类似jdbc驱动类) <property name="cache.provider_class"> org.hibernate.cache.EhCacheProvider </property> 4. src目录下添加ehcache.xml <?xml version="1.0" encoding="UTF-8"?> <!-- defaultCache 节点为缺省的缓存策越 maxElementsInMemory 内存中最大允许存在的对象数量 eternal 设置缓存中的对象是否永久不过期 overflowToDik 把溢出的对象存放到硬盘上 timeToIdleSeconds 指定缓存对象空闲多长时间就过期,过期的对象会被清除掉 timeToLiveSeconds 指定缓存对象总的存活时间 diskPersistent 当jvm(java虚拟机)结束时是否持久化对象 diskExpiryThreadIntervalSeconds 指定专门用于清除过期对象的监听线程的轮询时间 --> <ehcache> <!-- 缓存对象 存放到那个路径地下 --> <diskStore path="c:/hibernate_cache" /> <!-- 定义缓存的默认行为 maxElementsInMemory:缓存中最大存放的对象 eternal:缓存对象是否永远不过期 overflowToDisk:缓存中对象数量 超过设置最大的存放的数量时 是否把超过的对象放到磁盘上 diskExpiryThreadIntervalSeconds:设置一个时间 专门有一个线程 来清除过期的缓存对象 --> <defaultCache maxElementsInMemory="1000" eternal="false" overflowToDisk="true" timeToIdleSeconds="120" timeToLiveSeconds="180" diskPersistent="false" diskExpiryThreadIntervalSeconds="60" /> <!-- 针对某个区域中的 缓存进行设置 没有就 默认就是上面的设置 --> <cache name="com.hibernate.student.bean.Student" maxElementsInMemory="5" eternal="false" overflowToDisk="true" timeToIdleSeconds="300" timeToLiveSeconds="600" diskPersistent="false"/> <cache name="com.hibernate.user.bean.User" maxElementsInMemory="5" eternal="false" overflowToDisk="true" timeToIdleSeconds="300" timeToLiveSeconds="600" diskPersistent="false"/> </ehcache> 5. user.hbm.xml文件 添加缓存 <cache region="com.hibernate.user.bean.User" usage="read-write"/> 准备工作完成 测试: 二级sessionFactory 缓存测试(get一级缓存没有查询到,二级缓存查询) public User findUserByUid1ForGet(int uid) { System.out.println("没有开始缓存..."); User user= (User) session.get(User.class, uid); System.out.println("user对象缓存到一级缓存中"); session.clear(); session.close();// 关闭 session System.out.println("一级缓存关闭,user对象清空,会将对象放入二级缓存中"); System.out.println("请关闭数据库...."); try { Thread.sleep(1000*15);//休息15秒 } catch (Exception e) { // TODO: handle exception } System.out.println("开始从二级缓存中查询数据..."); Session s= sessionFactory.openSession(); User u=(User) s.get(User.class, uid); System.out.println(u.getUserName()); s.close(); return user; } 测试: ucd.findUserByUid1ForGet(1); Hql语句缓存(查询缓存) l (查询缓存)由于命中率较低,所以hibernate缺省是关闭;修改cache.use_query_cache为true打开对查询的缓存,并且调用query.setCacheable(true)或criteria.setCacheable(true) 1. hibernate.cfg.xml文件 添加 <property name="cache.use_query_cache">true</property> 开启查询缓存 2.代码中 query.setCacheable(true)或criteria.setCacheable(true) public List<User> findUserByUid2ForHql(int uid) { Query query= session.createQuery("from User as user where user.uid="+uid); query.setCacheable(true);//设置开启hql语句缓存 默认关闭 query.uniqueResult(); session.clear(); session.close(); System.out.println("请关闭数据库...."); try { Thread.sleep(1000*15);//休息15秒 } catch (Exception e) { // TODO: handle exception } Session s= sessionFactory.openSession(); Query q= s.createQuery("from User as user where user.uid="+uid); q.setCacheable(true); User user=(User) q.uniqueResult(); System.out.println(user.getUserName()); return null; } 测试: ucd.findUserByUid2ForHql(1);
|