SpringBoot 自定义SQL执行器

不点 阅读:813 2021-03-31 16:56:46 评论:0

业务需求:自定义SQL执行器,获取当前连接MySQL8 包含多少个数据库,指定数据库包含多少个表。

先分析项目结构的构成:springboot +mybatis3 + mysql8 搭建的项目.

我惊喜的发现了一个:

根据上面的自动注入 编写自己的SQL 执行器,代码如下:

 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Map; 
import org.apache.ibatis.builder.StaticSqlSource; 
import org.apache.ibatis.exceptions.TooManyResultsException; 
import org.apache.ibatis.mapping.MappedStatement; 
import org.apache.ibatis.mapping.ResultMap; 
import org.apache.ibatis.mapping.ResultMapping; 
import org.apache.ibatis.mapping.SqlCommandType; 
import org.apache.ibatis.mapping.SqlSource; 
import org.apache.ibatis.scripting.LanguageDriver; 
import org.apache.ibatis.session.Configuration; 
import org.apache.ibatis.session.SqlSession; 
import org.apache.ibatis.session.SqlSessionFactory; 
 
/** 
 * 自定义SQL 执行器 
 * 
 */ 
public class SQLActuator { 
	private MSUtils msUtils = null; 
	private SqlSession sqlSession = null; 
	private SqlSessionFactory factory; 
 
	public SqlSessionFactory getFactory() { 
		return factory; 
	} 
 
	public void setFactory(SqlSessionFactory factory) { 
		this.factory = factory; 
	} 
 
	/** 
	 * 构造方法,默认缓存MappedStatement 
	 * 
	 * @param sqlSession 
	 * @return 
	 */ 
	public SQLActuator(SqlSessionFactory factory) { 
		this.factory = factory; 
		this.sqlSession = factory.openSession(); 
		this.msUtils = new MSUtils(sqlSession.getConfiguration()); 
	} 
 
	/** 
	 * 获取List中最多只有一个的数据 
	 * 
	 * @param list 
	 *            List结果 
	 * @param <T> 
	 *            泛型类型 
	 * @return 
	 */ 
	private <T> T getOne(List<T> list) { 
		if (list.size() == 1) { 
			return list.get(0); 
		} else if (list.size() > 1) { 
			throw new TooManyResultsException( 
					"Expected one result (or null) to be returned by selectOne(), but found: " + list.size()); 
		} else { 
			return null; 
		} 
	} 
 
	/** 
	 * 查询返回一个结果,多个结果时抛出异常 
	 * 
	 * @param sql 
	 *            执行的sql 
	 * @return 
	 */ 
	public Map<String, Object> selectOne(String sql) { 
		List<Map<String, Object>> list = selectList(sql); 
		return getOne(list); 
	} 
 
	/** 
	 * 查询返回一个结果,多个结果时抛出异常 
	 * 
	 * @param sql 
	 *            执行的sql 
	 * @param value 
	 *            参数 
	 * @return 
	 */ 
	public Map<String, Object> selectOne(String sql, Object value) { 
		List<Map<String, Object>> list = selectList(sql, value); 
		return getOne(list); 
	} 
 
	/** 
	 * 查询返回一个结果,多个结果时抛出异常 
	 * 
	 * @param sql 
	 *            执行的sql 
	 * @param resultType 
	 *            返回的结果类型 
	 * @param <T> 
	 *            泛型类型 
	 * @return 
	 */ 
	public <T> T selectOne(String sql, Class<T> resultType) { 
		List<T> list = selectList(sql, resultType); 
		return getOne(list); 
	} 
 
	/** 
	 * 查询返回一个结果,多个结果时抛出异常 
	 * 
	 * @param sql 
	 *            执行的sql 
	 * @param value 
	 *            参数 
	 * @param resultType 
	 *            返回的结果类型 
	 * @param <T> 
	 *            泛型类型 
	 * @return 
	 */ 
	public <T> T selectOne(String sql, Object value, Class<T> resultType) { 
		List<T> list = selectList(sql, value, resultType); 
		return getOne(list); 
	} 
 
