参考博客:Hibernate——入门
作者hibernate系列:https://blog.csdn.net/gavin_john/article/category/7475515
1、Employee注解 不再使用 employee.hbm.xml
package com.yiibai;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "EMPLOYEE")
public class Employee {
@Id
@Column(name = "ID")
private int id;
@Column(name = "FIRSTNAME")
private String firstName;
@Column(name = "LASTNAME")
private String lastName;
public Employee() {}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
2、hibernate.cfg.xml 中的对象关系映射文件的位置需要修改
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:XE</property>
<property name="connection.username">petition</property>
<property name="connection.password">petition</property>
<property name="dialect">org.hibernate.dialect.OracleDialect</property>
<property name="show_sql">true</property>
<!-- 隐藏下面的 -->
<!--
<mapping resource="employee.hbm.xml"/>
-->
<mapping class="com.yiibai.Employee"/>
</session-factory>
</hibernate-configuration>
3、SessionFactory是一个重量级的类,所以应该保证其是单态的。所以将其封装起来。如下:
package com.yiibai;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* 单例模式
*
* 在使用Hibernate开发项目的时候,一定保证只有一个SessionFactory,
* 原则:理论上是一个数据库对应一个SessionFactory,项目中用了两个数据库,则可以存在两个SessionFactory
*/
final public class MySessionFactory {
private static SessionFactory sessionFactory;
static {
//1.创建Configuration,并调用configure方法读取配置文件完成初始化,
// 默认的文件名为hibernate.cfg.xml,故可以不写文件名
sessionFactory = new Configuration().configure().buildSessionFactory();
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
private MySessionFactory() {}
}
4、对Employee的修改
package com.yiibai;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class Test2 {
public static void main(String[] args) {
// addEmployee();
// updateEmployee();
// delectEmployee();
}
/**
* 向数据库中添加一个Employee对象
*/
public static void addEmployee() {
// 获取一个会话
Session session = MySessionFactory.getSessionFactory().openSession();
// 获取要修改的对象,再修改
/* 对于Hibernate而言,要求程序在进行增加,删除,修改的时候使用事务提交 */
Transaction t = session.beginTransaction();
// 添加一个Employee
Employee employee = new Employee();
employee.setId(1658);
employee.setFirstName("wang");
employee.setLastName("lingsheng");
// 之前的插入是insert语句,现在不用了
// 直接调用session.save(),就可以将Employee对象插入数据库
session.save(employee); // save employee 就是持久化该对象(把数据保存到了数据库中)
t.commit();
session.close();
System.out.println("successfully saved");
}
/**
* 修改Employee
*/
public static void updateEmployee() {
// 获取一个会话
Session session = MySessionFactory.getSessionFactory().openSession();
// 获取要修改的对象,再修改
Transaction t = session.beginTransaction();
// load是通过主键属性获取对象实例 <--> 与表的记录对应
Employee employee = session.load(Employee.class, 1);
// 下面这句话会导致一个update语句产生
employee.setFirstName("王灵生");
t.commit();
session.close();
System.out.println("successfully update");
}
public static void delectEmployee() {
// 获取一个会话
Session session = MySessionFactory.getSessionFactory().openSession();
// 删除,先获取该雇员,然后再删除
Transaction transaction = session.beginTransaction();
Employee employee = session.load(Employee.class, 1);
session.delete(employee);
transaction.commit();
session.close();
System.out.println("successfully delete");
}
}
openSession()和getCurrentSession()深入讨论
在SessionFactory启动的时候,Hibernate会根据配置创建相应的CurrentSessionContext,在getCurrentSession()被调用的时候,实际执行的方法是CurrentSessionContext.currentSession()。在currentSession执行时,如果当前Session为空,currentSession会调用SessionFactory的openSession()。
增加HibernateUtil
类,使用ThreadLocal
(线程局部变量模式)将Session
与线程关联起来。
package com.yiibai;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static SessionFactory sessionFactory = null;
// 用ThreadLocal模式(线程局部变量模式)管理Session
private static ThreadLocal<Session> threadLocal = new ThreadLocal<>();
private HibernateUtil() {}
static {
sessionFactory = new Configuration().configure().buildSessionFactory();
}
/**
* 获取全新的Session
* @return
*/
public static Session openSession() {
return sessionFactory.openSession();
}
/**
* 获取和线程关联的session
* @return
*/
public static Session getCurrentSession() {
Session session = threadLocal.get();
if (session==null) {
session = sessionFactory.openSession();
// 把session对象设置到threadLocal
// 相当于该session已经和线程绑定
threadLocal.set(session);
}
return session;
}
}