# swift-mybatis **Repository Path**: JayEinstein/swift-mybatis ## Basic Information - **Project Name**: swift-mybatis - **Description**: 一种非XML的mybatis实现方案的探索 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2022-04-22 - **Last Updated**: 2022-07-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Swift - Mybatis ### 前言 由于最近一段时间在项目开发上是使用的是别的DAO开发工具,让我对Mybatis的XML和注解的开发方式感到是如此的熟悉又陌生, 于是我想到了对Mybatis进行一些扩展和改造。 ### 简介 依赖于mybatis-spring,不修改原来的代码,以新增自定义SqlSession和切面的方式在Mybatis上进行拓展。 项目没有经过大规模测试,这里只抛个砖头,用于相互学习,不建议生产直接使用。 ### 跑步入门 安装swift-mybatis-core项目,在springboot中引入依赖 ```xml jay.einstein swift-mybatis-core 1.0-SNAPSHOT ``` 定义一个接口 DemoSwiftMapper ```java public interface DemoSwiftMapper { void execData(); } ``` 然后定义接口实现类 DemoSwiftMapperImpl, 实现类打上@SqlSessionContext注解,便会交由SqlSessionContextAdvisor增强管理, 再注入SqlHolder ```java // 必须打上注解 @SqlSessionContext public class DemoSwiftMapperImpl implements DemoSwiftMapper { /** * 操作DAO */ @Autowired private SqlHolder sqlHolder; @Override public void execData() { // 查询单个 Student student = sqlHolder.selectOne("select * from student limit 1", Student.class); // 查询list List studentList = sqlHolder.selectList("select * from student", Student.class); // 新增 sqlHolder.insert("insert into student (stu_name, stu_age) values(#{arg0}, #{arg1})", "小明", "18"); // 更新 sqlHolder.update("update student set stu_age = #{arg0} where code = #{arg1}", "20", "小明"); } } ``` ### 简单演示 swift-mybatis-test测试工程下,application.yml配置好数据库连接。 jay.einstein.test.swift.mybatis.controller.TestController ```java @GetMapping("/get") public Object get() { StringJoiner joiner = new StringJoiner("
"); // 初始化脚本 studentSwiftMapper.initData(); // 清理干扰数据 int clearData = studentSwiftMapper.clearData(); System.out.println(clearData); // mybatis 执行用例 execMybatis(joiner); joiner.add("