	/** 
	 * 查询返回List<Map<String, Object>> 
	 * 
	 * @param sql 
	 *            执行的sql 
	 * @return 
	 */ 
	public List<Map<String, Object>> selectList(String sql) { 
		String msId = msUtils.select(sql); 
		return sqlSession.selectList(msId); 
	} 
 
	/** 
	 * 查询返回List<Map<String, Object>> 
	 * 
	 * @param sql 
	 *            执行的sql 
	 * @param value 
	 *            参数 
	 * @return 
	 */ 
	public List<Map<String, Object>> selectList(String sql, Object value) { 
		Class<?> parameterType = value != null ? value.getClass() : null; 
		String msId = msUtils.selectDynamic(sql, parameterType); 
		return sqlSession.selectList(msId, value); 
	} 
 
	/** 
	 * 查询返回指定的结果类型 
	 * 
	 * @param sql 
	 *            执行的sql 
	 * @param resultType 
	 *            返回的结果类型 
	 * @param <T> 
	 *            泛型类型 
	 * @return 
	 */ 
	public <T> List<T> selectList(String sql, Class<T> resultType) { 
		String msId; 
		if (resultType == null) { 
			msId = msUtils.select(sql); 
		} else { 
			msId = msUtils.select(sql, resultType); 
		} 
		return sqlSession.selectList(msId); 
	} 
 
	/** 
	 * 查询返回指定的结果类型 
	 * 
	 * @param sql 
	 *            执行的sql 
	 * @param value 
	 *            参数 
	 * @param resultType 
	 *            返回的结果类型 
	 * @param <T> 
	 *            泛型类型 
	 * @return 
	 */ 
	public <T> List<T> selectList(String sql, Object value, Class<T> resultType) { 
		String msId; 
		Class<?> parameterType = value != null ? value.getClass() : null; 
		if (resultType == null) { 
			msId = msUtils.selectDynamic(sql, parameterType); 
		} else { 
			msId = msUtils.selectDynamic(sql, parameterType, resultType); 
		} 
		return sqlSession.selectList(msId, value); 
	} 
 
	/** 
	 * 插入数据 
	 * 
	 * @param sql 
	 *            执行的sql 
	 * @return 
	 */ 
	public int insert(String sql) { 
		String msId = msUtils.insert(sql); 
		return sqlSession.insert(msId); 
	} 
 
	/** 
	 * 插入数据 
	 * 
	 * @param sql 
	 *            执行的sql 
	 * @param value 
	 *            参数 
	 * @return 
	 */ 
	public int insert(String sql, Object value) { 
		Class<?> parameterType = value != null ? value.getClass() : null; 
		String msId = msUtils.insertDynamic(sql, parameterType); 
		return sqlSession.insert(msId, value); 
	} 
 
	/** 
	 * 更新数据 
	 * 
	 * @param sql 
	 *            执行的sql 
	 * @return 
	 */ 
	public int update(String sql) { 
		String msId = msUtils.update(sql); 
		return sqlSession.update(msId); 
	} 
 
	/** 
	 * 更新数据 
	 * 
	 * @param sql 
	 *            执行的sql 
	 * @param value 
	 *            参数 
	 * @return 
	 */ 
	public int update(String sql, Object value) { 
		Class<?> parameterType = value != null ? value.getClass() : null; 
		String msId = msUtils.updateDynamic(sql, parameterType); 
		return sqlSession.update(msId, value); 
	} 
 
	/** 
	 * 删除数据 
	 * 
	 * @param sql 
	 *            执行的sql 
	 * @return 
	 */ 
	public int delete(String sql) { 
		String msId = msUtils.delete(sql); 
		return sqlSession.delete(msId); 
	} 
 
