1. 程式人生 > 實用技巧 >mybatis 使用自定義sql 語句

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();
    }
}

如果實現 了 Interceptor 類進行SQL二次處理封裝,會報二次編譯的問題