zoukankan      html  css  js  c++  java
  • JPA数据懒加载LAZY配合事务@Transactional使用(三)

       上篇博文《JPA数据懒加载LAZY和实时加载EAGER(二)》讲到,如果使用懒加载来调用关联数据,必须要保证主查询session(数据库连接会话)的生命周期没有结束,否则,你是无法抽取到数据的。那么如果保证自己想要获取关联数据时,数据库会话session还存在呢?今天讲解一种方法,借助Spring提供的@Transactional注解来实现方法内部的操作在同一次数据库连接中执行。需要注意的是,使用@Transactional注解,必须要保证方法通过Spring组件解析方式处理,spring代理会为方法注入事务拦截逻辑。

       关于spring的事务实现原理,可以参考《Spring @Transactional工作原理

       一、为实体类ProcessBlock和Node添加一对多的关联关系。Set<Node>属性使用懒加载方式。下面给出代码。  

    @Entity(name = "nbpm_processblock")
    @NamedQuery(name = "ProcessBlock.findByName", query = "select p from nbpm_processblock p where p.name=?1")
    public class ProcessBlock implements Serializable {
        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
        long id;
        @Column(name = "name")
        String name;
        @Column(name = "description")
        String description;
        String subClass;
        @OneToMany(mappedBy = "processblock", cascade = CascadeType.ALL,fetch=FetchType.LAZY)
        // @JoinColumn(name="processblock_id")
        Set<Node> nodeSet = new HashSet<Node>();

     二、为查询方法添加事务注解

        @Transactional
        @RequestMapping(value = "/list", method = RequestMethod.GET)
        public String list(ModelMap model,HttpSession session) {
            //ProcessBlockRepository processBlock = ApplicationContextUtil.instance.getBean(ProcessBlockRepository.class);
            //List<ProcessBlock> list = processBlock.findByName1("主干流程");
            Map<String, Object> params = new HashMap<>();
            params.put("name", "主干流程");
            List<ProcessBlock> list = ApplicationContextUtil.instance.getJpaUtil().list(
                    "select u from simm.spring.entity.ProcessBlock u where u.name=:name", params, ProcessBlock.class);
            System.out.println("准备获取懒加载数据");
            Set<Node> nodes = list.get(0).getNodeSet();

      三、调试一下,查看调用情况

      1、测试代码先执行List<ProcessBlock>查询,之后输出"准备获取懒加载数据",最后查询第一条ProcessBlock对应的节点集合。通过执行日志很容易看出,懒加载的数据只有在后续的代码逻辑中被调用后,才会生成sql查询,在数据库中执行获取数据。

      

      2、先获取List<ProcessBlock>列表后,在来获取第一个ProcessBlock对象对应的节点集合。调试显示已经成功获取到数据。

       

      至此,测试完毕。用法很简单,但是关于spring事务的实现这块还是很有意思的,一次数据库连接在线程中通过ThreadLocal变量传递,其生命周期靠事务拦截器来控制。这个过程在ORM框架中应该是一种比较通用的思路,在Hibernate中如此,其他框架应该也是相差无几。感谢你的阅读,欢迎留言讨论交流!

  • 相关阅读:
    TCP Data Flow and Window Management(3)
    全渠道java b2b b2c o2o平台
    springmvc mybatis shiro ios android构建cms系统
    电子商务系统+java+web+完整项目+包含源码和数据库Java实用源码
    大型互联网 b2b b2c o2o 电子商务微服务云平台
    mybatis电子商务平台b2b2c
    spring mvc mybatis shiro构建cms系统ios android
    spring mvc+mybatis 构建 cms + 实现UC浏览器文章功能
    b2b b2c o2o电子商务微服务云平台
    java分布式电子商务云平台b2b b2c o2o需要准备哪些技术??
  • 原文地址:https://www.cnblogs.com/MrSi/p/8087090.html
Copyright © 2011-2022 走看看