SpringBoot-使用链接字符串动态创建SqlSessionFactory执行任意SQL脚本
引言
SpringBoot大大减少了使用XML配置的复杂性,但是想通过代码去实例化一个对象有点儿无从下手的感觉。
SpringMVC中通过XML的配置和层级关系,大致能翻译为代码去构建一个对象。
SqlSessionFactory的创建也是参考了XML的配置去构建的。
环境:SpringBoot 1.56 + Pgsql 14
目标
使用链接字符串动态创建SqlSessionFactory对象,通过mapper执行任意SQL脚本;
SqlSessionFactory的一般用法
更简单的调用可以直接注入一个mapper对象,但是隐藏了我们关注的SqlSessionFactiory对象;
mapper类和对应的xml是必不可少的组件;
要实现执行动态SQL,就要建一个通用的mapper和对应的xml文件,xml中的占位符要用${xxx}
${} 是非参数化占位符,有SQL注入风险;#{} 参数化占位符;
1.注入一个对象
@Autowired
SqlSessionFactory sqlSessionFactory;
2.实例化SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
3.实例化Mapper对象
GeneralMapper mapper = sqlSession.getMapper(GeneralMapper.class);
4.执行mapper中的方法
int n = mapper.xxxxx();
实例化SqlSessionFactory对象
封装一个getSqlSessionFactory()方法,可以动态的将链接参数传入支持多数据源切换;
private SqlSessionFactory getSqlSessionFactory(){
String driver = "org.postgresql.Driver";
//A6库
String connStr = "jdbc:postgresql://xxxxxxx:5432/CRP?currentSchema=mySchema";
String uname = "pguser";
String upwd = "123456";
//创建连接池
DataSource dataSource = new PooledDataSource(driver, connStr ,uname, upwd);
//事务控制(配置:隔离级别、自动提交等)
TransactionFactory transactionFactory = new JdbcTransactionFactory();
//环境配置(一些查询特性)
Environment environment = new Environment("development", transactionFactory, dataSource);
//创建配置
Configuration configuration = new Configuration(environment);
configuration.setMapUnderscoreToCamelCase(true);//开启驼峰规则
configuration.setCallSettersOnNulls(true);//规定查询数据为空是则返回null
//加入资源(Mapper接口)
configuration.addMapper(GeneralMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
return sqlSessionFactory;
}
通用Mapper接口
@Repository
public interface GeneralMapper {
List<Map<String,Object>> select(@Param("sql") String strSql);
void insert(@Param("sql") String strSql);
void delete(@Param("sql") String strSql);
int update(@Param("sql") String strSql);
}
通用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="my.GeneralMapper">
<select id="select" resultType="Map" statementType="STATEMENT">
${sql}
</select>
<insert id="insert" parameterType="java.lang.String">
${sql}
</insert>
<delete id="delete" parameterType="java.lang.String">
${sql}
</delete>
<update id="update" parameterType="java.lang.String">
${sql}
</update>
</mapper>
调用方式
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
GeneralMapper mapper = sqlSession.getMapper(GeneralMapper.class);
//注意通用查询返回的是一个map对象集,map.value必须是object类型
List<Map<String, Object>> dataLst = mapper.select(querySql);