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>
		<!-- dialect  方言-->
		<property name="dialect">
			org.hibernate.dialect.MySQLDialect
		</property>
		<property name="connection.username">root</property>
		<property name="connection.password">123456</property>
		<property name="connection.url">
			jdbc:mysql://localhost:3306/cloud_note
		</property>
		<property name="connection.driver_class">
			com.mysql.jdbc.Driver
		</property>
		
		<!-- 测试、调试需要 -->
		<!-- 可以输出生成的sql -->
		<property name="show_sql">true</property>
		<!-- 格式化sql,更美观 -->
		<property name="format_sql">true</property>
		
		<!-- 加载映射描述文件 -->
		<!-- <mapping resource="hbm/User.hbm.xml"/> -->
	</session-factory>
</hibernate-configuration>

此处连接的是Mysql数据库

User实体类:

package cn.tedu.entity;

import java.io.Serializable;

public class User implements Serializable{
	private static final long serialVersionUID = -2074369796447083139L;
	
	private String id;
	private String name;
	private String password;
	private String token;
	private String nick;
	public User() {}
	public User(String id, String name, String password, String token, String nick) {
		super();
		this.id = id;
		this.name = name;
		this.password = password;
		this.token = token;
		this.nick = nick;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getToken() {
		return token;
	}
	public void setToken(String token) {
		this.token = token;
	}
	public String getNick() {
		return nick;
	}
	public void setNick(String nick) {
		this.nick = nick;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((nick == null) ? 0 : nick.hashCode());
		result = prime * result + ((password == null) ? 0 : password.hashCode());
		result = prime * result + ((token == null) ? 0 : token.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (nick == null) {
			if (other.nick != null)
				return false;
		} else if (!nick.equals(other.nick))
			return false;
		if (password == null) {
			if (other.password != null)
				return false;
		} else if (!password.equals(other.password))
			return false;
		if (token == null) {
			if (other.token != null)
				return false;
		} else if (!token.equals(other.token))
			return false;
		return true;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", password=" + password + ", token=" + token + ", nick=" + nick
				+ "]";
	}
}

测试类:

package cn.tedu.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.Before;
import org.junit.Test;

import cn.tedu.entity.User;

public class TestCase {
	SessionFactory factory;
	
	@Before
	public void init(){
		Configuration cfg = new Configuration();
		cfg.configure("hibernate.cfg.xml");
		factory = cfg.buildSessionFactory();
	}
	
	@Test
	//Hibernate 3.6版本获取SessionFactory
	public void testSession(){
		//创建Session对象 session的底层就是JDBC Connection
		//如果没有异常,就说明数据库连接成功
		Session session = factory.openSession();
		System.out.println(session);
		session.close();
	}
	
	@Test
	//插入一条数据
	public void testSaveObject(){
		User user = new User("99", "Tom", "123", "OK", "Cat");
		Session session = factory.openSession();
		Transaction tx = session.beginTransaction();
		session.save(user);
		tx.commit();
		session.close();
	}
	
	@Test
	//修改数据
	public void testUpdateObject(){
		Session session = null;
		Transaction tx = null;
		try{
			session = factory.openSession();
			tx = session.beginTransaction();//开启事务
			//测试更新功能
			User user = (User)session.get(User.class, "100");//查询一个
			System.out.println(user); 
			//修改信息
			user.setName("Jerry");
			//将修改结果更新到数据库 
			session.update(user);
			tx.commit();//提交事务
		}catch(Exception e){
			e.printStackTrace();
			if(tx != null){
				tx.rollback();//回滚事务
			}
		}finally {
			if(session != null){
				session.close();//释放资源
			}
		}
	}
	
	@Test
	//删除一条数据
	public void testDeleteObject(){
		Session session = null;
		Transaction tx = null;
		try{
			session = factory.openSession();
			tx = session.beginTransaction();//开启事务
			//测试更新功能
			User user = (User)session.get(User.class, "99");//查询一个
			System.out.println(user); 
			//删除数据
			session.delete(user);
			tx.commit();//提交事务
		}catch(Exception e){
			e.printStackTrace();
			if(tx != null){
				tx.rollback();//回滚事务
			}
		}finally {
			if(session != null){
				session.close();//释放资源
			}
		}
	}
	
	@Test
	//Hibernate 4.3版本获取SessionFactory
	public void testSession2(){
		//读取配置文件
		Configuration cfg = new Configuration();
		cfg.configure("hibernate.cfg.xml");
		//buildSessionFactory()方法可能过时
		ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();
		SessionFactory factory = cfg.buildSessionFactory(serviceRegistry);
		Session session = factory.openSession();
		System.out.println(session);
		session.close();
	}

}

映射文件User.hnm.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>
	<!-- 将类映射到表: User类的对象存储到cn_user表中 -->
	<class name="cn.tedu.entity.User" table="cn_user">
		  <!-- id用于映射主键的对应关系 类中的id属性映射到表的cn_user_id列 -->
	      <id name="id" column="cn_user_id"></id>
	      
	      <!-- property 用于映射普通属性 -->
	      <property name="name" column="cn_user_name"></property>
	      <property name="password" column="cn_user_password"></property>
	      <property name="token" column="cn_user_token"></property>
	      <property name="nick" column="cn_user_nick"></property>
	</class>
</hibernate-mapping>

对于ID来说,由于此处的id为字符串,以上配置即可,但是ID还有其他的配置方式:

sequence: 根据序列生成ID,用于oracle
<generator class="sequence">
    <param name="sequence">序列名</param>
</generator>

identity: 自动生成ID,用于其他数据库
<generator class="identity"></generator>
native: sequence和identity二选一

<generator class="native">
    <param name="sequence">序列名</param>
</generator>

testSession方法输出如下:

SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=org.hibernate.engine.spi.ExecutableList@43bc63a3 updates=org.hibernate.engine.spi.ExecutableList@702657cc deletions=org.hibernate.engine.spi.ExecutableList@6a6cb05c orphanRemovals=org.hibernate.engine.spi.ExecutableList@40a4337a collectionCreations=org.hibernate.engine.spi.ExecutableList@6025e1b6 collectionRemovals=org.hibernate.engine.spi.ExecutableList@22ff4249 collectionUpdates=org.hibernate.engine.spi.ExecutableList@2d1ef81a collectionQueuedOps=org.hibernate.engine.spi.ExecutableList@4c402120 unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])

