1、Hibernate中的实体规则和对象状态
主键生成策略配置以及对象状态代码示例
Customer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping package="cn.ctgu.domain">
<class name="Customer" table="customer">
<id name="id" column="id">
<!-- generator:主键生成策略
就是每条记录录入时,主键的生成规则(7个)
identity:主键自增,有数据库来维护主键值,录入时不需要指定主键
increment(不用,存在线程安全问题,当多个线程同时插入数据事可能会产生覆盖):主键自增,由hibernate来维护,每次插入时会先查询表中id最大值,+1作为新主键值
sequence:Oracle中的主键生成策略
hilo(不用,同样存在线程安全问题):高低位算法,主键自增,由hibernate来维护,开发时不使用
native:hilo+sequence+identity 自动三选一策略
uuid:产生随机字符串作为主键,主键类型必须为String类型,否则会报错
assigned:自然主键生成策略,hibernate不会管理主键值,由开发人员自己录入
-->
<generator class="native"></generator>
</id>
<property name="name" column="NAME" ></property>
<property name="source" column="source"></property>
<property name="industry" column="industry"></property>
<property name="level" column="LEVEL"></property>
<property name="phone" column="phone"></property>
<property name="mobile" column="mobile"></property>
</class>
</hibernate-mapping>
package cn.ctgu.state;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import cn.ctgu.domain.Customer;
import cn.ctgu.utils.HibernateUtils;
//测试对象的三种状态
public class Demo {
@Test
//三种状态特点
//save方法:其实不能理解成保存,理解成将瞬时状态转换成持久状态的方法
//主键自增:执行save方法是为了将对象转换成持久化状态,必须生成id值,所以需要执行insert语句生成
//increment:执行save方法,为了生成id,会执行查询id最大值的sql语句
public void fun1() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
Customer c=new Customer();//没有id,没有与session关联=》瞬时状态
c.setName("联想");//瞬时状态
session.save(c);//持久化状态,有id,有关联
//4、提交事务,关闭资源
tx.commit();
session.close();//游离|托管状态,有id,没有关联
}
@Test
//持久化状态特点: 持久化状态对象的任何变化都会自动同步到数据库中
public void fun2() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
Customer c=session.get(Customer.class, 1l);//持久化状态对象
c.setName("微软");
session.save(c);//持久化状态,有id,有关联
//4、提交事务,关闭资源
tx.commit();
session.close();//游离|托管状态,有id,没有关联
}
}
2、Hibernate一级缓存快照及事务
相应配置及代码示例
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>
<!-- 必选配置 5个-->
<!-- 数据库驱动 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 数据库url -->
<property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
<!-- 数据库用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 数据库连接密码 -->
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<!--将hibernate生成的sql语句格式化(语法缩进) -->
<property name="hibernate.format_sql">true</property>
<!--
## auto schema export 自动到处表结构,自动建表,意思就是即使数据库中没有建立与实体相对应的表,它也不会插入数据
失败,因为它会自动创建一个表到数据库中,然后在插入数据
#hibernate.hbm2ddl.auto create-drop 自动建表,每次框架运行都会将所有表删除(开发环境中使用)
#hibernate.hbm2ddl.auto create 自动建表,每次框架运行都会创建新的表,以前的表将会被覆盖,表数据会丢失(开发环境中测试使用)
#hibernate.hbm2ddl.auto update (推荐使用)自动生成表,如果已经存在就不会生成,如果表有变动,自动更新表(不会删除任何数据)
#hibernate.hbm2ddl.auto validate 校验,不自动生成表,每次启动会校验数据库中表是否正确,也就是校验是否与实体匹配,校验失败则抛出异常
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!--指定hibernate操作数据库时的隔离级别
## specify a JDBC isolation level
#hibernate.connection.isolation 1|2|4|8
0001 1 读未提交
0010 2 读已提交
0100 4 可重复读
1000 8 串行化
-->
<property name="hibernate.connection.isolation">4</property>
<!-- 指定session与当前线程绑定 -->
<property name="hibernate.current_session_context_class">thread</property>
<mapping resource="cn/ctgu/domain/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
缓存以及快照测试代码
package cn.ctgu.cache;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import cn.ctgu.domain.Customer;
import cn.ctgu.utils.HibernateUtils;
//测试一级缓存
public class Demo {
@Test
//证明一级缓存的存在
public void fun1() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
Customer c1=session.get(Customer.class, 1l);
Customer c2=session.get(Customer.class, 1l);
Customer c3=session.get(Customer.class, 1l);
Customer c4=session.get(Customer.class, 1l);
Customer c5=session.get(Customer.class, 1l);
System.out.println(c3=c5);//true,只会执行一次,其它的直接在缓存中取
//4、提交事务,关闭资源
tx.commit();
session.close();
}
@Test
//快照
public void fun2() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
Customer c1=session.get(Customer.class, 1l);
c1.setName("haha");
c1.setName("谷歌");//直接取快照中的数据,而不再操作数据库,由于跟数据库中的数据c1一样
//4、提交事务,关闭资源
tx.commit();
session.close();
}
@Test
//持久化状态对象其实就是放入session缓存中的对象
public void fun3() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
Customer c1=new Customer();
c1.setId(1l);//托管|游离状态
session.update(c1);//c1被放入session缓存了,由游离状态变为持久化状态
Customer c2=session.get(Customer.class, 1l);
//4、提交事务,关闭资源
tx.commit();
session.close();
}
}
测试getCurrentSession
package cn.ctgu.tx;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import cn.ctgu.domain.Customer;
import cn.ctgu.utils.HibernateUtils;
//测试getCurrentSession
public class Demo {
@Test
//证明获取到的是同一个线程,前提必须得再主配置文件中配置
public void fun1() {
//1、获得session
Session session1=HibernateUtils.getCurrentSession();
Session session2=HibernateUtils.getCurrentSession();
System.out.println(session1==session2);//true,表示session1和session2是同一个session
}
}
3、Hibernate中的批量查询
3.1 HQL查询
代码示例
package cn.ctgu.hql;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import cn.ctgu.domain.Customer;
import cn.ctgu.utils.HibernateUtils;
public class Demo {
@Test
//基本查询
public void fun1() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
//1、书写HQL语句
// String hql="select * from cn.ctgu.domain.Customer";
// String hql="from cn.ctgu.domain.Customer";
String hql="from Customer";//以上三种都是查询所有Customer对象,注意后面接的实体的完整类名(只有不重复Customer类时才可以这样用)
//2、根据HQL语句创建查询对象
Query query=session.createQuery(hql);
//3、根据查询对象获得查询结果
List<Customer>list=query.list();//返回list结果
//query.uniqueResult();//接收唯一的查询结果
System.out.println(list);
//4、提交事务,关闭资源
tx.commit();
session.close();
}
@Test
//条件查询
//HQ语句中不可能出现任何数据库相关的信息的
public void fun2() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
//1、书写HQL语句
String hql="from Customer where id=1";//以上三种都是查询所有Customer对象
//2、根据HQL语句创建查询对象
Query query=session.createQuery(hql);
//3、根据查询对象获得查询结果
Customer c=(Customer) query.uniqueResult();//接收唯一的查询结果
System.out.println(c);
//4、提交事务,关闭资源
tx.commit();
session.close();
}
@Test
//条件查询
//问号占位符
public void fun3() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
//1、书写HQL语句
String hql="from Customer where id=?";//以上三种都是查询所有Customer对象
//2、根据HQL语句创建查询对象
Query query=session.createQuery(hql);
//设置参数
//query.setLong(0, 1l);//参数设置方式一:设置第一个参数为1l,注意:是从0开始的
query.setParameter(0, 1l);//参数设置方式二,不需要管它参数是什么类型
//3、根据查询对象获得查询结果
Customer c=(Customer) query.uniqueResult();//接收唯一的查询结果
System.out.println(c);
//4、提交事务,关闭资源
tx.commit();
session.close();
}
@Test
//条件查询
//命名占位符
public void fun4() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
//1、书写HQL语句
String hql="from Customer where id=:cus_id";//以上三种都是查询所有Customer对象
//2、根据HQL语句创建查询对象
Query query=session.createQuery(hql);
//设置参数
query.setParameter("cus_id", 1l);//参数设置方式二,不需要管它参数是什么类型
//3、根据查询对象获得查询结果
Customer c=(Customer) query.uniqueResult();//接收唯一的查询结果
System.out.println(c);
//4、提交事务,关闭资源
tx.commit();
session.close();
}
@Test
//分页查询
public void fun5() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
//1、书写HQL语句
String hql="from Customer limit ?,?";//以上三种都是查询所有Customer对象
//2、根据HQL语句创建查询对象
Query query=session.createQuery(hql);
//设置分页信息 相当于limit ?,?
query.setFirstResult(0);
query.setMaxResults(1);
//3、根据查询对象获得查询结果
List<Customer>list=query.list();//接收唯一的查询结果
System.out.println(list);
//4、提交事务,关闭资源
tx.commit();
session.close();
}
}
3.2 Criteria查询
代码示例
package cn.ctgu.criteria;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;
import cn.ctgu.domain.Customer;
import cn.ctgu.utils.HibernateUtils;
//测试criteria查询
public class Demo {
@Test
public void fun1() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
//查询所有的Customer对象
Criteria criteria=session.createCriteria(Customer.class);
List<Customer>list=criteria.list();
System.out.println(list);
//4、提交事务,关闭资源
tx.commit();
session.close();
}
@Test
//条件查询
public void fun2() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
//查询所有的Customer对象
Criteria criteria=session.createCriteria(Customer.class);
//添加criteria查询对象=>查询id为1的Customer对象
/*
* > gt
* >= ge
* <= lt
* == eq
* != ne
* in in
* between and between
* like like
* is not null isNotNull
* is null isNull
* or or
* and and
* */
criteria.add(Restrictions.eq("id", 1l));
//执行查询获得结果
Customer c=(Customer)criteria.uniqueResult();
System.out.println(c);
//4、提交事务,关闭资源
tx.commit();
session.close();
}
@Test
//分页查询
public void fun3() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
//查询所有的Customer对象
Criteria criteria=session.createCriteria(Customer.class);
//设置分页查询limit ?,?
criteria.setFirstResult(0);
criteria.setMaxResults(1);
//执行查询获得结果
List<Customer>list=criteria.list();
System.out.println(list);
//4、提交事务,关闭资源
tx.commit();
session.close();
}
@Test
//查询总记录数
public void fun4() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
//查询所有的Customer对象
Criteria criteria=session.createCriteria(Customer.class);
//设置查询的聚合函数=>总行数
criteria.setProjection(Projections.rowCount());
//执行查询获得结果
Long count=(Long) criteria.uniqueResult();
System.out.println(count);
//4、提交事务,关闭资源
tx.commit();
session.close();
}
}
3.3 原生SQL查询
代码示例
package cn.ctgu.sql;
import java.util.Arrays;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import cn.ctgu.domain.Customer;
import cn.ctgu.utils.HibernateUtils;
//测试原生sql查询
public class Demo {
@Test
//基本查询
public void fun1() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
//1、书写sql语句
String sql="select * from Customer";
//2、创建sql查询对象
SQLQuery query=session.createSQLQuery(sql);
//指定将结果集封装到哪个对象中
query.addEntity(Customer.class);
//3、调用方法查询结果
List<Customer>list=query.list();
//query.uniqueResult();
System.out.println(list);
//4、提交事务,关闭资源
tx.commit();
session.close();
}
@Test
//条件查询
public void fun2() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
//1、书写sql语句
String sql="select * from Customer where id=?";
//2、创建sql查询对象
SQLQuery query=session.createSQLQuery(sql);
query.setParameter(0, 1l);
//将指定结果封装到哪个对象中
query.addEntity(Customer.class);
//3、调用方法查询结果
List<Customer>list=query.list();
//query.uniqueResult();
System.out.println(list);
//4、提交事务,关闭资源
tx.commit();
session.close();
}
@Test
//分页查询
public void fun3() {
//1、获得session
Session session=HibernateUtils.openSession();
//2、控制事务
Transaction tx=session.beginTransaction();
//3、执行操作
//1、书写sql语句
String sql="select * from Customer limit ?,?";
//2、创建sql查询对象
SQLQuery query=session.createSQLQuery(sql);
query.setParameter(0, 0);
query.setParameter(1, 1);
//将指定结果封装到哪个对象中
query.addEntity(Customer.class);
//3、调用方法查询结果
List<Customer>list=query.list();
//query.uniqueResult();
System.out.println(list);
//4、提交事务,关闭资源
tx.commit();
session.close();
}
}