一、基本注解
- 接口类继承BaseMapper
- @TableName(value=“表名”,resultMap="")
- @TableId(value=“idName”,type=AUTO)
主键列名和实体属性名相同可不写
主键生成策略
- idType.AUTO
- idType.INPUT
- idType.UUID
- idType.ID_WORKER(默认)
- @TableFieldId(value=“column_name”,exist=true)
二、方法与原理
-
CRUD
- insert()
- updateById()
- update(entity,wrapper)
- selectById()
- selectOne(T t) //多条件查询
- selectBatchIds(List ids) //id批量查询
- selectByMap(Map map) //数据库列名
- selectPage(rowBouds,wapper) //分页条件,操作类; 内存分页,非Limit物理分页(pageHapper或MP提供的插件实现);
- selectList
- deleteById()
- deleteByBatchIds(List ids)
- deleteByMap(Map map)
- delete(wrapper)
CRU会进行非空判断,update空字段不更新
-
自动注入CRUD原理
- xxxMapper在启动的时候已经把其中每个方法的sql语句都已经构造好,并保存在configuration对象的mappedStatement中
- xxxMapper本质 = org.apche.ibatis.binding.MapperProxy
- MapperProxy
- SqlSession
- SqlSessionFactory
- Confuguration
- MappedStatements
- MappedStatement
- SqlSource
- 获取sql语句
- 启动扫描生成sql语句和MappedStatement
- AutoSqlInjector
- SqlMethod //sql模板的enum对象
- TableInfo //数据库表的反射对象,获取表相关信息
- SqlSource //sql语句处理对象
- MapperBuilderAssistant //用于缓存,sql参数,结果集处理等
- MappedStatement 被生成并放在全局Confuguration中的mappedStatements中
-
条件构造器EntityWrapper
- 作用:sql拼接,排序,实体参数查询等
注:使用的是数据库字段,不是javabean属性 - eg:查询user表中姓名为包含安欣,年龄1-10或者性别女的所有用户,按年龄排序
userMapper.selectPage(new Page<User>(1,10), new EntityWrapper(User) .like("user_name","安欣") .andNew() // 比and多个()拼接 .eq("sex",1) .or() .between("age",1,10) .orderBy("age") .last("desc") //或者orderDesc(Arrays.asList(new String[] {"age"})) )
- 作用:sql拼接,排序,实体参数查询等
三、AR
- 描述:一个模型类对应一个表,类的一个实例对应一行记录
- 启用AR模式:让实体类继承model类并实现主键指定的抽象方法
public class User extends Model<User>{ @Override protected Serializable pkVal(){ return id; } }
- CRUD
User user = new User();
…- user.insert()
- user.updateById()
- selectById(8) //或者user.setId(8)
- selectAll()
- selectList(wrapper)
- selectCount(wrapper)
- deleteById() //删除空数据逻辑成功也返回true
- deleteByid(Serializable id)
- delete(wrapper)
- 分布复杂操作
- selectPage(page,wrapper) //返回page对象,page.getRecords();
四、代码生成器
- 描述
不仅可以生成实体类(是否支持AR)、dao,xml,还可以生成service、controller - 依赖
- 默认使用了Apache的Velocity模板引擎
<dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version></version> </dependency>
- 代码生成
- 全局配置
GlobalConfig config = new GlobalConfig; config.setActiveRecord(true); //是否支持AR模式 .setAuthor("安欣") .setOutputDir("C:\\projects\anxin\src\\main\\java") //生成路径 .setFileOverride(true) //文件覆盖 .setIdType(IdType.AUTO) //主键策略 .setServiceName("%sService") //Service接口名字首字母是否为I .setBaseResultMap(true) //映射结果集 .setBaseColumnList(true) //列集合sql片段
- 数据库配置
DataSourceConfig dbConfig = new DataSourceConfig(); dbConfig.setDbType(DbType.Mysql) .setDriverName("com.mysql.jdbc.Driver") .setUrl("jdbc:mysql://localhost:3306/anxin") .setUsername("root") .set("root")
- 策略配置
StrategyConfig stConfig = new StrategyConfig(); stConfig.setCapitalMode(true) //全局大写全名 .setDbColumnUnderline(true) //指定数据库中表名 字段名是否使用下划线 .setNaming(NamingStragy.underline_to_camel) //数据库表映射到实体的命令策略 .setTablePreFix("data_") //数据库表前缀 .setInclude("data_user") //要生成的表
- 包名策略配置
PackageConfig pgConfig = new PackageConfig() pgConfig.setParent("com.anxin.user") .setBean("bean") .setMapper("mapper") .setService("service") .setController("controller") .setXml("mapper")
- 整合配置
AutoGenerator ag = new AutoGenerator(); ag.setGlobalConfig(config) .setDataSource(dbConfig) .setStrage(stConfig) .setPackageInfo(pgConfig)
- 执行
ag.execute();
- 全局配置
五、插件扩展
- 插件机制与原理
- 通过Interceptor可以拦截四大对象相关方法
- Executor
- StatementHandler
- ParameterHandler
- ResultSetHandler
- 原理
四大对象的每个对象在mybatis底层创建时,都会执行InterceptorChain.pluginAll()方法,会经过每个插件的plugin()方法,通过创建代理对象操作四大对象
- 通过Interceptor可以拦截四大对象相关方法
- PaginationInterceptor 分页插件
- 注册
- 使用:selectPage(new Page<>(1,10),null)
- Page对象
- getTotal() //总条件
- getCurrent() //当前页
- getPages() //总页数
- getSize() //每页条数
- hasPrevious() //是否有上一页
- hasNext() //是否有下一页
- setRecords(T t)//把查询结果封装到page,返回前端
- SqlExplainInterceptor 执行分析插件
- 分析DELETE、UPDATE全表操作,防止小白
只建议在开发环境使用 - xxMapper.delete(null) 全表删除就会抛出异常
- 分析DELETE、UPDATE全表操作,防止小白
- PerfermanceInterceptor 性能分析插件
- 性能分析拦截器,用于console输出每条sql语句及其执行时间
开发环境使用,超过指定时间,停止运行
- 性能分析拦截器,用于console输出每条sql语句及其执行时间
- OptimisticLockerInterceptor 乐观锁插件
- 原理
- 取出记录,获取VERSION
- 更新时,带上VERSION
- set VERSION = youerVersion+1 where VERSION = yourVersion,如果VERSION不对应,更新失败
- @Version用于注解实体字段,表也必需要有VERSION列
- 更新失败不会抛异常,影响行数为0判断
- 原理
六、自定义全局操作
- 不需要xml写sql语句,通过扩展AutoSqlInjector在加载mybatis环境时就注入
- AutoSqlInjector
- 在Mpper接口中定义好相关CRUD方法
- 扩展AutoSqlInjector.inject()方法,实现Mapper接口中方法要注入的sql
public class MySqlIntjector extends AutoSqlInjector{ @Override public void inject(Configuration config,MapperBuilderAssistant ms,Class<?> mapperClass,Class<?> modelClass,TableInfo tableInfo){ //将xxMapper中自定义的deleteAll,处理成对应的MappedStatment对象,加入到configration对象中 //要注入的sql语句 String sql = "delete from "+ tableInfo.getTableName(); //要注入的方法,要与接口中方法名一致 String method = "deleteAll()"; //构造sqlSource对象 SqlSource sqlSource = languageDriver.createSqlSource(config,sql,modelClass) //构造一个删除的MappedStatment this.addDeleteMappedStatment(mapperClass,method,sqlSource); } }
- 在全局策略中,配置自定义注入器
- LogicSqlInjector 自定义逻辑删除
- logicDelteValue //逻辑删除全局值
- logicNotDelteValue//逻辑未删除全局值
- 在Entity中逻辑删除字段加@TableLogic注解
- 在mp自带查询和更新方法的sql后面,自动追加
七、公共字段自动填充
- MetaObjectHandler 元数据处理器接口
- insertFill(metaObject)
- updateFill(metaObject)
- metaObject:元对象。
- 获取对象的属性值或者设置属性的值,通过反射获取到属性对应的方法的invoker,最终invoke
- 是Mybatis提供的一个用于更加方便,更加优雅的访问对象的属性并为其设置值的对象;
- 还会用于包装对象,支持Map,Object,Collection等对象进行包装
- 步骤
- @TableFiled(fill=FiledFill.INSERT_UPDATE)放在Entity中要填充的字段上
- 自定义公共字段填充处理器
public class MyMetaObjectHandler extends MetaObjectHandler{ @Override public void insertFill(metaObject){ //获取需要被填充的值 Object fieldValue = getFieldValByName("column_name",metaObject); if(fieldValue == null ){ setFieldValByName("anxin",metaObject); } } @Override updateFill(metaObject) }
- MP全局注入
八、IDEA快速开发插件
- MybatisX
- 根据接口中方法自动生成xml结构