一、序言
最近在做一个项目,项目需求大概就是写一个通用的操作数据库中表的方法,要求能够对表进行增删改查。后续只需要增加配置就可以对新加的表进行操作。
二、创建固定的几个类,使其能够自动的连接数据库
以下的代码只是用在我自己的项目中的,仅供参考。
DataSource类与DataSourceProperties类放在properties文件夹下面,DataSourceConfiguration类放在autoconfigure文件夹下面,properties文件夹是autoconfigure文件夹子文件夹。这两个文件需自己创建
创建DataSource类
@Data
@AllArgsConstructor
public class DataSource {
/**
* 数据库驱动
*/
private String driverClassName;
/**
* 数据库url
*/
private String url;
/**
* 数据库用户名
*/
private String username;
/**
* 数据库密码
*/
private String password;
}
这个类是个通用的类,其它的项目可以参考
创建DataSourceProperties类
此类的作用的是读取application.yml自己配置的数据库属性
@Data
@ConfigurationProperties(prefix = "spring.自己项目配置的地方", ignoreUnknownFields = true)
public class DataSourceProperties {
/**
* 是否启用
*/
private boolean enabled;
/**
* 驱动
*/
private String driverClassName;
/**
* url
*/
private String url;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
public DataSource getDataSource() {
return new DataSource(driverClassName, url, username, password);
}
}
创建DataSourceConfiguration类
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "spring.自己项目配置的地方", name = "enable", havingValue = "true", matchIfMissing = false)
@Data
public class DataSourceConfiguration {
@Configuration(proxyBeanMethods = true)
@EnableConfigurationProperties(GetMsgKafkaDataSourceProperties.class)
//basePackages 这个是后续写mapper接口带吗放置的位置
@MapperScan(basePackages = {"com.kafka.mapper"}, sqlSessionFactoryRef = "kafkaSqlSessionFactory")
protected static class KafkaSourceConfiguration {
@ConditionalOnMissingBean(name = "kafka")
@ConfigurationProperties("spring..自己项目配置的地方")
@Bean(name = "kafka")
public DruidDataSource PersonDataSource(DataSourceProperties DataSourceProperties) {
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "kafkaSqlSessionFactory")
public SqlSessionFactory kafkaSqlSessionFactory(@Qualifier("kafka") DruidDataSource dataSource) throws Exception {
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
MybatisSqlSessionFactoryBean sessionFactoryBean = new MybatisSqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
//此处的classpath是后续需要配置的mybatis的xml文件的放置位置,根据自己的文件位置配置
sessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:com/kafka/mapper/*.xml"));
sessionFactoryBean.setConfigLocation(resolver.getResource("classpath:config/mybatis/mybatis-config.xml"));
sessionFactoryBean.setPlugins(mybatisPlusInterceptor());
System.out.println("------------------kafka SqlSessionFactory connect!----------------");
return sessionFactoryBean.getObject();
}
@Bean("kafkaMybatisPlusInterceptor")
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.ORACLE));
return interceptor;
}
//增加事务注解
@Bean(name="kafkaTransactionManager")
public PlatformTransactionManager kafkaTransactionManager(@Qualifier("kafka") DruidDataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
}
三、创建访问数据库的接口类
这里是访问数据库的接口类,此接口类中updateTableByPrimaryKey方法是使用oracle数据库中的merge方法,更新操作数据库特别的方便。但是使用这个方法也有一些注意点
(1)组建的SQL语句字符串不能过长,否则会报 ORA-17410:无法从套接字中获取更多数据。就是一次发送的数据过多无法一次性把修改放入到数据库中。在此处的实验结果是updateDataList的长度最好在500以内。当然具体还需要看每个字段的实际长度来定。
public interface SyncModeMapper {
//查询数据库是否存在表
int isTableExist(@Param("tableName") String tableName);
//向表中插入值
void insert(@Param("tableName") String tableName, @Param("fields") String fileds, @Param("values") String values);
//创建表
void createTable(@Param("tableName") String tableName, @Param("fields") String fileds);
//清空表
void truncateTable(@Param("tableName") String tableName);
//获取表中所有的数据
List<Object> getAllData(@Param("tableName") String tableName);
//根据表名与字段值查询记录是否存在
List<Object> selectRecordsByTableNameAndFiledValue(@Param("tableName") String tableName,
@Param("filedValue") String filedValue);
//根据字段值查询数据库中是否存在此数据
int deleteRecordsByTableNameAndFiledValue(@Param("tableName") String tableName, @Param("filedValue") String filedValue);
int updateTableByPrimaryKey(@Param("tableName") String tableName,
@Param("updateDataList") List<String> updateDataList,
@Param("primaryKeyEqualPairs") String primaryKeyEqualPairs,
@Param("tableFieldEqualPairs") String tableFieldEqualPairs,
@Param("tfields") String tfields,
@Param("t1fields") String t1fields);
}
四、创建mybatis的xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kafka.mapper.SyncMapper">
<!--查询表是否存在-->
<select id="isTableExist" parameterType="String" resultType="int">
select count(*)
from user_tables
where table_name = #{tableName}
</select>
<!--插入值-->
<insert id="insert" parameterType="String">
insert into ${tableName} (${fields})
values (${values})
</insert>
<!--创建表-->
<update id="createTable" parameterType="String">
CREATE TABLE ${tableName}
(
${fields}
)
</update>
<!--清空表-->
<update id="truncateTable" parameterType="String">
truncate table ${tableName}
</update>
<!--获取表中所有数据-->
<select id="getAllData" parameterType="String" resultType="Map">
select *
from ${tableName}
</select>
<!--根据字段值查询数据库中是否存在此数据-->
<select id="selectRecordsByTableNameAndFiledValue" parameterType="String" resultType="Map">
select *
from ${tableName}
where ${filedValue}
</select>
<!--根据字段值查询数据库中是否存在此数据-->
<delete id="deleteRecordsByTableNameAndFiledValue" parameterType="String">
delete
from ${tableName}
where ${filedValue}
</delete>
<insert id="updateTableByPrimaryKey" parameterType="String">
MERGE INTO ${tableName} t
USING (
<foreach collection="updateDataList" item="item" separator="union">
select
${item}
from dual
</foreach>
) t1
on (${primaryKeyEqualPairs})
WHEN MATCHED THEN
UPDATE SET
${tableFieldEqualPairs}
WHEN NOT MATCHED THEN
INSERT (${tfields})
VALUES (${t1fields})
</insert>
</mapper>
五、使用
@Service
public class KafKaRunnable {
@Autowired
SyncModeMapper syncModeMapper;
@PostConstruct
public void run() {
String localTableName = null;
List<String> updateDataList = null;
String primaryKeyEqualPairs = null;
String tableFieldEqualPairs = null;
String tfields = null;
String t1fields = null;
int mergeNum = syncModeMapper.updateTableByPrimaryKey(localTableName, updateDataList, primaryKeyEqualPairs,
tableFieldEqualPairs, tfields, t1fields);
}
}