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类:
package com.imooc.hibernate;
import java.util.Date;
public class Students {
private int sid;
private String sname;
private String gender;
private Date birthday;
private String address;
public Students(int sid, String sname, String gender, Date birthday, String address) {
super();
this.sid = sid;
this.sname = sname;
this.gender = gender;
this.birthday = birthday;
this.address = address;
}
@Override
public String toString() {
return "Students [sid=" + sid + ", sname=" + sname + ", gender=" + gender + ", birthday=" + birthday
+ ", address=" + address + "]";
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
java类的配置文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-5-23 0:24:09 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.imooc.hibernate.Students" table="STUDENTS">
<id name="sid" type="int">
<column name="SID" />
<generator class="assigned" />
</id>
<property name="sname" type="java.lang.String">
<column name="SNAME" />
</property>
<property name="gender" type="java.lang.String">
<column name="GENDER" />
</property>
<property name="birthday" type="java.util.Date">
<column name="BIRTHDAY" />
</property>
<property name="address" type="java.lang.String">
<column name="ADDRESS" />
</property>
</class>
</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>
测试类
package com.icoom.test; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.Test; public class SessionTest { /*
* 使用openSession获得session对象
*/
@Test
public void testOpenSession() {
Configuration config = new Configuration().configure();//获得配置对象(读取hibernate.cfg.xml文件)
// 获得服务注册对象
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
// 获得sessionFactory对象
SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry);
// 获得session对象
Session session = sessionFactory.openSession();
if (session != null) {
System.out.println("session创建成功");
} else {
System.out.println("session创建失败");
}
} /*
* 使用getCurrentSession获得session对象(需要在hibernate配置文件中设置)
*/
@Test
public void testGetCurrentSession() {
Configuration config = new Configuration().configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry);
Session session = sessionFactory.getCurrentSession();
if (session != null) {
System.out.println("session创建成功!");
} else {
System.out.println("session创建失败!");
}
}
}
那么,openSession和getCurrentSession有什么区别?
1. getCurrentSession在事务提交或者回滚之后会自动关闭,openSession需要手动关闭。如果使用openSession而没有手动关闭,多次之后会导致连接池溢出。
package com.icoom.test; import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.Test; import com.imooc.hibernate.Students; public class SessionTest { @Test
public void saveStudentsByOpenSession() { // 获取配置对象
Configuration configure = new Configuration().configure();
// 获得服务注册对象
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configure.getProperties()).buildServiceRegistry();
/*
* 创建sessionFactory对象。sessionFactory是一种工厂模式,
* 目的是返回session,而不必new一个session。这样做比较安全。
*/
SessionFactory sessionFactory = configure.buildSessionFactory(serviceRegistry);
// 创建第一个session对象
Session session1 = sessionFactory.openSession();
// 开启事务
Transaction transaction = session1.beginTransaction();
// 生成一个学生对象
Students s = new Students(1,"张三","男",new Date(),"北京");
session1.doWork(new Work() { @Override
public void execute(Connection connection) throws SQLException {
// TODO Auto-generated method stub
System.out.println("connection's hashCode:" + connection.hashCode());
} });
session1.save(s);
// session1.close(); // 不执行close()方法,继续新建session对象
transaction.commit(); // 创建第二个session对象
Session session2 = sessionFactory.openSession();
transaction = session2.beginTransaction();
s = new Students(2,"李四","女",new Date(),"上海");
session2.doWork(new Work() { @Override
public void execute(Connection connection) throws SQLException {
// TODO Auto-generated method stub
System.out.println("connection's hashCode:" + connection.hashCode());
} });
session2.save(s);
transaction.commit();
}
}

控制台打印出两个hashcode值不同,所以使用openSession()方法而不手动关闭,每次创建都会新建一个链接,有可能导致连接池溢出。
再看getCurrentSession():
package com.icoom.test; import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.Test; import com.imooc.hibernate.Students; public class SessionTest { @Test
public void saveStudentsByGetCurrentSession() { // 获取配置对象
Configuration configure = new Configuration().configure();
// 获得服务注册对象
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configure.getProperties()).buildServiceRegistry();
/*
* 创建sessionFactory对象。sessionFactory是一种工厂模式,
* 目的是返回session,而不必new一个session。这样做比较安全。
*/
SessionFactory sessionFactory = configure.buildSessionFactory(serviceRegistry);
// 创建第一个session对象
Session session1 = sessionFactory.getCurrentSession();
// 开启事务
Transaction transaction = session1.beginTransaction();
// 生成一个学生对象
Students s = new Students(1,"张三","男",new Date(),"北京");
session1.doWork(new Work() { @Override
public void execute(Connection connection) throws SQLException {
// TODO Auto-generated method stub
System.out.println("connection's hashCode:" + connection.hashCode());
} });
session1.save(s);
// session1.close(); // 不执行close()方法,继续新建session对象
transaction.commit(); // 创建第二个session对象
Session session2 = sessionFactory.getCurrentSession();
transaction = session2.beginTransaction();
s = new Students(2,"李四","女",new Date(),"上海");
session2.doWork(new Work() { @Override
public void execute(Connection connection) throws SQLException {
// TODO Auto-generated method stub
System.out.println("connection's hashCode:" + connection.hashCode());
} });
session2.save(s);
// session2.close();
transaction.commit();
}
}