"); // swiftMybatis 执行用例 execSwiftMybatis(joiner); return joiner.toString(); } ``` 访问接口 *http://localhost:8082/ndx/get* 接口返回结果 ```html mybatis ===== begin ===== 新增数据 => Student[stu=null, code=mybatis, stuName=xx, stuSex=xx, stuAge=0] 新增结果 => 1 查询code [mybatis] => Student[stu=6, code=mybatis, stuName=xx, stuSex=xx, stuAge=0] 更新编码code [mybatis] => Student[stu=null, code=mybatis, stuName=新名字, stuSex=男, stuAge=18] 更新结果 => 1 查询code [mybatis] => Student[stu=6, code=mybatis, stuName=新名字, stuSex=男, stuAge=18] mybatis ===== end ===== swift mybatis ===== begin ===== 新增数据 => Student[stu=null, code=swift mybatis, stuName=xx, stuSex=xx, stuAge=0] 新增结果 => 1 查询code [swift mybatis] => Student[stu=7, code=swift mybatis, stuName=xx, stuSex=xx, stuAge=0] 更新编码code [swift mybatis] => Student[stu=null, code=swift mybatis, stuName=新名字, stuSex=男, stuAge=18] 更新结果 => 1 查询code [swift mybatis] => Student[stu=7, code=swift mybatis, stuName=新名字, stuSex=男, stuAge=18] swift mybatis ===== end ===== ``` mybatis 执行用例方法 ```java private void execMybatis(StringJoiner joiner) { joiner.add("mybatis ===== begin ===== "); String code = "mybatis"; // insert Student insert = new Student(); insert.setCode(code); insert.setStuName("xx"); insert.setStuAge("0"); insert.setStuSex("xx"); joiner.add(String.format("新增数据 => %s", insert)); int iRet = studentMapper.insertStudent(insert); joiner.add(String.format("新增结果 => %s", iRet)); // get Student get1 = studentMapper.getStudentByCode(code); joiner.add(String.format("查询code [%s] => %s", code, get1)); joiner.add("
"); // update Student update = new Student(); update.setCode(code); update.setStuName("新名字"); update.setStuAge("18"); update.setStuSex("男"); joiner.add(String.format("更新编码code [%s] => %s", code, update)); int uRet = studentMapper.updateByCode(update); joiner.add(String.format("更新结果 => %s", uRet)); // get Student get2 = studentMapper.getStudentByCode(code); joiner.add(String.format("查询code [%s] => %s", code, get2)); joiner.add("mybatis ===== end ===== "); } ``` StudentMapper 用例相关方法 ```java public interface StudentMapper { @Select("select * from student where code = #{code} limit 1") Student getStudentByCode(@Param("code") String code); @Insert("insert into student (stu_name, code, stu_sex, stu_age) values(#{stu.stuName}, #{stu.code}, #{stu.stuSex}, #{stu.stuAge})") int insertStudent(@Param("stu") Student stu); @Update("update student set stu_name = #{stu.stuName}, stu_sex = #{stu.stuSex}, stu_age = #{stu.stuAge} where code = #{stu.code}") int updateByCode(@Param("stu") Student stu); } ``` swiftMybatis 执行用例方法 ```java public void execSwiftMybatis(StringJoiner joiner) { joiner.add("swift mybatis ===== begin ===== "); String code = "swift mybatis"; // insert Student insert = new Student(); insert.setCode(code); insert.setStuName("xx"); insert.setStuAge("0"); insert.setStuSex("xx"); joiner.add(String.format("新增数据 => %s", insert)); int iRet = studentSwiftMapper.insertStudent(insert); joiner.add(String.format("新增结果 => %s", iRet)); // get Student get1 = studentSwiftMapper.getStudentByCode(code); joiner.add(String.format("查询code [%s] => %s", code, get1)); joiner.add("
"); // update Student update = new Student(); update.setCode(code); update.setStuName("新名字"); update.setStuAge("18"); update.setStuSex("男"); joiner.add(String.format("更新编码code [%s] => %s", code, update)); int uRet = studentSwiftMapper.updateByCode(update); joiner.add(String.format("更新结果 => %s", uRet)); // get Student get2 = studentSwiftMapper.getStudentByCode(code); joiner.add(String.format("查询code [%s] => %s", code, get2)); joiner.add("swift mybatis ===== end ===== "); } ``` StudentSwiftMapper 用例相关方法 ```java @SqlSessionContext public class StudentSwiftMapperImpl implements StudentSwiftMapper { @Autowired private SqlHolder sqlHolder; @Override public Student getStudentByCode(String code) { return sqlHolder.selectOne("select * from student where code = #{arg0} limit 1", Student.class, code); } @Override public int insertStudent(Student stu) { return sqlHolder.update("insert into student (stu_name, code, stu_sex, stu_age) values(#{arg0}, #{arg1}, #{arg2}, #{arg3})", stu.getStuName(), stu.getCode(), stu.getStuSex(), stu.getStuAge()); } @Override public int updateByCode(Student stu) { return sqlHolder.update("update student set stu_name = #{arg0}, stu_sex = #{arg1}, stu_age = #{arg2} where code = #{arg3}", stu.getStuName(), stu.getStuSex(), stu.getStuAge(), stu.getCode()); } } ``` 相关初始脚本 ```sql CREATE TABLE IF NOT EXISTS `student` ( `stu_id` int(0) NOT NULL AUTO_INCREMENT, `code` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `stu_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `stu_sex` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `stu_age` int(0) NULL DEFAULT NULL, PRIMARY KEY (`stu_id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; INSERT INTO `student` (`stu_id`, `code`, `stu_name`, `stu_sex`, `stu_age`) SELECT 1, '1', '小明', '男', 20 FROM DUAL WHERE NOT EXISTS (SELECT stu_id FROM `student` WHERE `stu_id` = 1); INSERT INTO `student` (`stu_id`, `code`, `stu_name`, `stu_sex`, `stu_age`) SELECT 2, '2', '小花', '女', 19 FROM DUAL WHERE NOT EXISTS (SELECT stu_id FROM `student` WHERE `stu_id` = 2); INSERT INTO `student` (`stu_id`, `code`, `stu_name`, `stu_sex`, `stu_age`) SELECT 3, '3', '大赤', '男', 20 FROM DUAL WHERE NOT EXISTS (SELECT stu_id FROM `student` WHERE `stu_id` = 3); INSERT INTO `student` (`stu_id`, `code`, `stu_name`, `stu_sex`, `stu_age`) SELECT 4, '4', '可乐', '男', 19 FROM DUAL WHERE NOT EXISTS (SELECT stu_id FROM `student` WHERE `stu_id` = 4); INSERT INTO `student` (`stu_id`, `code`, `stu_name`, `stu_sex`, `stu_age`) SELECT 5, '5', '莹莹', '女', 19 FROM DUAL WHERE NOT EXISTS (SELECT stu_id FROM `student` WHERE `stu_id` = 5); ```