# commons-flake **Repository Path**: seaboot/flake ## Basic Information - **Project Name**: commons-flake - **Description**: 如果说,可以将mybatis的配置放在任何你所希望的地方,你能想到什么? 这一套代码,允许程序员自己组织代码逻辑,按照自己的想法,设计数据库映射配置。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2022-02-10 - **Last Updated**: 2026-07-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: JDBC ## README ## seaboot-flack mybatis,但允许动态配置数据库映射 #### 设计背景 制作报表系统的时候,经常会有一个很头疼的事情: 明明只是写一个 SQL 的事情,但是系统各种配置,客户用不明白,时间久了,我们自己忘得差不多; 这时候,我们就会去思考:要不直接开放写 SQL 的权限? 客户想怎么查怎么查,自己写 SQL 去,我们将工作重心放到数据权限上就好了。 #### 调用 mybatis 原有的功能 如果期望完全由 mybatis 实现,不引入其它逻辑,可以用这种写法。 * 优点:完全通过 mybatis 实现,没什么维护负担; * 缺点:改完 xml,需要重新载入配置,修改成本较高; ```java /** * @author Mr.css * @version 2021-01-13 17:40 */ public class TestScanner { public static void main(String[] args) throws IOException { MyBatisConfiguration configuration = new MyBatisConfiguration(); String file = "D:\\seaboot\\seaboot\\mybatis-proxy\\src\\main\\resources\\mappe\\sys_menu.xml"; try(InputStream is = IOUtils.openFileInputStream(file)){ configuration.resolve("sys_menu", is); } MappedStatement statement = configuration.getMappedStatement("cn.seaboot.db.test.dao.MenuDao.selectById"); // 构建参数 Map params = new HashMap<>(); params.put("menuLevel", "3"); params.put("pid", "1"); params.put("path", "2"); // 获取渲染的 SQL BoundSql sql = statement.getBoundSql(params); System.out.println(sql.getSql()); System.out.println(sql.getParameterMappings()); System.out.println(statement.getResultMaps().get(0).getResultMappings()); } } ``` #### 仿 mybatis 实现 模仿 mybatis 渲染 sql 语句的方式,自己编码实现。 * 优点:提供了默认功能,可以按照需求重写接口,咋实现都成; * 缺点:代码需要自己维护; ```java public class Example { public static void main(String[] args) { SqlHelper help = new SqlHelper(); // 目前删除了默认实现,需要继承 FlakeTemplate 写一个 sql 模板解析工具 FlakeTemplate template = null; help.setTemplate(template); // 比如使用 beetl 模板引擎, String sql = "select * from table where id = #{id} " + "<% if(name != null && name != ''){%> and name = #{name} <%}%>" + "<% if(age >= 18){%> and age > #{age} <%}%>"; // 参数 Map params = new HashMap<>(); params.put("id", "1"); params.put("name", null); params.put("age", 18); PreparedSql ret = help.process(sql, params); System.out.println(ret); // 执行结果: // SQL ===>: select * from table where id = ? and age > ? // Parameters ===>: [1, 18] } } ``` #### 表结构分析 表结构分析,解析建表语句,将信息存入对象(目前支持 mysql)。 表结构分析结果,可以提供给AI,用于生成代码,当然,当前库也一些简单实现。 ```java /** * 从建表语句中获取表结构参数 */ public class GenerateCode { public static void main(String[] args) throws JSQLParserException, IOException { CreateTableParser parser = new CreateTableParser(); NormToMappingConverter converter = new NormToMappingConverter(); String sql = "CREATE TABLE `t_dev_subject_msg` (\n" + " `id` bigint DEFAULT NULL COMMENT 'ID',\n" + " `subject_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '边坡ID',\n" + " `video_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '设备ID',\n" + " `msg_type` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '消息类型',\n" + " `gmt_create` datetime DEFAULT NULL COMMENT '发送日期'\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8;"; NormTable normTable = parser.parse(sql); MappingTable mappingTable = converter.normTableToMappingTable(normTable); // 获取表结构信息 String json = FastJsonUtils.toJSONString(mappingTable); File out = new File("D:\\reverse\\" + normTable.getTableName() + ".json"); FileUtils.writeString(out, json, Charset.defaultCharset()); System.out.println(json); // 生成代码 Template template = new TypeScript(); System.out.println(template.process(mappingTable)); } } ``` #### 实现原理 参考了 mybatis 的实现方式: 1. 首先,处理SQL模版中的逻辑运算(if语句等),渲染出基本的SQL语句; 2. 然后,替换语句中的所有#{}占位符; 3. 最后,通过JDBC执行解析好的查询语句。 基本实现逻辑: 1. JDBC 部分,使用 JdbcTemplate; 2. SQL 渲染部分通过模版引擎实现,允许替换成自己喜欢的; 3. ${} 是通过模版引擎实现,会被直接替换到 SQL 模版中; 4. #{} 会被问号替换,这一部分通过分词器实现,同样允许自定义实现。 #### 版本 1. 2022-02-10:项目启动; 2. 2022-02-20:代码版本1.0; 3. 2022-02-28:增减表单/查询页面数据配置; 4. 2022-10-27:增加大量代码注释,优化API,代码更容易理解; 5. 2024-05-13:引入 beetl,语法用起来会更加舒服一些; 6. 2025-05-21:删除多余设计,保留最核心的功能;