1、对象状态转换跟session的操作函数有关
2、对象状态有三种:临时对象,持久化对象,游离对象
3、对象:
(1). 临时对象: session中不存在,数据库中不存在,通过new创建的对象的状态
(2). 持久化对象:session中存在,数据库中存在,调用session的save()、update()、saveOrUpdate()等方法时的对象的状态
(3). 游离对象: session中不存在,数据库中存在,session关闭后的对象状态
4、三种状态的区别
①临时对象:session中不存在,数据库中不存在
②持久化对象:session中存在,数据库中存在
③游离对象:session中不存在,数据库中存在
5、对象转换示意图
6、对象转换时,session调用的函数:
①只要遇到用new来创建的的对象,都是临时对象
②要变成持久化对象,通常都会调用session的get()、load()、update()、saveOrUpdate()、save()函数
③持久化对象在回收之前,需要先用close()或者clean()或者evict()变成游离对象,然后用delete()变成删除状态等待回收
④临时对象只能变成持久化对象或者等待回收
⑤持久化对象只能变成游离对象或者直接变成删除状态
⑥游离对象只能变成持久化对象或者变成删除状态或者直接被回收
7、没什么好说的,就记住什么情况对象状态会变成什么就好了
8、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"></property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/hebernateTEST</property>
<!-- 配置hibernate基本信息 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 执行操作室是否在控制台打印sql -->
<property name="show_sql">true</property>
<!-- 是否对sql格式化 -->
<property name="format_sql">true</property>
<!-- 指定自动生成数据表的策略 -->
<property name="hbm2ddl.auto">update</property>
<!-- 设置 Hibernate 的事务隔离级别 -->
<property name="connection.isolation">2</property>
<!-- 设置调用delete()时,OID变成null -->
<property name="hibernate.use_identifier_rollback">true</property>
<!-- 指定关联的 *.hbm.xml文件(目录结构) 每个.hbm.xml对应一个数据表-->
<mapping resource="com/demo/sshtest/Info.hbm.xml"/>
</session-factory>
</hibernate-configuration>
9、Info.hbm.xml
<?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 2018-4-4 16:22:30 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.demo.sshtest.Info" table="INFO">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="pswd" type="java.lang.String">
<column name="PSWD" />
</property>
<property name="description" type="java.lang.String">
<column name="DESCRIPTION" />
</property>
</class>
</hibernate-mapping>
10、Info.java
package com.demo.sshtest;
public class Info {
public Integer id;
public String name;
public String pswd;
public String description;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPswd() {
return pswd;
}
public void setPswd(String pswd) {
this.pswd = pswd;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Info(){}
public Info(String name, String pswd, String description) {
super();
this.name = name;
this.pswd = pswd;
this.description = description;
}
public Info(Integer id,String name, String pswd, String description) {
super();
this.id = id;
this.name = name;
this.pswd = pswd;
this.description = description;
}
@Override
public String toString() {
return "Info [id=" + id + ", name=" + name + ", pswd=" + pswd + ", description=" + description + "]";
}
}
11、TestSession.java
package com.demo.sshtest;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
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.After;
import org.junit.Before;
import org.junit.Test;
public class TestSession {
public SessionFactory sessionFactory;
public Session session;
public Transaction transaction;
//对象的状态(临时对象,持久化对象,游离对象)
//1、临时对象: session中不存在,数据库中不存在,通过new创建的对象的状态
//2、持久化对象:session中存在,数据库中存在,调用session的save()、update()、saveOrUpdate()等方法时的对象的状态
//3、游离对象: session中不存在,数据库中存在,session关闭后的对象状态
// session database
//临时对象 F F
//持久化对象 T T
//游离对象 F T
//这里用@xxxx的junit调试的时候 要把hamcrest-all-1.3.jar、junit.jar加载上
@Before
public void init(){
Configuration configuration = new Configuration().configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
session = sessionFactory.openSession();
transaction = session.beginTransaction();
System.out.println("init");
}
@After
public void destory(){
transaction.commit();
session.close();
sessionFactory.close();
System.out.println("destory");
}
@Test
public void Refresh(){
//执行refresh()时,会执行select语句,查询数据库,更新session
Info info = (Info)session.get(Info.class, 1);
info.setName("sdfadfadsfa");
System.out.println("========"+info);
session.refresh(info);
System.out.println("========"+info);
}
@Test
public void Flush(){
//Flush 类似Update 操作
//作用: 使数据表中的记录和 Session 缓存中的对象的状态保持一致. 为了保持一致, 则可能会发送对应的 SQL 语句
//1. 在 Transaction 的 commit() 方法中: 先调用 session 的 flush 方法, 再提交事务
//2. flush() 方法会可能会发送 SQL 语句, 但不会提交事务.
//3. 注意:
// 1)在未提交事务或显式的调用 session.flush() 方法之前, 也有可能会进行 flush() 操作.
// 2)执行 HQL 或 QBC 查询, 会先进行 flush() 操作, 以得到数据表的最新的记录
System.out.println("testflush");
Info info = (Info)session.get(Info.class, 1);
info.setPswd("323");
session.flush();
//flush后没更新数据库,但是destory()的时候执行了commit()操作,这个时候数据库才更新了pswd
}
@Test
public void Clear(){
//没执行clear(),session里面的EntityName是有数据的,且info2执行session.get()的时候不会执行select语句
//执行clear()之后session里面是被清空的,而且info2执行session.get()的时候会再次执行select语句
Info info = (Info)session.get(Info.class, 1);
System.out.println("========"+info);
System.out.println("========"+session);
session.clear();
System.out.println("========"+session);
Info info2 = (Info)session.get(Info.class, 1);
System.out.println("========"+info2);
}
@Test
public void Save(){
//1、使一个临时对象变为持久化对象
//2、为对象分配OID(即:id)
//3、在flush缓存时,会执行insert语句(在transaction.commit()方法中)
//4、设置主键id的话,需要在save()方法之前才有效
//5、持久化对象的OID(即:id)是不能被修改的
//6、若记录的OID(即:id)是由底层数据库使用自增的方式生成的, 则在调用 save() 方法时, 就会立即发送 INSERT 语句
System.out.println("Save");
Info info = new Info("name1", "pswd1", "desc1");
session.save(info);
}
@Test
public void Persist(){
//1、类似save()方法,也会执行insert语句
//2、调用persist()方法之前,如果对象有OID(即:id),则不执行insert并且抛出异常(save()方法不会)
System.out.println("Persist");
Info info = new Info("name1", "pswd1", "desc1");
session.persist(info);
}
@Test
public void Get(){
//1、获取指定id的数据
//2、调用get()方法马上执行查询(立即检索)
//3、session没关闭,需要使用对象时,如果数据表中没有对应记录,返回null
//4、在需要初始化代理对象前,关闭了session,不影响,因为已经加载代理对象了
System.out.println("Get");
Info info = (Info)session.get(Info.class, 1);
System.out.println(info);
}
@Test
public void Load(){
//1、获取指定id的数据
//2、调用load()方法时,如果不使用对象,则不会立即执行查询操作,并且返回一个代理对象 (延迟加载/延迟检索)
//3、session没关闭,需要使用对象时,如果数据表中没有对应记录,抛出异常(因为已经返回代理对象了,但是对象不存在,所以异常)
//4、load()方法可能抛出懒加载异常LazyInitializationException:在需要初始化代理对象前,关闭了session,就会抛这个异常
System.out.println("Load");
Info info = (Info)session.load(Info.class, 1);
System.out.println(info.getClass().getName());
//System.out.println(info);
}
@Test
public void Update(){
//1、若更新一个持久化对象,不需要显式调用update(),因为在调用transaction.commit()方法时,commit()方法会先执行session.flush()
//2、更新一个游离对象,需要显式调用session.update(),把游离对象转换成持久化对象
//3、注意事项:
// 1)要更新的有你对象和数据表记录,不管是否相同,都会执行update语句
// 2)如果希望update()方法只有在session数据有改变的情况下才执行,则需要到*.hbm.xml的class标签里面,加上select-before="true"
// 3)select-before默认为false,一般情况下不设置这个参数
// 4)如果数据表中没有对应id的记录,还使用update()的话,会抛出异常
// 5)如果update()方法关联的是一个游离对象时,session缓存中存在相同id的持久化对象,则会抛出异常,因为session缓存中不能存在OID相同的两个对象
System.out.println("Update");
Info info = (Info)session.get(Info.class, 1);
//info.setName("aoaoaoao");
session.update(info);
}
@Test
public void saveOrUpdate(){
//1、如果OID不为null,但数据表中没有和请求对应的记录,saveOrUpdate()方法就会抛出 异常(如:下面info.setId是2,但是数据库里面没有id为2的记录,这个时候会抛出异常)
//2、OID值等于id的unsaved-value属性值的对象,也会被认为是个游离对象
// (1)unsaved-value的值与子类对象的Id相等,表明没有持久化,调用save()
// (2)unsaved-value的值与子类对象的Id不相等,表明已持久化,调用Update()
// (3)unsaved-value默认值是null
System.out.println("saveOrUpdate");
Info info = new Info("dddsd", "bfsdfsbb", "xxsdfsdx");
info.setId(2);
session.saveOrUpdate(info);
}
@Test
public void merge(){
//就是用来把其他状态的对象变成持久化对象
//1、判断是游离对象还是临时对象
//2、如果是游离对象,先检查session里面是否存在OID,存在就执行update,不存在就加载数据库中对应id的持久化对象,然后执行update,最后不管是否存在OID,都会返回持久化对象
//3、如果是临时对象,创建一个新的对象,然后把下面info对象复制过去,再持久化新的对象,然后执行insert
System.out.println("merge");
Info info = (Info)session.get(Info.class, 1);
session.clear();
session.merge(info);
}
@Test
public void delete(){
//1、可以删除一个持久化对象,也可以删除一个游离对象
//2、逻辑运行顺序:(1)执行delte语句(2)从session删除这个对象
//3、cfg.xml配置文件中的hibernate.use_identifier_rollback默认为false,如果改为true,delete()会把对象OID改为null,把对象变成临时对象
//4、执行条件:OID和表中记录有对应,就能执行delete(),否则没反应
//5、如果OID在表中没有记录,则抛出异常
System.out.println("delete");
//删除游离对象
//Info info = new Info();
//info.setId(1);
//session.delete(info2);
//删除持久化对象
Info info2 = (Info)session.get(Info.class, 7);
session.delete(info2);
System.out.println(info2);
}
@Test
public void evict(){
//1、从session缓存中把指定持久化对象移除
System.out.println("evict");
Info info1 = (Info)session.get(Info.class, 5);
Info info2 = (Info)session.get(Info.class, 6);
info1.setName("asdfasdfa");
info2.setName("fefeefedfdfdfef");
//info1的数据不会更新到数据库
//info2的数据会更新到数据库
session.evict(info1);
}
@Test
public void Dowork(){
//通过调用doWork()方法,就能调用jre中原生的jdbc接口
System.out.println("dowork");
session.doWork(new Work() {
@Override
public void execute(Connection con) throws SQLException {
String sql = "select * from info where id=6";
Statement stmt = null;
ResultSet rs = null;
PreparedStatement pstmt;
try{
stmt = con.createStatement();
//传入类似sql="select * from test"
pstmt=con.prepareStatement(sql);
rs=pstmt.executeQuery();
while (rs.next()) {
System.out.println("打印resultset里面的参数值:");
System.out.println("id:"+rs.getInt("id"));
System.out.println("name:"+rs.getString("name"));
System.out.println("pswd:"+rs.getString("pswd"));
System.out.println("description:"+rs.getString("description"));
}
rs.close();
}catch (Exception e){
System.out.println("数据查询失败!");
e.printStackTrace();
}
try{
if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
}catch(Exception e) {
e.printStackTrace();
}
}
});
}
}
session每个方法函数的调用方法里面,都写满了注释,有关的作用、解释、注意事项都有了,调试的时候,是用junit的,直接选了要运行的方法函数然后用junit运行就好了
12、项目目录
13、运行结果:没什么好截图的,运行以下,看看select语句运行之后,对应不同参数,update语句或者insert语句select语句等,有没有按照函数应发挥的作用在运行,就好了。
14、demo
https://download.csdn.net/download/qq_22778717/10338899