开发背景
公司多年前项目,使用hibernate作为持久层,部分sql查询采用spring的JdbcTemplate,sql穿插在java代码中。因此,需要统一使用hibernate,并且sql部分需要类似Mybatis一样从文件中读取。由于引入Mybatis需要对项目改动较大,因此,需要编写相应代码用以支持hibernate动态读取外部sql。
功能介绍
对hibernate功能进行拓展,使之可读取外部sql并执行相应逻辑返回结果,功能类似Mybatis的相关逻辑。
代码简介
项目主要通过com.feng.spring.hibernate.extend.processor.HibernateExtendPostProcessor的postProcessBeanDefinitionRegistry方法,解析相关sql并缓存,将相关接口解析成代理类,其中:
BeanDefinitionBuilder builder1 = BeanDefinitionBuilder.genericBeanDefinition();AbstractBeanDefinition definition1 = builder1.getBeanDefinition();definition1.setBeanClass(HibernateExtendFactory.class);definition1.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);definition1.getPropertyValues().add("hibernateExtendConfiguration", configuration);definition1.getPropertyValues().add("hibernateExtendSQLExecutor", new DefaultHibernateExtendSQLExecutor());definition1.getPropertyValues().add("hibernateExtendSQLBuilder", new DefaultHibernateExtendSQLBuilder());registry.registerBeanDefinition(FACTORY_NAME, definition1);
建议HibernateExtendFactory的注册可以放到标注为@Configuration的配置文件中进行,由于项目没有引用springboot相关依赖,因此可以参照如下:
@Bean
public HibernateExtendFactory hibernateExtendFactory(SessionFactory sessionFactory){HibernateExtendFactory hibernateExtendFactory = new HibernateExtendFactory();hibernateExtendFactory.setSessionFactory(sessionFactory);return hibernateExtendFactory;
}
使用帮助
- 建议将代码下载,调整后编译为相应的jar包使用而不是直接拖入项目中。
- 项目需要spring的支持
- 相关查询的dao必须是接口形式存在,且相关方法名不允许多态
- sql文件命名规则为
类名全限定名 + _ + 方法名 +.sql
,且拓展名.sql
须小写,例如:com.feng.springboot.hibernate.demo.Tee_get.sql
。 - sql扫描路径配置属性为“hibernate-extend.locations”,例如:
hibernate-extend.locations=classpath*:/sql/**/*_*.sql
,不填写的情况下默认项目内扫描*_*.sql
的文件。建议填写越详细越好,可以提高扫描速度减少项目启动时间。 - 需要根据项目本身情况对本项目进行调整,尤其是Executor部分逻辑,需要定制更贴合自身项目的代码!
- 编写sql
- 编写第一个sql文件
com.feng.springboot.hibernate.demo.Tee_get.sql
:
select id, name from ${tableName} where id = #{id}
和Mybatis一样 ${}
表示替换变量,#{}
表示预编译参数。
- 编写第二个sql文件
com.feng.springboot.hibernate.demo.Tee_list.sql
:
select id, name from test_hibernate_entity where id in (#{ids})
和上面一样#{}
表示预编译参数,但是会根据java方法中传入的参数,判断为多个参数,会自动拼接多个占位符用以支持in查询。
- 编写接口类
com.feng.springboot.hibernate.demo.Tee
:
public interface Tee {List get(String tableName, int id);List list(List ids); // 参数说明:java.util.List或者相应格式数组都会被解析为多个参数
}
通过这两个步骤,代码中就可以自动注入Tee这个类了
其他
参照demo
源代码下载:
https://download.csdn.net/download/u013271384/89096891