# 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);
```