mybatis 使用自定义sql 语句
Posted 曾经是最好
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis 使用自定义sql 语句相关的知识,希望对你有一定的参考价值。
新建一个接口 SqlBaseMapper 封装常用的增删改查
public interface SqlBaseMapper { /** * 查询单条数据返回Map<String, Object> * * @param sql sql语句 * @return Map<String, Object> */ Map<String, Object> sqlSelectOne(String sql); /** * 查询单条数据返回Map<String, Object> * * @param sql sql语句 * @param value 参数 * @return Map<String, Object> */ Map<String, Object> sqlSelectOne(String sql, Object value); /** * 查询单条数据返回实体类型 * * @param sql sql语句 * @param resultType 具体类型 * @return 定义的实体类型 */ <T> T sqlSelectOne(String sql, Class<T> resultType); /** * 查询单条数据返回实体类型 * * @param sql sql语句 * @param value 参数 * @param resultType 具体类型 * @return 定义的实体类型 */ <T> T sqlSelectOne(String sql, Object value, Class<T> resultType); /** * 查询数据返回 * * @param sql sql语句 * @return List<Map < String, Object>> */ List<Map<String, Object>> sqlSelectList(String sql); /** * 查询数据返回 * * @param sql sql语句 * @param value 参数 * @return List<Map < String, Object>> */ List<Map<String, Object>> sqlSelectList(String sql, Object value); /** * 查询数据返回 * * @param sql sql语句 * @param resultType 具体类型 * @return List<T> */ <T> List<T> sqlSelectList(String sql, Class<T> resultType); /** * 查询数据返回 * * @param sql sql语句 * @param value 参数 * @param resultType 具体类型 * @return List<T> */ <T> List<T> sqlSelectList(String sql, Object value, Class<T> resultType); /** * 插入数据 * * @param sql sql语句 * @return int */ int sqlInsert(String sql); /** * 插入数据 * * @param sql sql语句 * @param value 参数 * @return int */ int sqlInsert(String sql, Object value); /** * 更新数据 * * @param sql sql语句 * @return int */ int sqlUpdate(String sql); /** * 更新数据 * * @param sql sql语句 * @param value 参数 * @return int */ int sqlUpdate(String sql, Object value); /** * 删除数据 * * @param sql sql语句 * @return int */ int sqlDelete(String sql); /** * 查询数据返回List<T> * * @param sql sql语句 * @param value 参数 * @return int */ int sqlDelete(String sql, Object value); }
新建一个SqlMapper 实现SqlBaseMapper接口
/** * @author chaild * @Date 2020-7-7 14:43:35 * 自定义SQL查询类 */ @Component public class SqlMapper implements SqlBaseMapper { /** * 使用方式 * * @Autowired private SqlMapper sqlMapper; */ private SqlSession sqlSession; private SqlMapper.MSUtils msUtils; @Autowired SqlSessionFactory sqlSessionFactory; public SqlMapper() { }
/**这个注解具体意思可以自己去了解一下**/ @PostConstruct private void init() { this.sqlSession = sqlSessionFactory.openSession(true); this.msUtils = new SqlMapper.MSUtils(sqlSession.getConfiguration()); } 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; } } /** * 查询单条数据返回Map<String, Object> * * @param sql sql语句 * @return Map<String, Object> */ @Override public Map<String, Object> sqlSelectOne(String sql) { List<Map<String, Object>> list = this.sqlSelectList(sql); return (Map) this.getOne(list); } /** * 查询单条数据返回Map<String, Object> * * @param sql sql语句 * @param value 参数 * @return Map<String, Object> */ @Override public Map<String, Object> sqlSelectOne(String sql, Object value) { List<Map<String, Object>> list = this.sqlSelectList(sql, value); return (Map) this.getOne(list); } /** * 查询单条数据返回实体类型 * * @param sql sql语句 * @param resultType 具体类型 * @return 定义的实体类型 */ @Override public <T> T sqlSelectOne(String sql, Class<T> resultType) { List<T> list = this.sqlSelectList(sql, resultType); return this.getOne(list); } /** * 查询单条数据返回实体类型 * * @param sql sql语句 * @param value 参数 * @param resultType 具体类型 * @return 定义的实体类型 */ @Override public <T> T sqlSelectOne(String sql, Object value, Class<T> resultType) { List<T> list = this.sqlSelectList(sql, value, resultType); return this.getOne(list); } /** * 查询数据返回 * * @param sql sql语句 * @return List<Map < String, Object>> */ @Override public List<Map<String, Object>> sqlSelectList(String sql) { String msId = this.msUtils.select(sql); return this.sqlSession.selectList(msId); } /** * 查询数据返回 * * @param sql sql语句 * @param value 参数 * @return List<Map < String, Object>> */ @Override public List<Map<String, Object>> sqlSelectList(String sql, Object value) { Class<?> parameterType = value != null ? value.getClass() : null; String msId = this.msUtils.selectDynamic(sql, parameterType); return this.sqlSession.selectList(msId, value); } /** * 查询数据返回 * * @param sql sql语句 * @param resultType 具体类型 * @return List<T> */ @Override public <T> List<T> sqlSelectList(String sql, Class<T> resultType) { String msId; if (resultType == null) { msId = this.msUtils.select(sql); } else { msId = this.msUtils.select(sql, resultType); } return this.sqlSession.selectList(msId); } /** * 查询数据返回 * * @param sql sql语句 * @param value 参数 * @param resultType 具体类型 * @return List<T> */ @Override public <T> List<T> sqlSelectList(String sql, Object value, Class<T> resultType) { Class<?> parameterType = value != null ? value.getClass() : null; String msId; if (resultType == null) { msId = this.msUtils.selectDynamic(sql, parameterType); } else { msId = this.msUtils.selectDynamic(sql, parameterType, resultType); } return this.sqlSession.selectList(msId, value); } /** * 插入数据 * * @param sql sql语句 * @return int */ @Override public int sqlInsert(String sql) { String msId = this.msUtils.insert(sql); return this.sqlSession.insert(msId); } /** * 插入数据 * * @param sql sql语句 * @param value 参数 * @return int */ @Override public int sqlInsert(String sql, Object value) { Class<?> parameterType = value != null ? value.getClass() : null; String msId = this.msUtils.insertDynamic(sql, parameterType); return this.sqlSession.insert(msId, value); } /** * 更新数据 * * @param sql sql语句 * @return int */ @Override public int sqlUpdate(String sql) { String msId = this.msUtils.update(sql); return this.sqlSession.update(msId); } /** * 更新数据 * * @param sql sql语句 * @param value 参数 * @return int */ @Override public int sqlUpdate(String sql, Object value) { Class<?> parameterType = value != null ? value.getClass() : null; String msId = this.msUtils.updateDynamic(sql, parameterType); return this.sqlSession.update(msId, value); } /** * 删除数据 * * @param sql sql语句 * @return int */ @Override public int sqlDelete(String sql) { String msId = this.msUtils.delete(sql); return this.sqlSession.delete(msId); } /** * 查询数据返回List<T> * * @param sql sql语句 * @param value 参数 * @return int */ @Override public int sqlDelete(String sql, Object value) { Class<?> parameterType = value != null ? value.getClass() : null; String msId = this.msUtils.deleteDynamic(sql, parameterType); return this.sqlSession.delete(msId, value); } /** * 进行预编译 */ private class MSUtils { private Configuration configuration; private LanguageDriver languageDriver; private MSUtils(Configuration configuration) { this.configuration = configuration; this.languageDriver = configuration.getDefaultScriptingLanguageInstance(); } private String newMsId(String sql, SqlCommandType sqlCommandType) { StringBuilder msIdBuilder = new StringBuilder(sqlCommandType.toString()); msIdBuilder.append(".").append(sql.hashCode()); return msIdBuilder.toString(); } private boolean hasMappedStatement(String msId) { return this.configuration.hasStatement(msId, false); } private void newSelectMappedStatement(String msId, SqlSource sqlSource, final Class<?> resultType) { MappedStatement ms = (new MappedStatement.Builder(this.configuration, msId, sqlSource, SqlCommandType.SELECT)).resultMaps(new ArrayList<ResultMap>() { { this.add((new org.apache.ibatis.mapping.ResultMap.Builder(com.culturalCenter.placeManage.mapper.SqlMapper.MSUtils.this.configuration, "defaultResultMap", resultType, new ArrayList(0))).build()); } }).build(); this.configuration.addMappedStatement(ms); } private void newUpdateMappedStatement(String msId, SqlSource sqlSource, SqlCommandType sqlCommandType) { MappedStatement ms = (new MappedStatement.Builder(this.configuration, msId, sqlSource, sqlCommandType)).resultMaps(new ArrayList<ResultMap>() { { this.add((new org.apache.ibatis.mapping.ResultMap.Builder(com.culturalCenter.placeManage.mapper.SqlMapper.MSUtils.this.configuration, "defaultResultMap", Integer.TYPE, new ArrayList(0))).build()); } }).build(); this.configuration.addMappedStatement(ms); } private String select(String sql) { String msId = this.newMsId(sql, SqlCommandType.SELECT); if (this.hasMappedStatement(msId)) { return msId; } else { StaticSqlSource sqlSource = new StaticSqlSource(this.configuration, sql); this.newSelectMappedStatement(msId, sqlSource, Map.class); return msId; } } private String selectDynamic(String sql, Class<?> parameterType) { String msId = this.newMsId(sql + parameterType, SqlCommandType.SELECT); if (this.hasMappedStatement(msId)) { return msId; } else { SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, parameterType); this.newSelectMappedStatement(msId, sqlSource, Map.class); return msId; } } private String select(String sql, Class<?> resultType) { String msId = this.newMsId(resultType + sql, SqlCommandType.SELECT); if (this.hasMappedStatement(msId)) { return msId; } else { StaticSqlSource sqlSource = new StaticSqlSource(this.configuration, sql); this.newSelectMappedStatement(msId, sqlSource, resultType); return msId; } } private String selectDynamic(String sql, Class<?> parameterType, Class<?> resultType) { String msId = this.newMsId(resultType + sql + parameterType, SqlCommandType.SELECT); if (this.hasMappedStatement(msId)) { return msId; } else { SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, parameterType); this.newSelectMappedStatement(msId, sqlSource, resultType); return msId; } } private String insert(String sql) { String msId = this.newMsId(sql, SqlCommandType.INSERT); if (this.hasMappedStatement(msId)) { return msId; } else { StaticSqlSource sqlSource = new StaticSqlSource(this.configuration, sql); this.newUpdateMappedStatement(msId, sqlSource, SqlCommandType.INSERT); return msId; } } private String insertDynamic(String sql, Class<?> parameterType) { String msId = this.newMsId(sql + parameterType, SqlCommandType.INSERT); if (this.hasMappedStatement(msId)) { return msId; } else { SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, parameterType); this.newUpdateMappedStatement(msId, sqlSource, SqlCommandType.INSERT); return msId; } } private String update(String sql) { String msId = this.newMsId(sql, SqlCommandType.UPDATE); if (this.hasMappedStatement(msId)) { return msId; } else { StaticSqlSource sqlSource = new StaticSqlSource(this.configuration, sql); this.newUpdateMappedStatement(msId, sqlSource, SqlCommandType.UPDATE); return msId; } } private String updateDynamic(String sql, Class<?> parameterType) { String msId = this.newMsId(sql + parameterType, SqlCommandType.UPDATE); if (this.hasMappedStatement(msId)) { return msId; } else { SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, parameterType); this.newUpdateMappedStatement(msId, sqlSource, SqlCommandType.UPDATE); return msId; } } private String delete(String sql) { String msId = this.newMsId(sql, SqlCommandType.DELETE); if (this.hasMappedStatement(msId)) { return msId; } else { StaticSqlSource sqlSource = new StaticSqlSource(this.configuration, sql); this.newUpdateMappedStatement(msId, sqlSource, SqlCommandType.DELETE); return msId; } } private String deleteDynamic(String sql, Class<?> parameterType) { String msId = this.newMsId(sql + parameterType, SqlCommandType.DELETE); if (this.hasMappedStatement(msId)) { return msId; } else { SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, parameterType); this.newUpdateMappedStatement(msId, sqlSource, SqlCommandType.DELETE); return msId; } } } }
然后做一个 数据连接工厂类
SqlSessionFactoryConfig
/** * @author chaild * @Date 2020年6月23日18:25:22 * 创建SQL连接工厂类 * */ @Configuration public class SqlSessionFactoryConfig { @javax.annotation.Resource DruidDataSource dataSource; @Bean @Primary public SqlSessionFactory sqlSessionFactory() throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource);//更多参数请自行注入 bean.setPlugins(new Interceptor[]{new SqlInterceptor()}); Resource[] resources = new PathMatchingResourcePatternResolver() .getResources("classpath*:mapper/*.xml"); bean.setMapperLocations(resources); return bean.getObject(); } }
使用示例:
@Autowired private SqlMapper sqlMapper; ###selectList //查询,返回List<Map> List<Map<String, Object>> list = sqlMapper.selectList("select * from country where id < 11"); //查询,返回指定的实体类 List<Country> countryList = sqlMapper.selectList("select * from country where id < 11", Country.class); //查询,带参数 countryList = sqlMapper.selectList("select * from country where id < #{id}", 11, Country.class); //复杂点的查询,这里参数和上面不同的地方,在于传入了一个对象 Country country = new Country(); country.setId(11); countryList = sqlMapper.selectList("<script>" + "select * from country " + " <where>" + " <if test="id != null">" + " id < #{id}" + " </if>" + " </where>" + "</script>", country, Country.class); ##复杂查询使用map传入参数 Map<String,String> map=new HashMap<>(); map.put("id","21321312312312312"); map.put("status","1"); sqlMapper.sqlSelectList("select * from tb_admin where id=#{id} and status=#{status}",map,Admin.class); ###selectOne 查询单条数据 Map<String, Object> map = sqlMapper.selectOne("select * from country where id = 35"); map = sqlMapper.selectOne("select * from country where id = #{id}", 35); Country country = sqlMapper.selectOne("select * from country where id = 35", Country.class); country = sqlMapper.selectOne("select * from country where id = #{id}", 35, Country.class); ###insert,update,delete ###insert 插入数据 int result = sqlMapper.insert("insert into country values(1921,‘天朝‘,‘TC‘)"); Country tc = new Country(); tc.setId(1921); tc.setCountryname("天朝"); tc.setCountrycode("TC"); //注意这里的countrycode和countryname故意写反的 result = sqlMapper.insert("insert into country values(#{id},#{countrycode},#{countryname})" , tc); ###update 更新使用 result = sqlMapper.update("update country set countryname = ‘天朝‘ where id = 35"); tc = new Country(); tc.setId(35); tc.setCountryname("天朝"); int result = sqlMapper.update("update country set countryname = #{countryname}" + " where id in(select id from country where countryname like ‘A%‘)", tc); ##delete 删除使用 result = sqlMapper.delete("delete from country where id = 35"); result = sqlMapper.delete("delete from country where id = #{id}", 35);
如果实现 了 Interceptor 类进行SQL二次处理封装,会报二次编译的问题
以上是关于mybatis 使用自定义sql 语句的主要内容,如果未能解决你的问题,请参考以下文章
[mybatis]动态sql_sql_抽取可重用的sql片段
MYBATIS05_ifwherechoosewhentrimsetforEach标签sql片段
springboot2.x+MyBatis-Plus+mysql5.7 动态拼接sql语句 分页查询 自定义sql 查询条件 分组 排序
springboot2.x+MyBatis-Plus+mysql5.7 动态拼接sql语句 分页查询 自定义sql 查询条件 分组 排序