• 讨论一下hibernate如何动态注册一个动态生成的实体类


      如何动态生成实体类请参考这篇博文:http://www.cnblogs.com/anai/p/4269858.html

      下面说说得到实体类后,如何能使用hibernate的接口来进行数据访问。

      我们都知道,hibernate是在web容器启动的时候根据相关配置信息,扫描class文件,然后注册到SessionFactory中。通过getAllClassMetadata()可以得到已经注册过的实体类的元信息。那么如果是在容器启动已经完成后,程序正常运行期间产生的类,显然是不能直接使用hibernate的接口的,因为hibernate还不认识这个新创建的类呢。那么如何在这个阶段让它们认识并建立关系呢,思路很简单,就是注册呗,但是这里有个问题,我们不能使用原来的sessionFactory了,会导致事务安全的问题,而且hibernate也建议sessionFactory一旦创建好了,就不要对其做修改,所以即使configration的内容变化了,之前就创建好的sessionFactory也不会受到影响。好了下面上代码:

    代码中 SpringContextUtil.getBean("&sessionFactory") 的&符的含义,可以参考这篇博文:http://www.cnblogs.com/anai/p/4258934.html

    public class myDao{   
        @Autowired
        @Qualifier("sessionFactory")
        private SessionFactory sessionFactory;
    
        private List<SessionFactory> sessionFactoryList = new ArrayList<SessionFactory>();
    
        /******************** 以下 方法只适用于对象是动态加载进JVM的情况******************************/
        /**
         * 获取Session工厂
         * 如果指定的model是动态加载到JVM中的,
         * 那么就更新当前的configuration,
         * 并重新创建一个Session工厂(因为Session工厂是全局单例的,所以创建好之后最好不要改动,容易出现事务安全问题),
         * 以便能为该对象执行数据库访问操作
         * 该方法如果频繁使用,会增加系统开销
         * @param entityClass
         * @return
         */
        private SessionFactory obtainSessionFactory(Class<?> entityClass){
            Map<String,ClassMetadata> map = sessionFactory.getAllClassMetadata();
            Set<String> set = map.keySet();
            if(!set.contains(entityClass.getName())){
                for(SessionFactory factory : sessionFactoryList){
                    Set<String> existSet = factory.getAllClassMetadata().keySet();
                    if(existSet.contains(entityClass.getName())){//该sessionFactory包含了此实体,就用该SessionFactory
                        return factory;
                    }
                }
                LocalSessionFactoryBean localSessionFactoryBean = SpringContextUtil.getBean("&sessionFactory");
                Configuration configuration = localSessionFactoryBean.getConfiguration();
                synchronized(configuration){//避免并发操作导致configuration重复添加相同的entityClass
                    if(configuration.getClassMapping(entityClass.getName())==null){
                        configuration.addAnnotatedClass(entityClass);
                    }
                }
                ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
                SessionFactory newSessionFactory = configuration.buildSessionFactory(serviceRegistry);
                sessionFactoryList.add(newSessionFactory);
                return newSessionFactory;
            }else{
                return sessionFactory;
            }
        }
    }

  • 相关阅读:
    iOS 10 因苹果健康导致闪退 crash-b
    iOS10 配置须知-b
    iOS开发 适配iOS10以及Xcode8-b
    iOS 10 的适配问题-b
    mybatis中分页查询
    mybatis开发流程,增删改查
    spring mvc接收参数方式,json格式返回请求数据
    xml配置文件中常见的命名空间解释
    myeclipse中配置schemaLocation路径,实现xml文件自动提示
    spring MVC工作流程
  • 原文地址:https://www.cnblogs.com/anai/p/4270214.html
Copyright © 2020-2023  润新知