Hibernate第二天

Hibernate 的主键生成策略

实际开发中不允许用户手动设计主键,一般将主键交给数据库,手动编写程序进行设置

  1. increment:hibernate中提供的自动增长机制,适用于short,int,long类型的主键,在单线程程序中使用
  2. identity:适用于short,int,long类型的主键,使用的是数据库底层的自动增长机制,适用于有自动增长机制的数据库(MySql)
  3. sequence:适用于short,int,long类型的主键,采用的是sequence的方式,像MYsql不能使用sequence
  4. uuid:适用于字符串类型的主键,使用hibernate中的随机方式生成字符串主键
  5. native:本地策略,可以在identity和sequence之间自动切换
  6. assigned:hibernate放弃外键的管理,需要通过手动编写程序或者用户自己设置
  7. foreign:外部的,一对一的关联映射的情况下使用

持久化类的三种状态

hibernate是持久化框架,通过持久化类完成ORM(object relational mapping)操作,hibernate为了更好的管理持久化类,将持久化类分成三种状态。

瞬时态

这种对象没有唯一的标识oid,没有被session所管理,称为瞬时态对象

瞬时态对象
获取 Customer customer = new Customer();
状态转换
瞬时->持久
save(),saveOrUpdate();
瞬时->脱管
Customer.setCust_id(1)

持久态(presisted)

这种对象有唯一的标识oid,被session所管理,称为持久态对象

  1. 持久化类的持久态的对象,可以自动更新数据库

持久态对象获取
get,load,find,iterate
session.get(Customer.class,1)
状态转换
持久->瞬时
delete
持久->脱管
session.close,clear, evict

脱管态(detached)

有唯一标识oid,没有被session管理,称为脱管态对象

获得Customer customer = new Customer > customer.setCust_id(1)
状态转换
脱管->持久
update(),saveOrUpdate()
脱管->瞬时
customer.setCust_id(null)

@Test
    public void demo1() {
        Session session = HibernateUtils.openSession();
        Transaction transaction = session.beginTransaction();
        Customer customer = new Customer();//瞬时态对象:没有唯一标识oid,没有session管理
        customer.setCust_name("王东");

        Serializable id = session.save(customer);//持久态对象,有唯一标识oid,被session管理

        Customer c1 = session.get(Customer.class, id);

        transaction.commit();
        session.close();
        System.out.println("客户名称:" + customer.getCust_name());//脱管态,有唯一标识oid,没有session管理
    }

Hibernate的缓存

缓存:是一种优化的方式,将数据存入内存,使用的时候直接从缓存中获取,不用通过存储源
Hibernate的一级缓存:称为是Session级别的缓存,一级缓存生命周期与session一致(一级缓存是由Session中的一系列的java集合构成),一级缓存是自带的不可卸载的。(Hibernate的二级缓存是SessionFactory级别的缓存,需要配置缓存)

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

        Customer customer = session.get(Customer.class, 1l);
        System.out.println(customer);
        Customer customer1 = session.get(Customer.class, 1l);
        System.out.println(customer1);
        System.out.println(customer == customer1);

        transaction.commit();
        session.close();
    }

Hibernate的一级缓存的结构

快照区:session的一级缓存区中存在这样一个快照区,它复制了一份当前session中的缓存,当这份缓存因为调用其他方法而被改变时,当tx.commit方法执行的时候,程序会比较缓存区和快照区的数据:数据一致的时候,不更新数据库;数据不一致的时候,更新数据库。

hibernate的事务管理

事务:事务指的是逻辑上的一组操作,组成这组操作的各个逻辑单元要么都成功,要么都失败
事务的特性:

  • 原子性:代表事务不可分割
  • 一致性:代表事务执行前后,数据的完整性保持一致
  • 隔离性:事务执行的过程中,不应该受其他事务的干扰
  • 持久性:事务执行完成后,数据就持久到数据库中

不考虑隔离性:

  • 读问题:
  • 脏读:一个事务读到了另一个事务未提交的数据
  • 不可重复读:一个事务读到另一个事务已经提交的update数据,导致在前一个事务多次查询结果不一致
  • 虚读:一个事务读到另一个事务已经提交的insert数据,导致在前一个事务多次查询结果不一致
  • 写问题:
    引发两类丢失更新

事务的隔离级别:
设置事务的隔离级别

  • read uncommited:以上读问题都会发生
  • read commited:解决脏读,但是不可重复读和虚读有可能发生
  • repeatable read:解决脏读和不可重复读,但是虚读有可能发生
  • serializable:解决所有读问题

Service中封装业务逻辑操作

必须保证连接对象是同一个:

  • 向下传递 DBUtils
  • 使用ThreadLocal对象

Hibernate框架内部已经绑定好了ThreadLocal
在sessionFactory中提供了一个方法getCurrentSession()
通过一个配置完成

<!--配置当前线程绑定的session-->
       <property name="hibernate.current_session_context_class">thread</property>

当前线程销毁,session销毁;因此不需要session.close

Hibernate的其他API

Query

public void demo1() {
        Session currentSession = HibernateUtils.getCurrentSession();
        Transaction transaction = currentSession.beginTransaction();

        //通过session获得Query接口
        //简单查询
        String sql = "from Customer";
        //条件查询
        String sql1 = "from Customer where cust_name like ?";
        Query query1 = currentSession.createQuery(sql1);
        //设置条件
        query1.setParameter(0, "王%");
        //设置分页
        query1.setFirstResult(0);
        query1.setMaxResults(3);
        Query query = currentSession.createQuery(sql);
        List<Customer> list = query.list();
        for (Customer customer : list) {
            System.out.println(customer);
        }

        List<Customer> list1 = query1.list();
        for (Customer customer : list1) {
            System.out.println(customer);
        }
        transaction.commit();
    }

Criteria

SQLQuery

用于接收sql语句

Hibernate多对多的配置文件

<?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>
    <class name="com.itheima.hibernate.demo1.User" table="sys_user">
        <!--建立OID与主键的映射-->
        <id name="user_id">
            <generator class="native"></generator>
        </id>
        <!--建立普通属性与字段的映射-->
        <property name="user_code" column="user_code"/>
        <property name="user_name" column="user_name"/>
        <property name="user_password" column="user_password"/>
        <property name="user_state" column="user_state"/>
        <!--关联关系的映射配置-->

        <!--
        set标签
        name:对方的集合的属性名称
        table: 多对多需要使用中间表,table为中间表的名称
        -->
        <set name="roles" table="sys_user_role" cascade="save-update">
            <!--
            key标签:
                column:当前对象对应中间表的外键的名称
            -->
            <key column="user_id"></key>
            <!--
            class:对方的类的全路径
            column:对方的对象在中间表中外键的名称
            -->
            <many-to-many column="role_id" class="com.itheima.hibernate.demo1.Role"/>
        </set>
    </class>
</hibernate-mapping>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值