template modules jpa 帮你轻松完成对数据的操作,无需额外编写dao,一个dao满足你所有需求。支持多数据源(多数据源也只需定义一个dao即可)。
<dependency>
<groupId>me.wuwenbin</groupId>
<artifactId>template-modules-jpa</artifactId>
<version>1.11.5-SNAPSHOT</version>
</dependency>- 新增初始化后可更改数据源的两种操作方法
- 增加参数log记录日志功能
- 更新insertXxxAutoGenKeyReturnXxx带tableName的方法,改为由方法自己从插入语句中计算出tableName,取代用户自己传入tableName参数
- 删除一些不必要的throws
- 删除一些不必要的泛型指定
- 增加查询单列单行,单列多行的方法。只允许为基本类型的包装类和String类型
- 取消自定义的函数式接口,改为直接调用JDK8内置的函数式接口。
- 修改了响应的方法以及类名称,使文意更清晰。具体为
InternalCall.transfer()方法。表示内部调用.调用方法
- 从1.9.0版本开始需要JDK8及以上支持。
- 在DaoFactory中增加用户可自己获取并且注入dao的方法。即不使用注解去动态切换。
- 修复了在方法内部调用方法的时候,多数据源注解切换无效的BUG。使用方法请使用对应的
Calls.get()方法。 - dao增加了2个插入方法,可以传入tableName和pkName,但前提,必须是实体类对应。
- 新增SQLServer2000以及SQLServer2005+的方法。
- 新增db2、derby、hsql、informix等支持。
- 增加了insertMapAutoGenKeyOutBean方法。
- xml配置方法(具体属性值配置此处省略,根据开发情况配置)
<bean id="ds1" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"/>
<bean id="ds2" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"/>- java配置方法(推荐Druid Spring Boot Starter快速配置)
@Primary
@Bean
@ConfigurationProperties("spring.datasource.druid.one")
public DataSource dataSourceOne(){
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.druid.two")
public DataSource dataSourceTwo(){
return DruidDataSourceBuilder.create().build();
}- xml配置方法
<bean id="dsx1" class="me.wuwenbin.modules.jpa.factory.business.DataSourceX">
<property name="dataSource" ref="ds1"/>
<property name="initDbType" value="Mysql"/><!-- 此处的Mysql为DbType.Mysql,默认Mysql-->
</bean>
<bean id="dsx2" class="me.wuwenbin.modules.jpa.factory.business.DataSourceX">
<property name="dataSource" ref="ds2"/>
<property name="initDbType" value="Mysql"/><!-- 此处的Mysql为DbType.Mysql,默认Mysql -->
</bean>- java配置方法
@Bean
public DataSourceX dataSourceX(DruidDataSource dataSource) {
DataSourceX dataSourceX = new DataSourceX();
dataSourceX.setDataSource(dataSource);
dataSourceX.setInitDbType(DbType.Mysql);
return dataSourceX;
}- xml配置
<bean id="daoFactory" class="me.wuwenbin.modules.jpa.factory.DaoFactory">
<!--多个增强数据源的map集合-->
<property name="dataSourceMap">
<map key-type="java.lang.String">
<entry key="tp" value-ref="dsx1"/>
<entry key="ct" value-ref="dsx2"/>
</map>
</property>
<!--默认的增强数据源-->
<property name="defaultDao" ref="dsx1"/>
</bean>- java配置
@Bean
public DaoFactory daoFactory(DataSourceX dataSourceX) {
DaoFactory daoFactory = new DaoFactory();
Map<String, DataSourceX> multiDao = new ConcurrentHashMap<>();
multiDao.put("template_default_dao", dataSourceX);
daoFactory.setDataSourceMap(multiDao);
daoFactory.setDefaultDao(dataSourceX);
return daoFactory;
}- 使用方法1:在Spring项目的一个Bean中注入DaoFactory即可。
@Autowired
private DaoFactory daoFactory;
public List<Student> findStudentsByCampusNo(String campusNo){
String sql = "select * from t_stu_info where campus_no = ?";
return daoFactory.dynamicDao.findListBeanByArray(sql, Student.class, campusNo);
}- 使用方法2:在Spring项目的一个Bean中注入AncestorDao即可。
private AncestorDao daoTemplate;
@Autowired
public void setDaoTemplate(DaoFactory daoFactory){
this.daoTemplate = daoFactory.dynamicDao;
}
public List<Student> findStudentsByCampusNo(String campusNo){
String sql = "select * from t_stu_info where campus_no = ?";
return daoTemplate.findListBeanByArray(sql, Student.class, campusNo);
}- 如果切换多数据源的操作 (在方法上加上@DynamicDataSource注解即可,其中参数为配置何种指定的key)
/**
* 当程序进入此方法时,数据源切换到key为tp的数据上,访问完毕后,会切回配置中默认的数据源。
*/
@DynamicDataSource("tp")
public List<Student> findStudentsByCampusNo(String campusNo){
String sql = "select * from t_stu_info where campus_no = ?";
return daoTemplate.findListBeanByArray(sql, Student.class, campusNo);
}- 如果某方法内含有调用其他方法的操作 (譬如a方法中有调用b方法的操作,且b方法切换了与a不同的数据源),则需以下操作
@DynamicDataSource("ct")
public List<UserA> findUserAs() {
String sql = "select * from t_user";
return daoFactory.dynamicDao.findListMapByArray(sql);
}
/**
* 此方法为默认数据源 ,所以无需注解,写注解也可以
*/
public List<UserB> findUserBs() {
String sql = "select * from t_oauth_user";
return daoFactory.dynamicDao.findListMapByArray(sql);
}
@DynamicDataSource("tp")
public List<UserB> findUserBs2(String sql) {
return daoFactory.dynamicDao.findListMapByArray(sql);
}
/**
* 以下为错误的用法 ,此处数据源则不会切换,一直使用默认的访问
*/
public void testError(){
tp1();
ct();
tp2();
}
/**
* 正确的用法如下。
* 原因:因为被aop代理之后,代理类中内部方法的调用并不能编译到上面的注解,aop没有拦截到,故需要显式调用(此处使用JDK8的函数式接口模式)。
*/
public void testCorrect(){
List<UserB> bs1 = InternalCall.transfer(PublicService::findUserBs);
List<UserB> bs2 =
InternalCall.transfer((Function<PublicService, List<UserB>>) bean -> bean.findUserBs2("select * from t_oauth_role"));
List<UserA> as = InternalCall.transfer(PublicService::campusTalk);
}- 如果AncestorDao中的方法还不能满足你的需求(基本上99%都可以),你可以自己获取相关原始对象来操作
private AncestorDao daoTemplate;
//获取simpleJdbcCall,一般用来执行存储过程的
daoTemplate.getSimpleJdbcCallObj();
//获取jdbcTemplate对象,用来执行?参数的sql语句
daoTemplate.getJdbcTemplateObj();
//获取namedParameterJdbcTemplate对象,一般用来执行:参数的sql语句
daoTemplate.getNamedParameterJdbcTemplateObj();- 执行存储过程
以 callProcedure 为开头的方法
- 执行插入语句,并且需要返回值的
类似 insertXxxAutoGenKeyReturnXxx 这样的方法
根据插入的类型选择前缀匹配,以及根据返回的需求进行后缀匹配即可
- 执行插入、更新、删除语句,返回影响条目数的,或者没什么要求的
类似 executeXxx 的方法
方法名后缀根据sql语句以及方法传的参数来选择
- 批量执行插入、更新、删除语句,返回影响条目数的,或者没什么要求的
类似 executeBatchByXxx 的方法
方法名后缀根据sql语句以及方法传的参数来选择
- 执行统计的语句
以 findNumberBy 开头的则返回类型为Number需自行转换对象的数字类型包装类
以 queryNumberBy 开头的则返回指定的数字类型包装类 方法名后缀根据sql语句以及方法传的参数来选择
- 执行单列单行的查找/单列多行的查询语句
以 findPrimitiveBy 开头的方法查找单列单行
以 findListPrimitiveBy 开头的方法查找单列多行
方法名后缀根据sql语句以及方法传的参数来选择
- 执行N列单行查找/N列N行的查询语句(某种程度上来讲此条包含上一条,只不过上面的是此条情况的一种特殊情况)
以 findMapBy 开头的是查找N列单行的无Java类对象匹配的方法
以 findBeanBy 开头的是查找N列单行的有相应的Java类对象匹配的方法
以 findListMapBy 开头的是查找N列N行的无Java类对象匹配的方法
以 findListBeanBy 开头的是查找N列N行的有相应的Java类对象匹配的方法
方法名后缀根据sql语句以及方法传的参数来选择
- 执行分页方法的查找,情况大致同上一条
此处不再列举,仅仅是方法名前面多了Page,情况和上一条一致