导包:
配置文件如下:
<?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共用