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&amp;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 }
时间: 2024-07-29 09:48:47

hibernate_03_session详解的相关文章

Spring事务管理(详解+实例)

写这篇博客之前我首先读了<Spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都

转载:DenseNet算法详解

原文连接:http://blog.csdn.net/u014380165/article/details/75142664 参考连接:http://blog.csdn.net/u012938704/article/details/53468483 本文这里仅当学习笔记使用,具体细节建议前往原文细度. 论文:Densely Connected Convolutional Networks 论文链接:https://arxiv.org/pdf/1608.06993.pdf 代码的github链接:h

MariaDB(MySQL)创建、删除、选择及数据类型使用详解

一.MariaDB简介(MySQL简介略过) MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品.在存储引擎方面,使用XtraDB(英语:XtraDB)来代替MySQL的InnoDB. MariaDB由MySQL的创始人Michael Widenius(英语:Michael Widenius)主导开发,他早前曾以10亿美元的价格,将自己创建的公司MySQL A

HttpServletResponse和HttpServletRequest详解

HttpServletResponse,HttpServletRequest详解 1.相关的接口 HttpServletRequest HttpServletRequest接口最常用的方法就是获得请求中的参数,这些参数一般是客户端表单中的数据.同时,HttpServletRequest接口可以获取由客户端传送的名称,也可以获取产生请求并且接收请求的服务器端主机名及IP地址,还可以获取客户端正在使用的通信协议等信息.下表是接口HttpServletRequest的常用方法. 说明:HttpServ

POSIX 线程详解(经典必看)

总共三部分: 第一部分:POSIX 线程详解                                   Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  2000 年 7 月 01 日 第二部分:通用线程:POSIX 线程详解,第 2部分       Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  20

.NET深入解析LINQ框架(五:IQueryable、IQueryProvider接口详解)

阅读目录: 1.环路执行对象模型.碎片化执行模型(假递归式调用) 2.N层对象执行模型(纵横向对比链式扩展方法) 3.LINQ查询表达式和链式查询方法其实都是空壳子 4.详细的对象结构图(对象的执行原理) 5.IQueryable<T>与IQueryProvider一对一的关系能否改成一对多的关系 6.完整的自定义查询 1]. 环路执行对象模型.碎片化执行模型(假递归式调用) 这个主题扯的可能有点远,但是它关系着整个LINQ框架的设计结构,至少在我还没有搞懂LINQ的本意之前,在我脑海里一直频

netstat状态详解

一.生产服务器netstat tcp连接状态................................................................................ 2 1.1生产服务器某个业务LVS负载均衡上连接状态数量............................................... 2 1.2生产服务器某个业务web上连接状态数量...............................................

详解go语言的array和slice 【二】

上一篇  详解go语言的array和slice [一]已经讲解过,array和slice的一些基本用法,使用array和slice时需要注意的地方,特别是slice需要注意的地方比较多.上一篇的最后讲解到创建新的slice时使用第三个索引来限制slice的容量,在操作新slice时,如果新slice的容量大于长度时,添加新元素依然后使源的相应元素改变.这一篇里我会讲解到如何避免这些问题,以及迭代.和做为方法参数方面的知识点. slice的长度和容量设置为同一个值 如果在创建新的slice时我们把

13.Linux键盘按键驱动 (详解)

版权声明:本文为博主原创文章,未经博主允许不得转载. 在上一节分析输入子系统内的intput_handler软件处理部分后,接下来我们开始写input_dev驱动 本节目标: 实现键盘驱动,让开发板的4个按键代表键盘中的L.S.空格键.回车键 1.先来介绍以下几个结构体使用和函数,下面代码中会用到 1)input_dev驱动设备结构体中常用成员如下: struct input_dev { void *private; const char *name; //设备名字 const char *ph