Hibernate (七) session常用方法、懒加载、一级缓存

这里写图片描述

对象的四种状态
临时状态
新创建出的对象。

持久化状态
数据库中查询出的对象

游离状态
数据库中查询出来,并修改后为保存的对象

删除状态
数据库delete后的对象。

hibernate的session对象自身是存在缓存的,当你重复get同一个对象只会执行一次。

Session 一级缓存:

在一次事务中重复相同查询,只会执行一次sql,该方式的范围在一次事务中。

    @Test
    public void testSave() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // --------------------------------------------
        User user = new User(); // 临时状态
        user.setName("test");
        session.save(user); // 变为了持久化状态,并且保存在Session缓存中
        session.save(user); //Session会对该对象进行比对,如果是相同就不再只会执行保存。
        //session.clear();//将Session清空,Session中没有User对象,所以无法在进行setName操作
        //session.evict(user); //指定清除Session中的user对象,后续不再执行user的setName操作。
        user.setName("李四"); //Session发现user那么修改了 数据 就会执行Update操作和数据库同步数据。
        // --------------------------------------------
        session.getTransaction().commit();
        session.close();

        user.setName("我无效");//Session 关闭后修改的不会更新到数据库

        session = sessionFactory.openSession();
        session.beginTransaction();
        user = (User) session.get(User.class, user.getId()); // 持久化
        System.out.println(user);
        session.getTransaction().commit();
        session.close();
    }

Session 内存溢出问题:

public class User {
    private Integer id;
    private String name;
    private byte[] data = new byte[1024 * 1024 * 5];//这里创建了一个大字节数据。

Session 的缓存数据如果超过了 java虚拟机就会导致内存溢出。
所以在单次事务操作大数据时,每隔一段时间对Session内存进行一次清理。

    @Test
    public void testBatchSave() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // --------------------------------------------

        for (int i = 0; i < 30; i++) {
            User user = new User();
            user.setName("测试");
            session.save(user);
            //缓存清理
            if (i % 10 == 0) {
                session.flush(); // 将缓存数据刷入数据库。
                session.clear(); // 清空Session缓存
            }
        }

        // --------------------------------------------
        session.getTransaction().commit();
        session.close();
    }

Load 懒加载

    @Test
    public void testLoad() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // --------------------------------------------
        //load()后返回的是一个代理对象,要求类不能是final的,否则不能生成子类代理,就不能使用懒加载功能了。
        User user = (User) session.load(User.class, 5);
        System.out.println(user.getClass());
        System.out.println("---");
        System.out.println(user.getId());//对象有id,就不会执行Sql查询
        System.out.println(user.getName());//发现对象没有name数据,这时才会去查询数据库
        // --------------------------------------------
        session.getTransaction().commit();
        session.close();
    }

懒加载:
1、懒加载配置方式有两种:
①、在类级别上配置 :

<class ... lazy="true/false">

②、在属性级别上配置:

<set/list/map/bag/ ...  lazy="true/false/extra">

2、懒加载 load()方法返回的是带有sql语句的代理对象而不是 带数据的实体对象,所以在调用里面方法时,才会去查询数据。
3、LazyInitalizationException 异常处理:
懒加载后对象获取数据的方法也必须在session关闭事务之前使用,如果想懒加载初始化所有数据,可以调用initializ()方法。否者就会包该异常。
4、true/false/extra
true:代表开启
false:代表关闭懒加载
extra:表示聪明的加载
比如下面的例子

public class User {
    private Integer id;
    private String name;
    //用户购物列表
    private Set<Goods> shopping;
    User user = (User) session.get(User.class, 5); 
    //如果使用lazy=true 的话 就会查询所有的结果,然后回去结果的数量:
    //如果使用lazy=extra: select count(id) from goods... 如果数据庞大的情况下,我只想获取总数,这样效率就会高很多
    int num = user.getShopping().size();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值