	/** 
	 * 删除数据 
	 * 
	 * @param sql 
	 *            执行的sql 
	 * @param value 
	 *            参数 
	 * @return 
	 */ 
	public int delete(String sql, Object value) { 
		Class<?> parameterType = value != null ? value.getClass() : null; 
		String msId = msUtils.deleteDynamic(sql, parameterType); 
		return sqlSession.delete(msId, value); 
	} 
 
	private class MSUtils { 
		private Configuration configuration; 
		private LanguageDriver languageDriver; 
 
		private MSUtils(Configuration configuration) { 
			this.configuration = configuration; 
			languageDriver = configuration.getDefaultScriptingLanuageInstance(); 
		} 
 
		/** 
		 * 创建MSID 
		 * 
		 * @param sql 
		 *            执行的sql 
		 * @param sql 
		 *            执行的sqlCommandType 
		 * @return 
		 */ 
		private String newMsId(String sql, SqlCommandType sqlCommandType) { 
			StringBuilder msIdBuilder = new StringBuilder(sqlCommandType.toString()); 
			msIdBuilder.append(".").append(sql.hashCode()); 
			return msIdBuilder.toString(); 
		} 
 
		/** 
		 * 是否已经存在该ID 
		 * 
		 * @param msId 
		 * @return 
		 */ 
		private boolean hasMappedStatement(String msId) { 
			return configuration.hasStatement(msId, false); 
		} 
 
		/** 
		 * 创建一个查询的MS 
		 * 
		 * @param msId 
		 * @param sqlSource 
		 *            执行的sqlSource 
		 * @param resultType 
		 *            返回的结果类型 
		 */ 
		private void newSelectMappedStatement(String msId, SqlSource sqlSource, final Class<?> resultType) { 
			MappedStatement ms = new MappedStatement.Builder(configuration, msId, sqlSource, SqlCommandType.SELECT) 
					.resultMaps(new ArrayList<ResultMap>() { 
						{ 
							add(new ResultMap.Builder(configuration, "defaultResultMap", resultType, 
									new ArrayList<ResultMapping>(0)).build()); 
						} 
					}).build(); 
			// 缓存 
			configuration.addMappedStatement(ms); 
		} 
 
		/** 
		 * 创建一个简单的MS 
		 * 
		 * @param msId 
		 * @param sqlSource 
		 *            执行的sqlSource 
		 * @param sqlCommandType 
		 *            执行的sqlCommandType 
		 */ 
		private void newUpdateMappedStatement(String msId, SqlSource sqlSource, SqlCommandType sqlCommandType) { 
			MappedStatement ms = new MappedStatement.Builder(configuration, msId, sqlSource, sqlCommandType) 
					.resultMaps(new ArrayList<ResultMap>() { 
						{ 
							add(new ResultMap.Builder(configuration, "defaultResultMap", int.class, 
									new ArrayList<ResultMapping>(0)).build()); 
						} 
					}).build(); 
			// 缓存 
			configuration.addMappedStatement(ms); 
		} 
 
		private String select(String sql) { 
			String msId = newMsId(sql, SqlCommandType.SELECT); 
			if (hasMappedStatement(msId)) { 
				return msId; 
			} 
			StaticSqlSource sqlSource = new StaticSqlSource(configuration, sql); 
			newSelectMappedStatement(msId, sqlSource, Map.class); 
			return msId; 
		} 
 
		private String selectDynamic(String sql, Class<?> parameterType) { 
			String msId = newMsId(sql + parameterType, SqlCommandType.SELECT); 
			if (hasMappedStatement(msId)) { 
				return msId; 
			} 
			SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, parameterType); 
			newSelectMappedStatement(msId, sqlSource, Map.class); 
			return msId; 
		} 
 
		private String select(String sql, Class<?> resultType) { 
			String msId = newMsId(resultType + sql, SqlCommandType.SELECT); 
			if (hasMappedStatement(msId)) { 
				return msId; 
			} 
			StaticSqlSource sqlSource = new StaticSqlSource(configuration, sql); 
			newSelectMappedStatement(msId, sqlSource, resultType); 
			return msId; 
		} 
 
