HIBERNATE

本文介绍了Hibernate中实体类的设计规范、主键生成策略及多种查询方式,包括HQL和SQL查询等,帮助理解Hibernate持久层框架的核心概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实体类规范

  1. 为实体类提供有参和无参构造方法;
  2. 将成员变量私有化,提供get/set方法。
  3. 基本数据类型尽量使用包装类型(可以表示一个值null )
  4. 实体类中必须要有一个与表中主键对应的Id, hibernate是通过主键来区别对象是否相同。
  5. 不可以使用final修饰实体类。

主键的类型

  1. 自然主键,例如 身份证号,没人只有一个唯一的。
  2. 代理主键(常用),找不到符合业务字段的主键就自己设置一个没有任何意义的Id列来充当主键,叫做代理主键。

hibernate中主键的生成策略

  1. identity:主键自增,有数据库维护主键,录入时不需要制定主键,
 <generator class="identity"></generator>
@Test
    public void fun1() {
        //获取session
        Session session = HibernateUtil.getSession();
        //开启事务
        Transaction transaction = session.beginTransaction();
        //包裹语句
        //不需要设置主键,数据库会自动添加主键
        User user = new User();
        user.setUsername("wl");
        user.setPassword("123");
        session.save(user);
        //提价事务
        transaction.commit();
        //关闭session
        session.clear();

    }

2.increment 主键自增 由hibernate维护主键id 每次插入数据都会先查询最大的主键,然后加1 来设置主键

<generator class="increment"></generator>

3.sequence :Oracle 中的主键生成策略 序列。
4.hilo:高低位算法(数据库中的主键自增算法原理) 也是由hibernate维护
5.native:hilo+identity+sequence 三选一,系统会检测你的数据库,来确定使用哪个(常用)。
6.uuid:全球不重复的值并且这个值是一个字符串,但是这个主键必须是字符串类型
7.assigned:有程序员自己管理的主键;

三种状态

  1. 瞬时态:没有id 没有上session缓存
  2. 持久态:有id 有session缓存
  3. 游离态:有id 没有session缓存
@Test
    public void fun2() {
        //获取session
        Session session = HibernateUtil.getSession();
        //开启事务
        Transaction transaction = session.beginTransaction();
        //包裹语句
        // 瞬时态 没有id 没有和session关联
        User user = new User();
        user.setUsername("wl");
        user.setPassword("123");
        //持久态 有id 有和session关联
        session.save(user);
        //提价事务
        transaction.commit();
        //关闭session
        //游离态有id没有关联
        session.clear();

    }

结论:将我们想要同步到数据库的数据 所对应的对象转化成持久态。

一级缓存和快照

一级缓存

使用hibernate进行查询的时候,将查询结果放置到session的一级缓存中,在一级缓存中存在对象,对象使用属性的OID的值进行区分,此时再使用相同的OID进行查询的时候,首先会在session一级缓存中进行查找是否存在相同的OID。
1. 如果存在相同的OID,此时不再查询数据库,而是直接使用一级缓存中存在的对象
2. 如果没有存在相同的OID,此时再查询数据库,将查询得到的结果数据再放置到session一级缓存中
3. 目的:减少访问数据库的次数,提高效率。

快照

使用id进行查询数据库,将查询得到的结果放置到session一级缓存中,同时复制一份数据,放置到session的快照中
当使用tr.commit()的时候,同时清理session的一级缓存(flush)
当清理session一级缓存的时候,会使用OID判断一级缓存中对象和快照中的对象进行比对。
1. 如果2个对象(一级缓存的对象和快照的对象)中的属性发生变化,则执行update语句,此时更新数据库,更新成一级缓存中的数据。
2. 如果2个对象中的属性不发生变化,此时不执行update语句
3. 目的:确保和数据库中的数据一致。

事务的隔离级别

通过hibernate设置事务的隔离级别
1.脏读
2.可重复读
3.幻读
READ UNCOMMITTED 读未提交 123 0001
READ COMMITTED 读已提交 23 0010
REPEATABLE READ 可重复读 3 0100
SERIALIZABLE 串行化(只能一个一个访问)1000
设置事物的隔离级别(etc)
specify a JDBC isolation level
hibernate.connection.isolation 1|2|4|8
隔离级别使用一个字节存储的