两个hashCode一致。
2. openSession每次创建新的session对象,getCurrentSession使用现有的session对象。
package com.icoom.test; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.Test; public class SessionTest { /*
* openSession每次创建新的session对象
*/
@Test
public void testOpenSession() {
Configuration config = new Configuration().configure();//获得配置对象(读取hibernate.cfg.xml文件)
// 获得服务注册对象
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
// 获得sessionFactory对象
SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry);
// 获得session对象
Session session1 = sessionFactory.openSession();
Session session2 = sessionFactory.openSession();
System.out.println(session1 == session2); // false
} /*
* getCurrentSession使用现有的session对象
*/
@Test
public void testGetCurrentSession() {
Configuration config = new Configuration().configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry);
Session session1 = sessionFactory.getCurrentSession();
Session session2 = sessionFactory.getCurrentSession();
System.out.println(session1 == session2); // true
}
}
hibernate_03_session详解的更多相关文章
- Linq之旅:Linq入门详解(Linq to Objects)
示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...
- 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)
一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...
- EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解
前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...
- Java 字符串格式化详解
Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...
- Android Notification 详解(一)——基本操作
Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...
- Android Notification 详解——基本操作
Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...
- Git初探--笔记整理和Git命令详解
几个重要的概念 首先先明确几个概念: WorkPlace : 工作区 Index: 暂存区 Repository: 本地仓库/版本库 Remote: 远程仓库 当在Remote(如Github)上面c ...
- Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
- Node.js npm 详解
一.npm简介 安装npm请阅读我之前的文章Hello Node中npm安装那一部分,不过只介绍了linux平台,如果是其它平台,有前辈写了更加详细的介绍. npm的全称:Node Package M ...
随机推荐
- 【Mail.Ru Cup 2018 Round 2 B】 Alice and Hairdresser
[链接] 我是链接,点我呀:) [题意] [题解] 因为只会增加. 所以. 一开始暴力算出来初始答案 每次改变一个点的话. 就只需要看看和他相邻的数字的值就好. 看看他们是不是大于l 分情况增加.减少 ...
- 【codeforces 527D】Clique Problem
[题目链接]:http://codeforces.com/contest/527/problem/D [题意] 一维线段上有n个点 每个点有坐标和权值两个域分别为xi,wi; 任意一对点(i,j) 如 ...
- group by语句,聚合函数与其他语句(关系,执行过程)
(本文一切基于SQL SERVER 2008 R2) 先来看一个语句执行过程发生的错误提示: 消息 8120,级别 16,状态 1,第 2 行 选择列表中的列 'SC.CNO' 无效,因为该列没有包含 ...
- centos7 yum源
https://www.cnblogs.com/muyunren/p/7221505.html https://www.cnblogs.com/renpingsheng/p/7845096.html
- 网络流入门 Drainage Ditches
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submission(s) ...
- HDU 5392 BC #51
就是求最大公倍数,但要用分解质因子求. 自己写的WA到爆.... #include<iostream> #include<stdio.h> #include<math.h ...
- 微信获得access-token
微信获得access-token RestTemplate template = new RestTemplate(); String appid = "aa"; String s ...
- nyoj 1238 最少换乘 (河南省第八届acm程序设计大赛)
题目1238 题目信息 执行结果 本题排行 pid=1238" style="text-decoration:none; color:rgb(55,119,188)"&g ...
- spring基于通用Dao的多数据源配置
有时候在一个项目中会连接多个数据库,须要在spring中配置多个数据源,近期就遇到了这个问题,因为我的项目之前是基于通用Dao的,配置的时候问题不断.这样的方式和资源文件冲突:扫描映射文件的话,Sql ...
- URAL 1196. History Exam (二分)
1196. History Exam Time limit: 1.5 second Memory limit: 64 MB Professor of history decided to simpli ...