在工作中,本人经常只是写一些基础的CRUD操作,干了小一年的时间感觉生活迷茫,那时候也经常看书但是实操的经验还是很少很多书本上学习到的知识点到现实中很难体现,后来就想这不能这样度日即开始了对一些开源框架的自我学习,把那些开源大佬的代码拉下来一行行的看,最后目标是实现自己的一些框架的编写就像mybatis-plus一样,内容很枯燥但…
本讲解的mybaits-plus版本即3.4.3.3版本,spring的版本2.5.3
实现一个基于接口的普通的Insert操作sql,且不进行添加xml操作想要实现这样的功能,即需要configuration中添加对应的MappedStatement,即我们的xml文件中的
即在自己的项目中根据mybatis-plus的包路径创建一个与他相同的java文件,然后把代码赋值即可,添加我们的功能
因为我们既要运行自己定义的mapper,需要依赖他提供的baseMapper接口
public interface baseMapper添加一个sql脚本extends Mapper { int insert(T entity); int deleteById(Serializable id); // ....... // 全部复制过来,然后在后面添加一个你自己定义的方法名称 // ======================================= // 即,不管我们entity属性添加说明字段,我们只让他添加name属性, int insertDefaultName(T entity); }
赋值过来添加一个即可,且method必须与baseMapper中的方法对应
这里的脚本写一个xml文件类似的,不过对应的表名,字段名,和属性值都是%S可以用java代码进行填充
public enum SqlMethod {
INSERT_DEFAULT("insertDefaultName", "插入一条数据(选择字段插入)", "");
}
添加一个AbstractMethod的继承类
这个类似我们在xml文件中添加一个
// 必须继承AbstractMethod,基础类中有一些添加MapperdStatement的方法,最主要的还是传入了一个MapperBuilderAssistant
public class InsertDefaultName extends AbstractMethod {
public InsertDefaultName() {
}
// 具体实现的逻辑,这里回被创建DefaultSqlInjector时创建
public MappedStatement injectMappedStatement(Class> mapperClass, Class> modelClass, TableInfo tableInfo) {
KeyGenerator keyGenerator = NoKeyGenerator.INSTANCE;
// 前面定义的脚本
SqlMethod sqlMethod = SqlMethod.INSERT_DEFAULT;
// 定义属性名称
String columnscript = "(`name`)";
// 定义属性值,这个的属性值就和我们写xml一样通过mybatis获取我们写上对应的语法即可
String valuesscript = "(#{name})";
// 获取主键信息,这里就先不将大致的意思即获取我们POJO类中的id属性,然后获取到他的属性名称,和数据库名称(可能是驼峰命名的)
String keyProperty = null;
String keyColumn = null;
if (StringUtils.isNotBlank(tableInfo.getKeyProperty())) {
if (tableInfo.getIdType() == IdType.AUTO) {
keyGenerator = Jdbc3KeyGenerator.INSTANCE;
keyProperty = tableInfo.getKeyProperty();
keyColumn = tableInfo.getKeyColumn();
} else if (null != tableInfo.getKeySequence()) {
keyGenerator = TableInfoHelper.genKeyGenerator(this.getMethod(sqlMethod), tableInfo, this.builderAssistant);
keyProperty = tableInfo.getKeyProperty();
keyColumn = tableInfo.getKeyColumn();
}
}
//======================================
// 这里通过 %s进行填充数据,填充表名,属性名,属性值
String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), columnscript, valuesscript);
// 通过语言驱动解析,这里就mybatis部分
SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
// 调用抽象类方法来添加一个我们创建的mappedStatment
return this.addInsertMappedStatement(mapperClass, modelClass, this.getMethod(sqlMethod), sqlSource, (KeyGenerator)keyGenerator, keyProperty, keyColumn);
}
}
覆盖DefaultSqlInjector类添加一个自定义的MapperStatement
具体的了解这里不详情讲,因为这里面覆盖的内容还是很多就,大致的意思类似将我们xml中的insert,update,select语句加载到配置类中,注意: 这里是假设说是xml实际上并没有真正使用xml还是用java代码写的
注意,我们在添加时将我们自定义的一个InsertDefaultName添加进去了,没有添加的话则没有对应的功能,在baseMapper中定义了也不启作用
public class DefaultSqlInjector extends AbstractSqlInjector {
public DefaultSqlInjector() {
}
public List getMethodList(Class> mapperClass, TableInfo tableInfo) {
// 查看我们的POJO类是否有那个主键使用了@Id注解,如果有的话添加下面的insert...,否则的话添加下面的没有id的insert....等等的方法
// 主要的区别,几个根据id操作的方法
if (tableInfo.havePK()) {
return (List)Stream.of(new Insert(), new Delete(), new DeleteByMap(), new DeleteById(), new DeleteBatchByIds(), new Update(), new UpdateById(), new SelectById(), new SelectBatchByIds(), new SelectByMap(), new SelectCount(), new SelectMaps(), new SelectMapsPage(), new SelectObjs(), new SelectList(), new SelectPage(),new InsertDefaultName()).collect(Collectors.toList());
} else {
this.logger.warn(String.format("%s ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.", tableInfo.getEntityType()));
return (List)Stream.of(new Insert(), new Delete(), new DeleteByMap(), new Update(), new SelectByMap(), new SelectCount(), new SelectMaps(), new SelectMapsPage(), new SelectObjs(), new SelectList(), new SelectPage()).collect(Collectors.toList());
}
}
}
使用
然后即可使用了,和我们平常怎么使用就怎么使用
源码分析


