hibernate_03_session详解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate_03_session详解相关的知识,希望对你有一定的参考价值。
获得session对象有两种方法:
1)openSession
2)getCurrentSession
如果使用的是getCurrentSession需要在hibernate.cfg.xml文件中进行配置:
如果是本地事务(jdbc事务),按照如下方法配置:
<property name="hibernate.current_session_context_class">thread</property>
如果是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>
例子:
先创建java类:
1 package com.imooc.hibernate; 2 3 import java.util.Date; 4 5 public class Students { 6 7 private int sid; 8 private String sname; 9 private String gender; 10 private Date birthday; 11 private String address; 12 13 public Students(int sid, String sname, String gender, Date birthday, String address) { 14 super(); 15 this.sid = sid; 16 this.sname = sname; 17 this.gender = gender; 18 this.birthday = birthday; 19 this.address = address; 20 } 21 22 @Override 23 public String toString() { 24 return "Students [sid=" + sid + ", sname=" + sname + ", gender=" + gender + ", birthday=" + birthday 25 + ", address=" + address + "]"; 26 } 27 28 public int getSid() { 29 return sid; 30 } 31 32 public void setSid(int sid) { 33 this.sid = sid; 34 } 35 36 public String getSname() { 37 return sname; 38 } 39 40 public void setSname(String sname) { 41 this.sname = sname; 42 } 43 44 public String getGender() { 45 return gender; 46 } 47 48 public void setGender(String gender) { 49 this.gender = gender; 50 } 51 52 public Date getBirthday() { 53 return birthday; 54 } 55 56 public void setBirthday(Date birthday) { 57 this.birthday = birthday; 58 } 59 60 public String getAddress() { 61 return address; 62 } 63 64 public void setAddress(String address) { 65 this.address = address; 66 } 67 }
java类的配置文件
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4 <!-- Generated 2017-5-23 0:24:09 by Hibernate Tools 3.5.0.Final --> 5 <hibernate-mapping> 6 <class name="com.imooc.hibernate.Students" table="STUDENTS"> 7 <id name="sid" type="int"> 8 <column name="SID" /> 9 <generator class="assigned" /> 10 </id> 11 <property name="sname" type="java.lang.String"> 12 <column name="SNAME" /> 13 </property> 14 <property name="gender" type="java.lang.String"> 15 <column name="GENDER" /> 16 </property> 17 <property name="birthday" type="java.util.Date"> 18 <column name="BIRTHDAY" /> 19 </property> 20 <property name="address" type="java.lang.String"> 21 <column name="ADDRESS" /> 22 </property> 23 </class> 24 </hibernate-mapping>
hibernate配置文件
<?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> <property name="connection.username">root</property> <property name="connection.password">root</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/hibernate?useUnicode=true&characterEncoding=UTF-8</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 是否将sql语句打印到控制台,编码阶段便于测试,建议设为true --> <property name="show_sql">true</property> <!-- 是否将sql语句进行排版,建议设为true --> <property name="format_sql">true</property> <!-- 生成表结构的策略。create是如果之前有表结构,先删除表结构再重建; update:原有的基础上更新; create-drop:先删除表结构再重建 validate:与原表进行验证,如果和原表表结构不同,则不进行创建。 一般使用create和update --> <property name="hbm2ddl.auto">create</property> <!-- 使用getCurrentSession方法必须在配置文件中配置 --> <property name="hibernate.current_session_context_class">thread</property> <mapping resource="com/imooc/hibernate/Students.hbm.xml"/> </session-factory> </hibernate-configuration>
测试类
1 package com.icoom.test; 2 3 import org.hibernate.Session; 4 import org.hibernate.SessionFactory; 5 import org.hibernate.cfg.Configuration; 6 import org.hibernate.service.ServiceRegistry; 7 import org.hibernate.service.ServiceRegistryBuilder; 8 import org.junit.Test; 9 10 public class SessionTest { 11 12 /* 13 * 使用openSession获得session对象 14 */ 15 @Test 16 public void testOpenSession() { 17 Configuration config = new Configuration().configure();//获得配置对象(读取hibernate.cfg.xml文件) 18 // 获得服务注册对象 19 ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry(); 20 // 获得sessionFactory对象 21 SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); 22 // 获得session对象 23 Session session = sessionFactory.openSession(); 24 if (session != null) { 25 System.out.println("session创建成功"); 26 } else { 27 System.out.println("session创建失败"); 28 } 29 } 30 31 /* 32 * 使用getCurrentSession获得session对象(需要在hibernate配置文件中设置) 33 */ 34 @Test 35 public void testGetCurrentSession() { 36 Configuration config = new Configuration().configure(); 37 ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry(); 38 SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); 39 Session session = sessionFactory.getCurrentSession(); 40 if (session != null) { 41 System.out.println("session创建成功!"); 42 } else { 43 System.out.println("session创建失败!"); 44 } 45 } 46 }
那么,openSession和getCurrentSession有什么区别?
1. getCurrentSession在事务提交或者回滚之后会自动关闭,openSession需要手动关闭。如果使用openSession而没有手动关闭,多次之后会导致连接池溢出。
1 package com.icoom.test;
2
3 import java.sql.Connection;
4 import java.sql.SQLException;
5 import java.util.Date;
6
7 import org.hibernate.Session;
8 import org.hibernate.SessionFactory;
9 import org.hibernate.Transaction;
10 import org.hibernate.cfg.Configuration;
11 import org.hibernate.jdbc.Work;
12 import org.hibernate.service.ServiceRegistry;
13 import org.hibernate.service.ServiceRegistryBuilder;
14 import org.junit.Test;
15
16 import com.imooc.hibernate.Students;
17
18 public class SessionTest {
19
20 @Test
21 public void saveStudentsByOpenSession() {
22
23 // 获取配置对象
24 Configuration configure = new Configuration().configure();
25 // 获得服务注册对象
26 ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configure.getProperties()).buildServiceRegistry();
27 /*
28 * 创建sessionFactory对象。sessionFactory是一种工厂模式,
29 * 目的是返回session,而不必new一个session。这样做比较安全。
30 */
31 SessionFactory sessionFactory = configure.buildSessionFactory(serviceRegistry);
32 // 创建第一个session对象
33 Session session1 = sessionFactory.openSession();
34 // 开启事务
35 Transaction transaction = session1.beginTransaction();
36 // 生成一个学生对象
37 Students s = new Students(1,"张三","男",new Date(),"北京");
38 session1.doWork(new Work() {
39
40 @Override
41 public void execute(Connection connection) throws SQLException {
42 // TODO Auto-generated method stub
43 System.out.println("connection‘s hashCode:" + connection.hashCode());
44 }
45
46 });
47 session1.save(s);
48 // session1.close(); // 不执行close()方法,继续新建session对象
49 transaction.commit();
50
51 // 创建第二个session对象
52 Session session2 = sessionFactory.openSession();
53 transaction = session2.beginTransaction();
54 s = new Students(2,"李四","女",new Date(),"上海");
55 session2.doWork(new Work() {
56
57 @Override
58 public void execute(Connection connection) throws SQLException {
59 // TODO Auto-generated method stub
60 System.out.println("connection‘s hashCode:" + connection.hashCode());
61 }
62
63 });
64 session2.save(s);
65 transaction.commit();
66 }
67 }
控制台打印出两个hashcode值不同,所以使用openSession()方法而不手动关闭,每次创建都会新建一个链接,有可能导致连接池溢出。
再看getCurrentSession():
1 package com.icoom.test; 2 3 import java.sql.Connection; 4 import java.sql.SQLException; 5 import java.util.Date; 6 7 import org.hibernate.Session; 8 import org.hibernate.SessionFactory; 9 import org.hibernate.Transaction; 10 import org.hibernate.cfg.Configuration; 11 import org.hibernate.jdbc.Work; 12 import org.hibernate.service.ServiceRegistry; 13 import org.hibernate.service.ServiceRegistryBuilder; 14 import org.junit.Test; 15 16 import com.imooc.hibernate.Students; 17 18 public class SessionTest { 19 20 @Test 21 public void saveStudentsByGetCurrentSession() { 22 23 // 获取配置对象 24 Configuration configure = new Configuration().configure(); 25 // 获得服务注册对象 26 ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configure.getProperties()).buildServiceRegistry(); 27 /* 28 * 创建sessionFactory对象。sessionFactory是一种工厂模式, 29 * 目的是返回session,而不必new一个session。这样做比较安全。 30 */ 31 SessionFactory sessionFactory = configure.buildSessionFactory(serviceRegistry); 32 // 创建第一个session对象 33 Session session1 = sessionFactory.getCurrentSession(); 34 // 开启事务 35 Transaction transaction = session1.beginTransaction(); 36 // 生成一个学生对象 37 Students s = new Students(1,"张三","男",new Date(),"北京"); 38 session1.doWork(new Work() { 39 40 @Override 41 public void execute(Connection connection) throws SQLException { 42 // TODO Auto-generated method stub 43 System.out.println("connection‘s hashCode:" + connection.hashCode()); 44 } 45 46 }); 47 session1.save(s); 48 // session1.close(); // 不执行close()方法,继续新建session对象 49 transaction.commit(); 50 51 // 创建第二个session对象 52 Session session2 = sessionFactory.getCurrentSession(); 53 transaction = session2.beginTransaction(); 54 s = new Students(2,"李四","女",new Date(),"上海"); 55 session2.doWork(new Work() { 56 57 @Override 58 public void execute(Connection connection) throws SQLException { 59 // TODO Auto-generated method stub 60 System.out.println("connection‘s hashCode:" + connection.hashCode()); 61 } 62 63 }); 64 session2.save(s); 65 // session2.close(); 66 transaction.commit(); 67 } 68 }
两个hashCode一致。
2. openSession每次创建新的session对象,getCurrentSession使用现有的session对象。
1 package com.icoom.test;
2
3 import org.hibernate.Session;
4 import org.hibernate.SessionFactory;
5 import org.hibernate.cfg.Configuration;
6 import org.hibernate.service.ServiceRegistry;
7 import org.hibernate.service.ServiceRegistryBuilder;
8 import org.junit.Test;
9
10 public class SessionTest {
11
12 /*
13 * openSession每次创建新的session对象
14 */
15 @Test
16 public void testOpenSession() {
17 Configuration config = new Configuration().configure();//获得配置对象(读取hibernate.cfg.xml文件)
18 // 获得服务注册对象
19 ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
20 // 获得sessionFactory对象
21 SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry);
22 // 获得session对象
23 Session session1 = sessionFactory.openSession();
24 Session session2 = sessionFactory.openSession();
25 System.out.println(session1 == session2); // false
26 }
27
28 /*
29 * getCurrentSession使用现有的session对象
30 */
31 @Test
32 public void testGetCurrentSession() {
33 Configuration config = new Configuration().configure();
34 ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
35 SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry);
36 Session session1 = sessionFactory.getCurrentSession();
37 Session session2 = sessionFactory.getCurrentSession();
38 System.out.println(session1 == session2); // true
39 }
40 }
以上是关于hibernate_03_session详解的主要内容,如果未能解决你的问题,请参考以下文章
SPRING05_BeanFactory概述HierarchicalBeanFactoryListableBeanFacotoryDefaultListableBeanFactory档案馆详解(代码片