@chy282
2017-12-01T06:46:58.000000Z
字数 8903
阅读 2877
Hibernate
© 版权声明:本文为博主原创文章,转载请注明出处
Hibernate是对JDBC的轻量级封装,将JDBC的Connection封装到了Session中,因此Hibernate对数据库的操作大多都是通过session实现的。
在获取Session对象时,Hibernate默认关闭了自动提交事务。
Hibernate执行SQL时,会将所有SQL存入Session的缓存中,提交事务时,再在数据库中执行SQL
private SessionFactory sessionFactory;private Session session;private Transaction transaction;@Testpublic void testSaveStudent() {// 生成学生对象Student s = new Student(3, "张三丰", "男", new Date(), "武当山");session.save(s);}Beforepublic void init() {// 创建会话工厂对象sessionFactory = new Configuration().configure().buildSessionFactory();// 创建会话对象session = sessionFactory.openSession();// 开始事务transaction = session.beginTransaction();}@Afterpublic void destory () {// 提交事务transaction.commit();// 关闭会话session.close();// 关闭会话工厂sessionFactory.close();}
若不开启事务或开启事务不提交,则SQL语句就不能在数据库中执行,此时可以通过session.flush()方法,强制将缓存中的SQL语句刷新到数据库
private SessionFactory sessionFactory;private Session session;/*** 不开启事务,数据无法保存到数据库*/@Testpublic void testSaveStudentNoTransaction() {// 生成学生对象Student s = new Student(5, "张三丰", "男", new Date(), "武当山");session.save(s);}/*** 不开启事务,使用session.flush()强制同步数据到数据库*/@Testpublic void testSaveStudentByflush() {// 生成学生对象Student s = new Student(5, "张三丰", "男", new Date(), "武当山");session.save(s);session.flush();// 当不使用事务时,需使用flush方法,强制提交}/*** 开启事务,但不使用commit提交,而是使用session.flush()强制提交*/@Testpublic void testSaveStudentTransaction() {// 开启事务session.beginTransaction();// 生成学生对象Student s = new Student(6, "张三丰", "男", new Date(), "武当山");session.save(s);session.flush();// 不提交事务时,直接使用flush方法,也可强制提交}Beforepublic void init() {// 创建会话工厂对象sessionFactory = new Configuration().configure().buildSessionFactory();// 创建会话对象session = sessionFactory.openSession();}@Afterpublic void destory () {// 关闭会话session.close();// 关闭会话工厂sessionFactory.close();}
Hibernate使用面向对象的思想来进行数据库操作,推荐使用的也是封装的HQL语句,但有时项目需要进行jdbc操作,此时可以使用session.doWork(),在匿名内部类中获取Connection,进行jdbc操作。
/*** 使用session.doWork()实现jdbc操作*/@Testpublic void testSessionDowork() {final List<String> list = new ArrayList<String>();session.doWork(new Work() { // 使用dowork方法进行jdbc操作@Overridepublic void execute(Connection connection) throws SQLException {String sql = "select sname from student";PreparedStatement ps = (PreparedStatement) connection.prepareStatement(sql);ResultSet rs = ps.executeQuery();try {while (rs.next()) {String name = rs.getString(1);list.add(name);}} finally {if (rs != null) {rs.close();}if (ps != null) {ps.close();}// 此时connection被session管理,不能手动关闭/*if (connection != null) {connection.close();}*/}}});for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}}Beforepublic void init() {// 创建会话工厂对象sessionFactory = new Configuration().configure().buildSessionFactory();// 创建会话对象session = sessionFactory.openSession();}@Afterpublic void destory () {// 关闭会话session.close();// 关闭会话工厂sessionFactory.close();}
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.imooc</groupId><artifactId>Hibernate_001</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!-- Hibernate --><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>5.1.5.Final</version></dependency><!-- mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.22</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.6.1</version><configuration><target>1.7</target><source>1.7</source><encoding>UTF-8</encoding></configuration></plugin></plugins></build></project>
Student.java
package com.imooc.hibernate.model;import java.util.Date;public class Student {private int sid; // 学号private String sname; // 姓名private String gender; // 性别private Date birthday; // 出生日期private String address; // 地址public Student() {}public Student(int sid, String sname, String gender, Date birthday, String address) {this.sid = sid;this.sname = sname;this.gender = gender;this.birthday = birthday;this.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;}@Overridepublic String toString() {return "Student [sid=" + sid + ", sname=" + sname + ", gender="+ gender + ", birthday=" + birthday + ", address=" + address + "]";}}
student.hbm.xml
<?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><class name="com.imooc.hibernate.model.Student"><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"></column></property><property name="birthday" type="java.util.Date"><column name="BIRTHDAY"/></property><property name="address" type="java.lang.String"><column name="ADDRESS"></column></property></class></hibernate-mapping>
hibernate.cfg.xml
<?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">20121221</property><!-- 数据库驱动 --><property name="connection.driver_class">com.mysql.jdbc.Driver</property><!-- 数据库连接url --><property name="connection.url">jdbc:mysql://localhost:3306/hibernate?useSSL=true&useUnicode=true&characterEncoding=UTF-8</property><!-- 方言 --><property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property><!-- 展示SQL --><property name="show_sql">true</property><!-- 格式化SQL --><property name="format_sql">false</property><!-- 建表策略 --><property name="hbm2ddl.auto">update</property><!-- 指定映射文件 --><mapping resource="hbm/student.hbm.xml"/></session-factory></hibernate-configuration>
StudentTest.java
package com.imooc.hibernate.test;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.Date;import java.util.List;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.hibernate.jdbc.Work;import org.junit.After;import org.junit.Before;import org.junit.Test;import com.imooc.hibernate.model.Student;import com.mysql.jdbc.PreparedStatement;public class StudentTest {private SessionFactory sessionFactory;private Session session;/*** 不开启事务,数据无法保存到数据库*/@Testpublic void testSaveStudentNoTransaction() {// 生成学生对象Student s = new Student(5, "张三丰", "男", new Date(), "武当山");session.save(s);}/*** 不开启事务,使用session.flush()强制同步数据到数据库*/@Testpublic void testSaveStudentByflush() {// 生成学生对象Student s = new Student(5, "张三丰", "男", new Date(), "武当山");session.save(s);session.flush();// 当不使用事务时,需使用flush方法,强制提交}/*** 开启事务,但不使用commit提交,而是使用session.flush()强制提交*/@Testpublic void testSaveStudentTransaction() {// 开启事务session.beginTransaction();// 生成学生对象Student s = new Student(6, "张三丰", "男", new Date(), "武当山");session.save(s);session.flush();// 不提交事务时,直接使用flush方法,也可强制提交}/*** 使用session.doWork()实现jdbc操作*/@Testpublic void testSessionDowork() {final List<String> list = new ArrayList<String>();session.doWork(new Work() { // 使用dowork方法进行jdbc操作@Overridepublic void execute(Connection connection) throws SQLException {String sql = "select sname from student";PreparedStatement ps = (PreparedStatement) connection.prepareStatement(sql);ResultSet rs = ps.executeQuery();try {while (rs.next()) {String name = rs.getString(1);list.add(name);}} finally {if (rs != null) {rs.close();}if (ps != null) {ps.close();}// 此时connection被session管理,不能手动关闭/*if (connection != null) {connection.close();}*/}}});for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}}@Beforepublic void init() {// 创建会话工厂对象sessionFactory = new Configuration().configure().buildSessionFactory();// 创建会话对象session = sessionFactory.openSession();}@Afterpublic void destory () {// 关闭会话session.close();// 关闭会话工厂sessionFactory.close();}}
使用Hibernate时,若需使用jdbc进行操作,则使用session.doWork()
若需提前提交session缓存中的SQL,则使用session.flush()
eg:
Transaction tx = session.beginTransaction();for (int i = 0; i < 100000; i++) {Student s = new Student(...);session.save(s);if (i % 20 == 0) { // 防止session内存溢出session.flush();session.clear();}}tx.commit();session.close();