java无忧网
标题: Hibernate 学习与使用 [打印本页]
作者: java无忧网 时间: 2016-5-28 17:38
标题: Hibernate 学习与使用
**************第一章************
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);
欢迎光临 java无忧网 (http://www.javawyw.com/) |
Powered by Discuz! X3.2 |