标签:
使用手动配置hibernate方式开发一个hibernate项目,完成相关操作。
开发Hibernate三种方式
我们使用第二种方式
首先在hibernate数据库下创建student表
create table student(id int primary key,name varchar(20) not null,age varchar(20) not null,);5.开发domain对象 和对象关系映射
对象关系映射文件,用于指定domain对象和表的映射关系,该文件的取名有规范,domain对象hbm.xml,一般和domain对象同一包下。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.sun.hibernate.model"> <class name="Student"> <id name="id"></id> <property name="name"></property> <property name="age"></property> </class> </hibernate-mapping>6.手动配置hibernate.cfg.xml文件,该文件用于配置连接的数据库类型,diver,用户名,密码....同时管理对象关系映射文件和该文件的名称,这个文件一般放在src目录下。
<?xml version=‘1.0‘ encoding=‘utf-8‘?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Database connection settings --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost/hibernate</property> <property name="connection.username">root</property> <property name="connection.password"></property> <!-- JDBC connection pool (use the built-in) --> <!-- <property name="connection.pool_size">1</property> --> <!-- SQL dialect --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <!-- Enable Hibernate‘s automatic session context management --> <!--<property name="current_session_context_class">thread</property>--> <!-- Drop and re-create the database schema on startup --> <!-- <property name="hbm2ddl.auto">create</property> --> <!-- Disable the second-level cache --> <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <mapping resource="com/sun/hibernate/model/Student.hbm.xml"/> </session-factory> </hibernate-configuration>7. 创建对应的student模型
package com.sun.hibernate.model;public class Student { private int id; private String name; private int age; 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; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}8.测试方法(向数据库中添加一条数据)
package com.sun.hibernate.model;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.hibernate.classic.Session;public class StudentTest { public static void main(String[] args){ Student s = new Student(); s.setId(1); s.setName("s1"); s.setAge(2); //1.创建Configuration ,该对象用于读取hibernate.cfg.xml,并完成初始化 Configuration cfg = new Configuration(); //2.创建SessionFactory<这是一个会话工厂,是一个重量级对象> SessionFactory sf = cfg.configure().buildSessionFactory(); //3.创建一个session,相当于jdbc Connection<不是jsp中的那个session> Session session = sf.openSession(); //4.对hibernate而言,要求程序员在进行增加,删除,修改时必须使用事物提交 session.beginTransaction(); session.save(s); //insert into ... <sql语句被hibernate封装了> session.getTransaction().commit(); session.close(); sf.close(); }}直接运行StudentTest就可以将数据插入到数据库中了。
Session内置不能被卸载,Session的缓存是事务范围的缓存(Session对象的生命周期通常对应一个数据库事务或者一个应用事务)。
一级缓存中,持久化类的每个实例都具有唯一的OID。
第二级缓存是可选的,是一个可配置的插件,默认下SessionFactory不会启用这个插件。
Hibernate提供了org.hibernate.cache.CacheProvider接口,它充当缓存插件与Hibernate之间的适配器。
什么样的数据适合存放到第二级缓存中?
1) 很少被修改的数据
2) 不是很重要的数据,允许出现偶尔并发的数据
3) 不会被并发访问的数据
4) 常量数据
不适合存放到第二级缓存的数据?
1) 经常被修改的数据
2) 绝对不允许出现并发访问的数据,如财务数据,绝对不允许出现并发
3) 与其他应用共享的数据。
Hibernate查找对象如何应用缓存?
当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;
查不到,如果配置了二级缓存,那么从二级缓存中查;
如果都查不到,再查询数据库,把结果按照ID放入到缓存删除、更新、增加数据的时候,同时更新缓存。
通过Query接口我们可以完成更加复杂的查询任务
###快速入门
/*获取query应用【这里student不是表,而是domain】where后面的条件可以是一个类的属性名,也可以是表的字段,按照hibernate规定,我们还是应该使用类的属性名*/ Query query = session.createQuery("from Teacher where id = 2"); //通过list方法获取结果,这个list会自动将封装成对应的dommain //所以我们jdbc进行二次封装的工作没有 List<Teacher> list = query.list(); for(Teacher tea: list){ System.out.println(tea.getName() + " " + tea.getAge()); }快速入门
Criteria cri = session.createCriteria(Teacher.class).setMaxResults(4); List<Teacher> list = cri.list(); for(Teacher tea:list){ System.out.println(tea.getId() + " " + tea.getName()); }(hibernate query language)
在现有的只是基础上,对对象的批量删除,修改,查询还不能很方便的实现。
模拟创建表
查询所有对象
List<Student> list = session.createQuery("from Student").list();如果检索一个对象,明确知道最多只有一个,则建议使用该方法。
具体用法:
Student stu = (Student) session.createQuery(" from Student where sid = 20040001").uniqueResult();distinct的用法:(用于过滤重复记录)
List<Object[]> list = (List<Object[]>)session.createQuery(" select distinct ssex,sage from Student").list();between...and的用法
List<Object[]> list = (List<Object[]>)session.createQuery(" select distinct sname,ssex,sage from Student where sage between 22 and 24").list();in 和 not in的用法
List<Student> list = session.createQuery("from Student where sdept in (‘数学系‘,‘计算机系‘)").list();group 和 having 和 order by
group用法:(查询各个系的学生的平均年龄)
List<Object[]> list = session.createQuery("select avg(sage),sdept from Student group by sdept").list();having的使用(显示人数大于等于2的系)
List<Object[]> list = session.createQuery("select count(*),sdept from Student group by sdept having count(*) >= 2").list();(查询各个系女生的人数)
List<Object[]> list = session.createQuery("select count(*),sdept from Student where ssex=‘M‘ group by sdept").list();order by用法(查询所有学生的成绩拼按照成绩高低排序)
List<Object[]> list = session.createQuery("select student.sname,course.cname,grade from Studcourse order by grade DESC").list();查询计算机系共有多少学生
如果返回一列数据,取出数据是必须用Object,而不是Object[]
List<Object[]> list = session.createQuery("select count(*) from Student where sdept=‘计算机系‘").list();查询总成绩是多少
List<Object[]> list = session.createQuery("select sum(grade) from Studcourse").list();查询课程号为1001的课程名称,最高分和最低分
List<Object[]> list = session.createQuery("select course.cname,min(grade),max(grade) from Studcourse where course.cid=1011").list();查询各科大于80分的学生的名字,科目,分数
List<Object[]> list =session.createQuery("select student.sname,course.cname,grade from Studcourse where grade > 80").list();计算各科大于80分的的学生数量
List<Object[]> list = session.createQuery("select course.cname,count(*) from Studcourse where grade>80 group by course.cid").list();查询所有学生成绩进行高低排序并只分页显示。
//获取页数int pageCount = Integer.parseInt(session.createQuery("select count(*) from Studcourse").uniqueResult().toString()) /3 +1;System.out.println("一共有"+pageCount+"页");//开始查询for(int i = 0; i < pageCount; i++){ List<Object[]> list = session.createQuery("select student.sname,course.cname,grade from Studcourse order by grade DESC"). setFirstResult(i*3).setMaxResults(3).list(); for(int j = 0; j < list.size(); j ++) { Object[] obj = list.get(j); System.out.println(obj[0].toString() + " " + obj[1].toString() + " " + obj[2].toString()); } System.out.println("*******第"+(i+1)+"页**********");}好处:
1.可读性高
2.效果好
3.防止sql注入漏洞
一般写法:
List<Student> list = session.createQuery("from Student where sage = 22 and sname = ‘张三‘").list();参数绑定写法:
如果我们的参数是冒号形式给出的,则可以这样写:
List<Student> list = session.createQuery("from Student where sage=:sage andsname=:sname").setString("sage", "22").setString("sname", "张三").list();如果我们的参数是问号形式给出的,则可以这样写:
List<Student> list = session.createQuery("from Student where sage=? and sname=?").setString(0, "22").setString(1, "张三").list();将绑定分开写:
Query query = session.createQuery("from Student where sage=? and sname=?");query.setInteger(0, 22);query.setString(1, "张三");List<Student> list = query.list();hibernate提供了一种更加灵活的查询方法。
把hql语句配置到对象关系映射文件
<query name="myquerytest"> from Student</query>数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器回收,一般是new出来且且与session没有关联的对象。
数据库中有数据与之对应,与当前session有关联,并且相关联的session没有关闭,事物没有提交;持久对象状态发生改变,在事务提交时会影响数据库(hibernate能检测得到)
数据库中有数据与之对应,但当前没有session与之关联;脱管状态发生改变时,hibernate不能检测到。
Student stu = new Student(); //stu就是瞬时状态 stu.setSname("王宝强"); stu.setSsex("M"); stu.setSdept("表演系"); stu.setSage(32); stu.setSaddress("河南"); Session session = null; Transaction ts = null; try { session = HibernateUtil.openSession(); ts = session.beginTransaction(); session.save(stu); //stu既处于session管理下, //同时stu被保存到数据库中,因此stu此时是持久态 stu.setSname("唐国强");//hibernate能检测到,并且会提交到数据库中去 ts.commit(); session.close(); //这是stu被保存到数据库中,没有处于session的管理之下 //此时stu就是脱管状态(游离态) } catch (Exception e) { if(ts != null){ ts.rollback(); } throw new RuntimeException(e.getMessage()); }finally{ }1. 什么是pojo类,他有什么要求?
* pojo类和一张表对应
* 一般放在com.XXX.domain下
* pojo需要一个主键属性(用于标示一个pojo对象)
* 除了主键属性,它还应当有其他属性,属性的访问权限为private
* 提供get/set方法
* 它应当有一个无参构造方法(hibernate反射)
* pojo类其实就是一个javaBean(有时也叫Data对象)
2. hibernate核心类和接口
1. configuration类
2. 读取配置文件
3. 管理关系映射文件
4. 加载hibernate的驱动,url,用户
5. 管理hibernate配置信息
3. hibernate.cfg.xml
4. 对象关系映射文件
5. SessionFactory接口(会话工厂)
1. 可以缓存sql语句和数据(称为session级缓存)
2. 是一个重量级的类,因此需要保证一个数据库有一个SessionFactory
6. 通过SessionFactory获取Session的两个方法
1. openSession()是获取一个新的Session
2. getCurrentSession()获取和当前绑定的session,换言之,在同一个线程中,我们获取的session是同一个session。(如果希望使用getCurrentSession需要配置hibernate.cfg.xml)
<property name="current_session_context_class">thread</property>3.如何选择
如果在同一个线程中,保证使用同一个session,则使用getCurrentSession(),如果在同一个线程中需要使用不同的Session,则使用opentSession()
4. openSession() 和 getCurrentSession()的区别
* 通过getCurrentSession获取的session在事务提交以后会自动关闭,通过openSession获取的session则必须手动关闭,但是我们建议不管什么形式获取的session都进行判断后手动关闭。
* 如果是通过getCurrentSession()获取session进行查询时,也要进行事务提交。
7. 本地事务:针对一个数据库的事物
全局事务:跨数据库的事物(jta)
8. session接口:
主要功能和作用
1. session一个实例代表与数据库的一次操作。(当然一次操作可以使crud组合)
2. session实例是通过SessionFactory获取,用完需要关闭。
3. session实例是线程不同步的(不安全),因此要保证在同一线程中使用,可以用getCurrentSession()
*4.*session可以看做是持久化管理器,它与持久化操作相关的接口。
get() 和load()区别
1.
get()方法直接返回实体类,如果找不到数据则返回null。load()会返回一个实体代理对象(当前这个对象可以自动转化为实体对象)。但当代理对
象被调用时,如果数据不存在,就会抛出org.hibernate.ObjectNotFoundException异常。
2.
load先到缓存(session缓存/二级缓存)中去查,如果没有则返回一个代理对象(不马上到DB中去找),等后面使用这个代理对象操作的时候,才到
DB中去查询,这就是我们常说的load在默认情况下支持延迟加载(lazy--->我们可以在配置文件中关闭懒加载功能).
<!-- 禁用懒加载功能 --><class name="Student" lazy="false">3. get先到缓存(session缓存/二级缓存)中去查,如果没有就到DB中去查(即马上发出sql)。总之,如果你确定DB中有这个对象就用load(),不确定就用get()(这样效率高)
使用手动配置hibernate方式开发一个hibernate项目,完成相关操作。
开发Hibernate三种方式
我们使用第二种方式
首先在hibernate数据库下创建student表
create table student(id int primary key,name varchar(20)notnull,age varchar(20)notnull,);5.开发domain对象 和对象关系映射
对象关系映射文件,用于指定domain对象和表的映射关系,该文件的取名有规范,domain对象hbm.xml,一般和domain对象同一包下。
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mappingpackage="com.sun.hibernate.model"><classname="Student"><idname="id"></id><propertyname="name"></property><propertyname="age"></property></class></hibernate-mapping>6.手动配置hibernate.cfg.xml文件,该文件用于配置连接的数据库类型,diver,用户名,密码....同时管理对象关系映射文件和该文件的名称,这个文件一般放在src目录下。
<?xml version=‘1.0‘ encoding=‘utf-8‘?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory><!-- Database connection settings --><propertyname="connection.driver_class">com.mysql.jdbc.Driver</property><propertyname="connection.url">jdbc:mysql://localhost/hibernate</property><propertyname="connection.username">root</property><propertyname="connection.password"></property><!-- JDBC connection pool (use the built-in) --><!-- <property name="connection.pool_size">1</property> --><!-- SQL dialect --><propertyname="dialect">org.hibernate.dialect.MySQLDialect</property><!-- Echo all executed SQL to stdout --><propertyname="show_sql">true</property><!-- Enable Hibernate‘s automatic session context management --><!--<property name="current_session_context_class">thread</property>--><!-- Drop and re-create the database schema on startup --><!-- <property name="hbm2ddl.auto">create</property> --><!-- Disable the second-level cache --><propertyname="cache.provider_class">org.hibernate.cache.NoCacheProvider</property><mappingresource="com/sun/hibernate/model/Student.hbm.xml"/></session-factory></hibernate-configuration>7. 创建对应的student模型
package com.sun.hibernate.model;publicclassStudent{privateint id;privateString name;privateint age;publicint getId(){return id;}publicvoid setId(int id){this.id = id;}publicString getName(){return name;}publicvoid setName(String name){this.name = name;}publicint getAge(){return age;}publicvoid setAge(int age){this.age = age;}}8.测试方法(向数据库中添加一条数据)
package com.sun.hibernate.model;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.hibernate.classic.Session;publicclassStudentTest{publicstaticvoid main(String[] args){Student s =newStudent(); s.setId(1); s.setName("s1"); s.setAge(2);//1.创建Configuration ,该对象用于读取hibernate.cfg.xml,并完成初始化Configuration cfg =newConfiguration();//2.创建SessionFactory<这是一个会话工厂,是一个重量级对象>SessionFactory sf = cfg.configure().buildSessionFactory();//3.创建一个session,相当于jdbc Connection<不是jsp中的那个session>Session session = sf.openSession();//4.对hibernate而言,要求程序员在进行增加,删除,修改时必须使用事物提交 session.beginTransaction(); session.save(s);//insert into ... <sql语句被hibernate封装了> session.getTransaction().commit(); session.close(); sf.close();}}直接运行StudentTest就可以将数据插入到数据库中了。
Session内置不能被卸载,Session的缓存是事务范围的缓存(Session对象的生命周期通常对应一个数据库事务或者一个应用事务)。
一级缓存中,持久化类的每个实例都具有唯一的OID。
第二级缓存是可选的,是一个可配置的插件,默认下SessionFactory不会启用这个插件。
Hibernate提供了org.hibernate.cache.CacheProvider接口,它充当缓存插件与Hibernate之间的适配器。
什么样的数据适合存放到第二级缓存中?
1) 很少被修改的数据
2) 不是很重要的数据,允许出现偶尔并发的数据
3) 不会被并发访问的数据
4) 常量数据
不适合存放到第二级缓存的数据?
1) 经常被修改的数据
2) 绝对不允许出现并发访问的数据,如财务数据,绝对不允许出现并发
3) 与其他应用共享的数据。
Hibernate查找对象如何应用缓存?
当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;
查不到,如果配置了二级缓存,那么从二级缓存中查;
如果都查不到,再查询数据库,把结果按照ID放入到缓存删除、更新、增加数据的时候,同时更新缓存。
通过Query接口我们可以完成更加复杂的查询任务
###快速入门
/*获取query应用【这里student不是表,而是domain】where后面的条件可以是一个类的属性名,也可以是表的字段,按照hibernate规定,我们还是应该使用类的属性名*/Query query = session.createQuery("from Teacher where id = 2");//通过list方法获取结果,这个list会自动将封装成对应的dommain//所以我们jdbc进行二次封装的工作没有List<Teacher> list = query.list();for(Teacher tea: list){System.out.println(tea.getName()+" "+ tea.getAge());}快速入门
Criteria cri = session.createCriteria(Teacher.class).setMaxResults(4);List<Teacher> list = cri.list();for(Teacher tea:list){System.out.println(tea.getId()+" "+ tea.getName());}(hibernate query language)
在现有的只是基础上,对对象的批量删除,修改,查询还不能很方便的实现。
模拟创建表
查询所有对象
List<Student> list = session.createQuery("from Student").list();如果检索一个对象,明确知道最多只有一个,则建议使用该方法。
具体用法:
Student stu =(Student) session.createQuery(" from Student where sid = 20040001").uniqueResult();distinct的用法:(用于过滤重复记录)
List<Object[]> list =(List<Object[]>)session.createQuery(" select distinct ssex,sage from Student").list();between...and的用法
List<Object[]> list =(List<Object[]>)session.createQuery(" select distinct sname,ssex,sage from Student where sage between 22 and 24").list();in 和 not in的用法
List<Student> list = session.createQuery("from Student where sdept in (‘数学系‘,‘计算机系‘)").list();group 和 having 和 order by
group用法:(查询各个系的学生的平均年龄)
List<Object[]> list = session.createQuery("select avg(sage),sdept from Student group by sdept").list();having的使用(显示人数大于等于2的系)
List<Object[]> list = session.createQuery("select count(*),sdept from Student group by sdept having count(*) >= 2").list();(查询各个系女生的人数)
List<Object[]> list = session.createQuery("select count(*),sdept from Student where ssex=‘M‘ group by sdept").list();order by用法(查询所有学生的成绩拼按照成绩高低排序)
List<Object[]> list = session.createQuery("select student.sname,course.cname,grade from Studcourse order by grade DESC").list();查询计算机系共有多少学生
如果返回一列数据,取出数据是必须用Object,而不是Object[]
List<Object[]> list = session.createQuery("select count(*) from Student where sdept=‘计算机系‘").list();查询总成绩是多少
List<Object[]> list = session.createQuery("select sum(grade) from Studcourse").list();查询课程号为1001的课程名称,最高分和最低分
List<Object[]> list = session.createQuery("select course.cname,min(grade),max(grade) from Studcourse where course.cid=1011").list();查询各科大于80分的学生的名字,科目,分数
List<Object[]> list =session.createQuery("select student.sname,course.cname,grade from Studcourse where grade > 80").list();计算各科大于80分的的学生数量
List<Object[]> list = session.createQuery("select course.cname,count(*) from Studcourse where grade>80 group by course.cid").list();查询所有学生成绩进行高低排序并只分页显示。
//获取页数int pageCount =Integer.parseInt(session.createQuery("select count(*) from Studcourse").uniqueResult().toString())/3+1;System.out.println("一共有"+pageCount+"页");//开始查询for(int i =0; i < pageCount; i++){List<Object[]> list = session.createQuery("select student.sname,course.cname,grade from Studcourse order by grade DESC"). setFirstResult(i*3).setMaxResults(3).list();for(int j =0; j < list.size(); j ++){Object[] obj = list.get(j);System.out.println(obj[0].toString()+" "+ obj[1].toString()+" "+ obj[2].toString());}System.out.println("*******第"+(i+1)+"页**********");}好处:
1.可读性高
2.效果好
3.防止sql注入漏洞
一般写法:
List<Student> list = session.createQuery("from Student where sage = 22 and sname = ‘张三‘").list();参数绑定写法:
如果我们的参数是冒号形式给出的,则可以这样写:
List<Student> list = session.createQuery("from Student where sage=:sage andsname=:sname").setString("sage","22").setString("sname","张三").list();如果我们的参数是问号形式给出的,则可以这样写:
List<Student> list = session.createQuery("from Student where sage=? and sname=?").setString(0,"22").setString(1,"张三").list();将绑定分开写:
Query query = session.createQuery("from Student where sage=? and sname=?");query.setInteger(0,22);query.setString(1,"张三");List<Student> list = query.list();hibernate提供了一种更加灵活的查询方法。
把hql语句配置到对象关系映射文件
<queryname="myquerytest"> from Student</query>数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器回收,一般是new出来且且与session没有关联的对象。
数据库中有数据与之对应,与当前session有关联,并且相关联的session没有关闭,事物没有提交;持久对象状态发生改变,在事务提交时会影响数据库(hibernate能检测得到)
数据库中有数据与之对应,但当前没有session与之关联;脱管状态发生改变时,hibernate不能检测到。
Student stu =newStudent();//stu就是瞬时状态 stu.setSname("王宝强"); stu.setSsex("M"); stu.setSdept("表演系"); stu.setSage(32); stu.setSaddress("河南");Session session =null;Transaction ts =null;try{ session =HibernateUtil.openSession(); ts = session.beginTransaction(); session.save(stu);//stu既处于session管理下,//同时stu被保存到数据库中,因此stu此时是持久态 stu.setSname("唐国强");//hibernate能检测到,并且会提交到数据库中去 ts.commit(); session.close();//这是stu被保存到数据库中,没有处于session的管理之下//此时stu就是脱管状态(游离态)}catch(Exception e){if(ts !=null){ ts.rollback();}thrownewRuntimeException(e.getMessage());}finally{}1. 什么是pojo类,他有什么要求?
* pojo类和一张表对应
* 一般放在com.XXX.domain下
* pojo需要一个主键属性(用于标示一个pojo对象)
* 除了主键属性,它还应当有其他属性,属性的访问权限为private
* 提供get/set方法
* 它应当有一个无参构造方法(hibernate反射)
* pojo类其实就是一个javaBean(有时也叫Data对象)
2. hibernate核心类和接口
1. configuration类
2. 读取配置文件
3. 管理关系映射文件
4. 加载hibernate的驱动,url,用户
5. 管理hibernate配置信息
3. hibernate.cfg.xml
4. 对象关系映射文件
5. SessionFactory接口(会话工厂)
1. 可以缓存sql语句和数据(称为session级缓存)
2. 是一个重量级的类,因此需要保证一个数据库有一个SessionFactory
6. 通过SessionFactory获取Session的两个方法
1. openSession()是获取一个新的Session
2. getCurrentSession()获取和当前绑定的session,换言之,在同一个线程中,我们获取的session是同一个session。(如果希望使用getCurrentSession需要配置hibernate.cfg.xml)
<propertyname="current_session_context_class">thread</property>3.如何选择
如果在同一个线程中,保证使用同一个session,则使用getCurrentSession(),如果在同一个线程中需要使用不同的Session,则使用opentSession()
4. openSession() 和 getCurrentSession()的区别
* 通过getCurrentSession获取的session在事务提交以后会自动关闭,通过openSession获取的session则必须手动关闭,但是我们建议不管什么形式获取的session都进行判断后手动关闭。
* 如果是通过getCurrentSession()获取session进行查询时,也要进行事务提交。
7. 本地事务:针对一个数据库的事物
全局事务:跨数据库的事物(jta)
8. session接口:
主要功能和作用
1. session一个实例代表与数据库的一次操作。(当然一次操作可以使crud组合)
2. session实例是通过SessionFactory获取,用完需要关闭。
3. session实例是线程不同步的(不安全),因此要保证在同一线程中使用,可以用getCurrentSession()
*4.*session可以看做是持久化管理器,它与持久化操作相关的接口。
get() 和load()区别
1.
get()方法直接返回实体类,如果找不到数据则返回null。load()会返回一个实体代理对象(当前这个对象可以自动转化为实体对象)。但当代理对
象被调用时,如果数据不存在,就会抛出org.hibernate.ObjectNotFoundException异常。
2.
load先到缓存(session缓存/二级缓存)中去查,如果没有则返回一个代理对象(不马上到DB中去找),等后面使用这个代理对象操作的时候,才到
DB中去查询,这就是我们常说的load在默认情况下支持延迟加载(lazy--->我们可以在配置文件中关闭懒加载功能).
<!-- 禁用懒加载功能 --><classname="Student"lazy="false">3. get先到缓存(session缓存/二级缓存)中去查,如果没有就到DB中去查(即马上发出sql)。总之,如果你确定DB中有这个对象就用load(),不确定就用get()(这样效率高)
标签:
原文地址:http://www.cnblogs.com/snail-lb/p/5669121.html