testSaveObject方法输出如下:

Hibernate: 
    insert 
    into
        cn_user
        (cn_user_name, cn_user_password, cn_user_token, cn_user_nick, cn_user_id) 
    values
        (?, ?, ?, ?, ?)

由于在配置文件中配置了sql的打印输出,所以在控制台能够看见,其次在数据库中插入了一条数据

持久状态(内存中有对象,自动关联,数据保存在session的一级缓存中,更改属性将自动更新到数据库中):

注意:

@Test
	//插入一条数据
	public void testSaveObject2(){
		User user = new User("88", "Tom", "123", "OK", "Cat");
		Session session = factory.openSession();
		Transaction tx = session.beginTransaction();
		session.save(user);//user对象转换为持久状态
		user.setNick("Andy");//修改持久对象的属性将影响数据库
		tx.commit();
		session.close();
	}

此时插入的数据变为了Andy,这是Hibernate的特殊性,控制台输出可以看出这是执行了两条SQL:

Hibernate: 
    insert 
    into
        cn_user
        (cn_user_name, cn_user_password, cn_user_token, cn_user_nick, cn_user_id) 
    values
        (?, ?, ?, ?, ?)
Hibernate: 
    update
        cn_user 
    set
        cn_user_name=?,
        cn_user_password=?,
        cn_user_token=?,
        cn_user_nick=? 
    where
        cn_user_id=?

注意:

	@Test
	public void testUpdate(){
		Session session = factory.openSession();
		Transaction tx = session.beginTransaction();
		//get方法返回的对象是持久状态对象
		User user = (User) session.get(User.class, "88");
		//修改"持久状态"对象属性 将影响数据库
		user.setNick("老王");
		
		tx.commit();
		session.close();
	}

此处也是执行了两次SQL,属性修改为‘老王’

游离状态(内存中有对象,不关联,更改属性,数据库数据不会更新):

	@Test
	//游离状态
	public void testEvict(){
		Session session = factory.openSession();
		Transaction tx = session.beginTransaction();
		//get方法返回的对象是持久状态对象
		User user = (User) session.get(User.class, "88");
		System.out.println(user);
		session.evict(user);//将对象user踢出session缓存,使之成为游离状态
		//修改"游离状态"对象属性不会影响数据库
		user.setNick("老宋");
		tx.commit();
		session.close();
	}

数据库中的数据不会更新,只执行了一条查询SQL, session.clear()在此处也可以,表示将所有的对象踢出session缓存,和session.evict相比,范围更广,但是session.evict方法更精细

在上述案例中,user.setNick("老宋");代码后面若再Update,则会变为持久状态,将‘老宋’写入数据库

注意:持久状态下,多次修改数据,只生成一个Update语句,一条SQL语句,这是Hibernate框架的性能优越

这就是Hibernate的三种状态:总结如下

  • Hibernate对象有3种状态: 临时态、持久态、游离态
  • Hibernate通过状态来管理对象,不同状态的对象有不同的处理机制

每种状态的特征

临时态

  • 临时态对象未经过持久化,未与session关联
  • 临时态对象可以被垃圾回收

持久态

  • 持久态对象进行了持久化,已与session关联
  • 持久态对象存在与session(一级)缓存中
  • 持久态对象能自动更新到数据库,更新是在调用session.flush()时

commit()的底层调用了session.flush()

游离态

  • 游离态对象进行过持久化,但已与session解除了关联
  • 游离态对象可以被垃圾回收

二级缓存

  • 也叫SessionFactory级缓存
  • 只能缓存对象数据
  • 是在SessionFactory中缓存数据,该数据可以由所有session共用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荒--

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值