<property name="hibernate.connection.isolation">4</property>

三种查询

  1. HQL查询
    单数据查询:uniqueResult接收结果
@Test
    public void fun1() {
        String hql = "From User Where id = 2";
        Session session = HibernateUtil.getSession();
        Transaction beginTransaction = session.beginTransaction();
        Query query = session.createQuery(hql);
        // 预见结果(单数据使用uniqueResult)
        User user = (User) query.uniqueResult();
        System.out.println(user);
        beginTransaction.commit();
        session.close();
    }

多数据: list集合接收

@Test
    public void fun2() {
        String hql = "From User";
        Session session = HibernateUtil.getSession();
        Transaction beginTransaction = session.beginTransaction();
        Query query = session.createQuery(hql);
        // 预见结果(单数据)
        // User user = (User)query.uniqueResult();
        // System.out.println(user);
        List<User> list = query.list();
        System.out.println(list);
        beginTransaction.commit();
        session.close();
    }

HQL 查询 问号占位符

@Test
    public void fun3() {
        Session session = HibernateUtil.getSession();
        Transaction beginTransaction = session.beginTransaction();
        String hql = "from User where id= ? username=?";
        Query query = session.createQuery(hql);
        // 相当于给语句中的?赋值从0开始
        query.setParameter(0, 2);
        // query.setParameter(1, "w");
        // List<User> list = query.list();
        User user = (User) query.uniqueResult();
        System.out.println(user);
        beginTransaction.commit();
        session.close();
    }

HQL查询 冒号占位符

@Test
    public void fun4() {
        Session session = HibernateUtil.getSession();
        Transaction beginTransaction = session.beginTransaction();
        String hql = "from User where id=:ww";
        // 冒号后面相当于给冒号占位符替别名
        // 冒号后面不要加空格
        Query query = session.createQuery(hql);
        // 直接使用别名赋值
        query.setParameter("ww", 1);
        System.out.println(query.uniqueResult());
        beginTransaction.commit();
        session.close();
    }

分页查询

@Test
    public void fun5() {
        Session session = HibernateUtil.getSession();
        Transaction beginTransaction = session.beginTransaction();
        String hql = "from User ";
        Query query = session.createQuery(hql);
        // 设置起始和最大显示
        query.setFirstResult(3);
        query.setMaxResults(2);
        // 接受结果
        List list = query.list();
        System.out.println(list);
        beginTransaction.commit();
        session.close();
    }

2.无语句查询

/*
     * 无语句查询
     */
    @Test
    public void fun6() {
        Session session = HibernateUtil.getSession();
        Transaction beginTransaction = session.beginTransaction();
        Criteria criteria = session.createCriteria(User.class);
        List list = criteria.list();
        System.out.println(list);
        beginTransaction.commit();
        session.close();
    }

无语句条件查询

@Test
    public void fun7() {
        Session session = HibernateUtil.getSession();
        Transaction beginTransaction = session.beginTransaction();
        Criteria criteria = session.createCriteria(User.class);
        // 添加一个查询条件
        criteria.add(Restrictions.gt("id", 6));
        User user = (User) criteria.uniqueResult();
        System.out.println(user);
        beginTransaction.commit();
        session.close();
    }

无语句按条件查询 查询总行数

@Test
    public void fun8() {
        Session session = HibernateUtil.getSession();
        Transaction beginTransaction = session.beginTransaction();
        Criteria criteria = session.createCriteria(User.class);
        criteria.setProjection(Projections.rowCount());
        // 返回值是数的通常使用Long接受
        Long l = (Long) criteria.uniqueResult();
        System.out.println(l);
        beginTransaction.commit();
        session.close();
    }

3.SQL查询

@Test
    public void fun9() {

        Session session = HibernateUtil.getSession();
        Transaction beginTransaction = session.beginTransaction();
        String sql = "select * from user where id = ?";
        Query query = session.createSQLQuery(sql);
        query.setParameter(0, 2);
        //一条记录就是一个object[]
        Object[] objects = (Object[])query.uniqueResult();
        for (Object object : objects) {
            System.out.println(object);
        }
//      List<Object[]> list = query.list();
//      for (Object[] objects : list) {
//          System.out.println(Arrays.toString(objects));
//      }
        beginTransaction.commit();
        session.close();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值