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

来源:互联网 发布:如何出售域名 编辑:程序博客网 时间:2024/04/28 19:23

这里写图片描述

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

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

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

删除状态
数据库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
原创粉丝点击