		private String selectDynamic(String sql, Class<?> parameterType, Class<?> resultType) { 
			String msId = newMsId(resultType + sql + parameterType, SqlCommandType.SELECT); 
			if (hasMappedStatement(msId)) { 
				return msId; 
			} 
			SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, parameterType); 
			newSelectMappedStatement(msId, sqlSource, resultType); 
			return msId; 
		} 
 
		private String insert(String sql) { 
			String msId = newMsId(sql, SqlCommandType.INSERT); 
			if (hasMappedStatement(msId)) { 
				return msId; 
			} 
			StaticSqlSource sqlSource = new StaticSqlSource(configuration, sql); 
			newUpdateMappedStatement(msId, sqlSource, SqlCommandType.INSERT); 
			return msId; 
		} 
 
		private String insertDynamic(String sql, Class<?> parameterType) { 
			String msId = newMsId(sql + parameterType, SqlCommandType.INSERT); 
			if (hasMappedStatement(msId)) { 
				return msId; 
			} 
			SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, parameterType); 
			newUpdateMappedStatement(msId, sqlSource, SqlCommandType.INSERT); 
			return msId; 
		} 
 
		private String update(String sql) { 
			String msId = newMsId(sql, SqlCommandType.UPDATE); 
			if (hasMappedStatement(msId)) { 
				return msId; 
			} 
			StaticSqlSource sqlSource = new StaticSqlSource(configuration, sql); 
			newUpdateMappedStatement(msId, sqlSource, SqlCommandType.UPDATE); 
			return msId; 
		} 
 
		private String updateDynamic(String sql, Class<?> parameterType) { 
			String msId = newMsId(sql + parameterType, SqlCommandType.UPDATE); 
			if (hasMappedStatement(msId)) { 
				return msId; 
			} 
			SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, parameterType); 
			newUpdateMappedStatement(msId, sqlSource, SqlCommandType.UPDATE); 
			return msId; 
		} 
 
		private String delete(String sql) { 
			String msId = newMsId(sql, SqlCommandType.DELETE); 
			if (hasMappedStatement(msId)) { 
				return msId; 
			} 
			StaticSqlSource sqlSource = new StaticSqlSource(configuration, sql); 
			newUpdateMappedStatement(msId, sqlSource, SqlCommandType.DELETE); 
			return msId; 
		} 
 
		private String deleteDynamic(String sql, Class<?> parameterType) { 
			String msId = newMsId(sql + parameterType, SqlCommandType.DELETE); 
			if (hasMappedStatement(msId)) { 
				return msId; 
			} 
			SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, parameterType); 
			newUpdateMappedStatement(msId, sqlSource, SqlCommandType.DELETE); 
			return msId; 
		} 
	} 
 
} 

通过配置文件实列化改SQL执行器:

import java.util.Properties; 
 
import org.apache.ibatis.session.SqlSessionFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
 
import com.***.SQLActuator; 
import com.github.pagehelper.PageHelper; 
 
@Configuration 
public class MyBatisConfig { 
	@Autowired 
	private SqlSessionFactory factory; 
	 
	/** 
	 * 分页对象实列化 
	 * @return 
	 */ 
	@Bean 
	public PageHelper pageHelper() { 
		PageHelper pageHelper = new PageHelper(); 
		Properties p = new Properties(); 
		p.setProperty("offsetAsPageNum", "true"); 
		p.setProperty("rowBoundsWithCount", "true"); 
		p.setProperty("reasonable", "true"); 
		p.setProperty("dialect", "mysql"); 
		pageHelper.setProperties(p); 
		return pageHelper; 
	} 
	 
	/** 
	 * 数据库执行SQL执行对象 
	 */ 
	@Bean 
	public SQLActuator getMapper(){ 
		SQLActuator mapper = new SQLActuator(factory); 
		return mapper; 
	} 
	 
}

 

标签:Spring Boot
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号