2

一、hibernate中实体规则

实体类创建的注意事项

1.持久化类提供无参数构造
2.成员变量私有,提供get、set方法访问,需提供属性(属性就是get、set方法)
3.持久化类中的属性,应尽量使用包装类型(可以表示null,在插如数据库中有作用)
4.持久化类需要提供oid(主键属性)与数据库中主键列对应
5.不需要final修饰class(原因:hibernate使用cglib代理生成代理对象,如果被final修饰将无法生成代理)

主键类型

1.自然主键(少见)

表的业务列中,有某业务列符合,必须有且不重复的特征时,该列可以作为主键使用

2.代理主键(常见)

表的业务列中,没有某业务列符合,必须有且不重复的特征时,创建一个没有业务意义的列做为主键

主键生成策略

1.代理主键

indentity:主键自增,有数据库来维护主键值,录入时不需要指定主键
sequence:Oracle中的主键生成策略
increment(了解):主键自增,由hibernate来维护,每次插入前会先查询表中的id的最大值,+1作为新主键插入
hilo(了解):高低位算法,主键自增,有hibernate来维护,开发时不使用
native:hilo + sequence + indeyity 自动三选一策略
uuid:产生随机字符串作为主键,主键类型必须为String类型

2.自然主键

assigned:自然主键生成策略,hibernate不会管理主键值,由开发人员自己录入

二、hibernate中的对象状态

对象分为三种状态

1.瞬时状态

没有id,没有与session关联

2.持久化状态

有id,与session有关联

3.游离|托管状态

有id,没有与session关联

代码

@Test
public void save() {
    Session session = HibernateUtils.openSession();
    
    Transaction tx = session.beginTransaction();

    Customer c = new Customer(); // 没有id,没有与session对象关联 => 瞬时状态

    session.save(c); // 持久化状态,有id,与session对象关联

    tx.commit();

    session.close(); // 游离|托管状态,有id,没有关联
}

三种状态的转换图
clipboard.png

三、hibernate一级缓存

缓存:提高效率,hibernate中的一级缓存也是为了提高操作数据库的效率

四、hibernate中的事务

事务特性

a原子性
c一致性
i隔离性(事务并发的时候隔离级别)
d持久性

事务并发问题

1、脏读
2、不可重复读
3、幻、虚读

事务的隔离级别

读未提交:出现的问题1、2、3
读已提交:出现的问题2、3
可重复读:出现的问题3(mysql默认级别)
串行化:没有问题,会极大的降低效率

如何在hibernate中指定隔离级别

在hibernate主配置中
<!--specify a JDBC isolation level-->
hibernate.connection.isolation 1|2|4|8
数据库中存储级别是一个字节
0001 1  读未提交
0010 2  读已提交
0100 4  可重复读
1000 8  串行化

项目中如何管理事务

业务开始之前打开事务,业务执行之后提交事务,执行过程中出现异常,回滚事务
在dao层操作数据库需要用到session对象,在service控制事务也是使用session对象完成,我们要确保dao层和service层使用的是同一个session对象
在hibernate中确保使用同一个session的问题,hibernate已经帮我们解决了,我们开发人员只需要调用sf.getCurrentSession()方法获得与当前线程绑定的session对象
注意:调用getCurrentSession()方法必须配合主配置中的一项配置,如下
    指定session与当前线程绑定
    hibernate.current_session_context_class  thread
    通过getCurrentSession()方法获得session对象,当事务提交时session会自动关闭,不需要手动close关闭

五、hibernate中的批量查询

HQ查询-hibernate Query Language(支持多表查询,但一般是不复杂时使用)

// 1、书写HQL语句
String hql = "form Customer"; // 查询所有的Customer对象
// 2、根据HQL语句创建查询对象
Query query = session.createQuery(hql);
// 3、根据对象获得查询结果
List<Customer> list = query.list(); // 返回list结果
// query.uniqueResult();//返回唯一的查询结果
// ?占位符
String hql = "form Customer  where cus_id = ?"; // 查询所有的Customer对象
//设置参数
session.setParamter(0, 1)// hibernate ?占位符索引从0开始,jdbc从1开始
// :占位符
String hql = "form Customer  where cus_id = :cus_id";
session.setParamter("cus_id", 1)// hibernate :占位符直接输入占位名字
// 分页查询
query.setFirstResult(0);// 第一条数据开始的位置,0是索引
query.setMaxResult(20);// 设置查询结果最大条数,想当与pagesize

Criteria查询-hibernate自创的无语句查询(单表查询)

Criteria criteria = session.createCriteria(Customer.calss); //查询所有的Customer对象
List<Customer> list = criteria.list();// 返回list结果
// criteria.uniqueResult();// 返回唯一查询结果
// 条件查询
// >              gt
// >=             ge
// <              lt
// <=             le
// ==             eq
// !=             ne
// in             in
// between and    between
// like           like
// is not null    isNotNull
// is null        isNull
// or             or
// and            and
criteria.add(Restrictions.eq("cus_id", 1))// 查询cus_id为1的对象
// 聚合函数
criteria.setProjection(Projections.rowCount);// count函数
// 分页查询
criteria.setFirstResult(0);// 第一条数据开始的位置,0是索引
criteria.setMaxResult(20);// 设置查询结果最大条数,想当与pagesize

原生SQL查询(复杂业务查询)

// 书写sql语句
String sql = "select * from customer";
// 创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);
// 指定结果集封装到指定对象中
query.addEntity(Customer.class);
// 调用方法查询结果
List<Customer> list = query.list();

zer0_li
1.4k 声望307 粉丝

经不住似水流年,逃不过此间少年