基于Mybatis+Druid实现执行SQL功能

        Mybatis是Java持久层的框架,支持 SQL查询,存储过程和高级映射等功能。Druid是Java的管理数据库连接池和监控数据库的工具。使用Mybatis+Druid就可以轻松实现任意SQL语句的执行功能。

        Mybatis在实现执行SQL功能中的作用是:执行SQL,封装返回结果。Druid在实现执行SQL功能中的作用是:校验SQL语法和查询类SQL添加limit限制。下面将从代码角度说明:

        1. 执行SQL入口(SqlExecuteController):

/**
 * 〈一句话功能简述〉
* 〈〉 * * @author hanxiaozhang * @create 2023/6/14 * @since 1.0.0 */ @Controller @RequestMapping("/sql") public class SqlExecuteController { @Autowired private SqlExecuteService sqlExecuteService; @PostMapping("/execute") @ResponseBody public R execute(String sql) { String result = null; try { result = sqlExecuteService.execute(sql); } catch (Exception e) { return R.error(e.getMessage()); } return R.ok(result); } }

            2. 执行SQL服务(SqlExecuteService):

/**
 * 〈一句话功能简述〉
* 〈执行Sql服务,基于Mybatis+使用Druid〉 * * @author hanxiaozhang * @create 2023/6/14 * @since 1.0.0 */ @Slf4j @Service public class SqlExecuteService { private static final int DEFAULT_LIMIT = 1000; @Resource private SqlExecuteDao sqlExecuteDao; @Autowired private DataSourceProperties dataSourceProperties; /** * 执行 *

* Tips: * 1. 可以增加权限校验。 * 2. 支持数据备份。 * * @param sql * @return */ @Override public String execute(String sql) { String result = null; // 校验SQL语法 SQLStatement statement = checkSyntax(sql); try { if (statement instanceof SQLInsertStatement) { result = String.valueOf(sqlExecuteDao.insert(sql)); } if (statement instanceof SQLDeleteStatement) { result = String.valueOf(sqlExecuteDao.delete(sql)); } if (statement instanceof SQLSelectStatement) { setQueryLimit((SQLSelectStatement) statement, DEFAULT_LIMIT); List> list = sqlExecuteDao.select(SQLUtils.toMySqlString(statement)); result = JSON.toJSONString(list); } if (statement instanceof SQLUpdateStatement) { result = String.valueOf(sqlExecuteDao.update(sql)); } } catch (Exception e) { log.error("执行Sql异常,异常信息:[{}]", e); throw new RuntimeException("执行Sql异常!"); } return result; } /** * 设置查询limit * * @param statement * @param limitNum */ private void setQueryLimit(SQLSelectStatement statement, Integer limitNum) { SQLSelectQuery query = statement.getSelect().getQuery(); if (query instanceof SQLSelectQueryBlock) { // 单表SQL查询(包括管理查询) SQLSelectQueryBlock select = (SQLSelectQueryBlock) query; if (select.getLimit() == null) { select.setLimit(new SQLLimit(new SQLIntegerExpr(limitNum))); } } else if (query instanceof SQLUnionQuery) { // 联合表SQL查询 SQLUnionQuery select = (SQLUnionQuery) query; if (select.getLimit() == null) { select.setLimit(new SQLLimit(new SQLIntegerExpr(limitNum))); } } } /** * 校验SQL语法 * * @param sql * @return */ private SQLStatement checkSyntax(String sql) { List sqlStatements = SQLUtils.parseStatements(sql, dataSourceProperties.getDriverClassName()); if (sqlStatements.size() > 1) { throw new ParserException("每次只允许执行一个sql语句!"); } SQLStatement statement = sqlStatements.get(0); return statement; } }

         3. 执行SQL数据持久层(SqlExecuteDao):

/**
 * 〈一句话功能简述〉
* 〈〉 * * @author hanxiaozhang * @create 2023/6/14 * @since 1.0.0 */ @Mapper public interface SqlExecuteDao { List getTables(); @MapKey("sql") List> select(@Param("sql") String sql); int update(@Param("sql") String sql); int delete(@Param("sql") String sql); int insert(@Param("sql") String sql); }

         4. 执行SQL数据持久层的xml(SqlExecuteMapper):





	

	

	
	    ${sql}
	

	
		${sql}
	

	
		${sql}
	



        最后,通过接口形式演示一下:

        1. 执行查询 SELECT * FROM sys_dict WHERE id =1;

基于Mybatis+Druid实现执行SQL功能_第1张图片

         2. 执行更新 update sys_dict SET name ='你不好' WHERE id =1;

基于Mybatis+Druid实现执行SQL功能_第2张图片

          3. 再次执行查询 SELECT * FROM sys_dict WHERE id =1;

基于Mybatis+Druid实现执行SQL功能_第3张图片

你可能感兴趣的:(mybatis,sql,oracle)