MybatisPlus<br />一、简介<br />1、Mybatis介绍<br /> 只对Mybatis进行增强不做改变<br />2、代码及文档地址<br /> [https://mp.baomidou.com/](https://mp.baomidou.com/)<br />3、前置知识<br /> Mybatis<br /> Spring<br />Maven<br />二、集成MP<br />1、创建测试表<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012037424-024b4a14-e38d-4ac1-957d-69f9ef3aff18.png#height=169&width=375)<br />2、创建JavaBean<br />3、依赖配置<br /> (1)依赖 <br /><dependency><br /> <groupId>com.baomidou</groupId><br /> <artifactId>mybatis-plus</artifactId><br /> <version>2.3</version><br /> </dependency><br /> 无需加入Mybatis和Mybatis-Spring依赖,MP会自动帮我们维护<br /> (2)全局配置文件<br /> <br />4、测试<br /> 测试是否有DataSource和Connection对象<br />5、集成MP(将Mybatis-Plus集成进来)<br /> Mybatis提供的:org.mybatis.spring.SqlSessionFactoryBean<br />Mybatis-Plus提供的:<br />com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean<br />三、入门HelloWorld<br />1、通用CRUD<br /> 实现:让XxxMapper接口继承BaseMapper接口即可。<br /> BaseMapper<T>:泛型指定的就是的当前Mapper接口所操作的实体类<br /> BaseMapper接口:不需要编写XxxMapper.xml,接口内部提供了一系列的<br />方法。<br />![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012037694-53770f20-d9b4-4058-b6f6-597cc170b07e.png#height=257&width=305) <br />2、插入操作和引出的所有知识点<br /> 方法1:insert(对象); 插入一条记录<br /> 会判断实体对象的属性是否有设置值,没有的就不会出现在sql<br />语句中。<br />![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012037885-f9853561-0f50-404d-a87b-375588fdb7ea.png#height=62&width=415)<br />@Tabled:主键注解<br /> 属性:<br /> value:属性值和字段名不一致时,需要设置成表中字段名<br /> type:主键生成策略。有5种<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012038286-979aabca-6af4-4bac-af19-4b6e29d9db46.png#height=126&width=320) <br /> @TableName:表名注解<br /> 属性:<br /> value:实体类和表名不一致时,需要指定表名<br /> resultMap:xml中 resultMap的id。设置此值时则按指定的<br />resultMap封装数据<br /> <br /> @TableField:非主键的字段注解<br /> 该注解在2.3版本之后,很少使用了。因为dbColumnUnderline默认是<br />true。<br />属性:<br /> value:指定表中的字段名与该属性对应<br /> exist:标识该属性是否为表中的字段,默认为true<br /> 作用:当实体类有其它属性时,但该属性不参与任何的CRUD操<br />作,该属性必须设置为@TableField(exist=false)<br /> <br /> (1)插入数据获取主键值<br /> 直接使用对象的getId()方法,就可以获取当前对象的主键值。不<br />需要进行任何的配置。<br /> <br />方法2:insertAllColumn(对象); 插入一条记录<br /> 不管属性有没有设置值,都会出现在sql语句中,没有值的设置尾<br />NULL。<br /> <br />3、全局策略配置<br /> 类:GlobalConfiguration<br />![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012038517-ad5600e4-4346-4eed-b35d-488267059793.png#height=52&width=415)<br />注入到SqlSessionFactoryBean中:<br /> property的name属性:globalConfig<br /> property的ref属性:对应bean的id<br />![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012038714-77adbc75-c4d2-46f3-961b-04fc94d93d7b.png#height=13&width=415)<br />属性:dbColumnUnderline:驼峰命名来匹配下划线格式。在2.3版本以后,<br />默认为true,不需要配置。<br /> 例如:实体类的lastName属性--->表中的last_name字段名<br />idType:全局的主键策略 ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012038978-3d2675e0-bfec-42c0-9141-f065d7e7e3c8.png#height=72&width=415)<br />tablePrefix:全局的表前缀策略<br /> 配置后,Mybatis-Plus会将前缀与实体类的类名连接起来,然后与数据库中的表名对比。<br />4、更新操作<br /> 方法1:Integer updateById(T); 更新一条记录<br />根据id确定要修改的对象,然后重新修改对象的属性值,再调用方法进行更新数据。只会对非空的属性进行sql语句的更新。<br /> 方法2:updateAllColumnById(T);更新一条记录<br /> 对所有的属性进行sql语句的更新,没有设置值的属性,默认更新为Null<br />5、查询操作<br /> 方法1:T selectById(Serializable id);<br /> 直接传入主键id,就会返回查询结果对象<br /> 方法2:T selectOne(T);<br /> 参数对象可以设置1个或多个属性值,根据参数对象来查找唯一的对象<br /> 查找到多个对象时,会报错。<br /> 方法3:List<T> selectBatchIds(List idList);<br /> 传入一个带有主键id的List来查询数据库,返回List集合对象<br /> 方法4:List<T> selectByMap(Map<String,Object> columnMap);<br /> 参数:String是数据表的字段名 ,Object就是要查的字段值<br /> 返回值:返回的是集合对象<br /> 方法5:T selectPage(RowBounds rowBounds,Wrapper<T> wrapper);<br /> 作用:根据entity条件,查询全部记录(并翻页)<br /> 参数:<br /> RowBounds:分页查询条件(可以为RowBounds.DEFAULT)<br /> 可以传入Page类(实现分页辅助类)<br /> new Page<>(第几页,每页的条数);<br />Wrapper:条件构造器,实体对象封装操作类(可以为null)<br /> 详解:sql语句没有使用limlit关键字,因此该方法用的是RowBounds<br />底层的内存分页(逻辑分页)。后期我们要借助分页插件,实现物<br />理分页(带有limlit关键字)。<br />6、删除操作<br /> 方法1:Integer deleteById(Serializable id);根据主键删除记录<br /> 方法2:Integer deleteByMap(Map<String,Object> columnMap);<br /> 参数:String是数据表的字段名 ,Object就是要查的字段值<br /> 作用:根据多个字段的值,来删除记录<br /> 返回值:返回删除的记录条数<br /> 方法3:Integer deleteBatchIds(List idList);<br /> 参数:多个主键id封装而成的List集合<br /> 作用:根据多个主键来来删除多条记录<br />返回值:删除的记录条数<br />7、MP启动注入SQL原理分析<br /> (1)问题:XxxMapper继承了BaseMapper,BaseMapper提供了通用的CRUD<br />方法,有方法就必须有SQL,因为Mybatis最终还是需要通过<br />SQL语句操作数据。<br /> (2)前置知识:Mybatis源码中比较重要的一些对象,Mybatis框架的执行<br />流程:<br /> Configuration<br /> MappedStatement<br /> ......<br /> (3)通过现象看到本质的东西:<br /> A、XxxMapper的本质是:MapperProxy(代理对象)<br /> B、MapperProxy中的sqlSession,再sqlSessionFactory<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012039340-8d1cc4ca-777e-463f-a3be-714095a3ee7a.png#height=78&width=309)<br /> C、sqlSessionFactory中的configuration(全局配置文件)<br /> D、configuration中的MappedStatements<br /> 每一个mappedStatement都表示Mapper接口中的一个方法与<br />Mapper映射文件的SQL。<br /> E、MP在启动就会挨个分析xxMapper中的方法,并且将对应的SQL<br />语句处理好,保存到configuration对象中的mappedStatement<br />中<br /> F、本质:<br />![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012039729-4dca684f-528c-4ff6-acc7-494b21d3b88d.png#height=109&width=415)<br /> SqlMethod:枚举对象,内含不完整的模版SQL语句<br /> TableInfo:数据库表的反射对象,可以获取到数据库表相关信息<br /> SqlSource:SQL语句处理对象<br /> MapperBuilderAssistant:用于缓存、SQL参数、查询结果集处理,<br />可以将MappedStatement添加到<br />Configuration中去。<br /> <br />8、通用CRUD小结<br /> (1)以上的所有操作,只需要继承BaseMapper接口就可以使用。<br /> (2)提出需求:分页查询tbl_employee表,年龄在18-50且为男性的,姓<br />名为xx所有用户,这时我们就要使用MP中的条件构造器:<br />EntityWrapper<br /> <br />四、条件构造器EntityWrapper<br />1、简介<br />(1)MP可以通过EntityWrapper或者Condition来让用户自由构建条件,提高<br />效率。<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012039933-814772e0-d78a-4373-b450-b278e913a574.png#height=46&width=314)<br />(2)实体包装器,主要用于处理sql拼接,排序,实体参数查询等<br />(3)注意:使用的是数据库表中字段名,不是实体类的属性名<br />(4)条件参数说明:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012040540-3d1ca1fd-e44c-45b0-98bc-26fdc3228a39.png#height=376&width=223)<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012041100-5ba13d3f-2578-4332-b307-dd820c612cce.png#height=210&width=224)<br /> <br />2、selectPage方法<br />需求:分页查询tbl_employee表,年龄在18-50之间性别为男且姓名为Pzm<br />的所有用户。<br /> 注意:每个条件之间默认使用and连接起来的<br /> 实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012041569-c8c8dae3-22dd-4215-93ed-660b89bc229a.png#height=102&width=365)<br /> <br />3、带条件的查询<br /> 需求:查询tbl_employeeb表,性别为女且名字带有“老师”或者邮箱中带<br />有“a”<br /> 方法:List<T> selectList(Wrapper<T> wrapper);<br /> 实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012042094-d78215f2-dcf9-4293-a365-da46bde85ad3.png#height=128&width=375)<br />4、带条件的修改<br /> 需求:修改名字为Pzm且年龄为21的 <br />方法:Integer update(T entity,Wrapper<T> wrapper);<br />参数:entity:封装修改后的对象<br /> Wrapper:封装条件<br />实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012042594-944eacb8-3cc8-4afd-9a31-0eabc3e1179c.png#height=118&width=356)<br />5、带条件的删除<br /> 需求:删除名字为LDM且年龄为25的数据<br />方法:Integer delete(Wrapper<T> wrapper);<br />实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012043142-81249470-ffb2-494c-b4e7-c5cf83f2c100.png#height=93&width=365)<br />6、EntityWrapper的常用方法<br />(1)orderBy(“”):默认升序<br /> orderAsc(Collection<String> columns): 升序<br /> orderDesc(Collection<String> columns):降序<br /> last(“”):手动把sql拼接到最后(有sql注入的风险,请谨慎使用)<br />需求:查询性别为女(0),根据age进行排序,简单分页<br /> 实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012043757-908d82b3-a372-4a39-b9a8-6dfbcb32f010.png#height=132&width=359) <br />7、使用Condition类<br />除了创建实例对象与EntityWrapper不一样,其余的条件构造方法都是一样的,因为都是来自于Wrapper类的。<br />创建实例:Condition.create();<br /> <br /> <br />五、ActiveRecord(活动记录)<br />1、概述<br /> 一个模型类对应关系型数据库中的一个表,模型类的一个实例对应表中的<br />一行记录。<br />2、使用AR模式<br /> 实现:实体类继承Model类且实现主键指定方法<br /> 实现的方法:返回当前实体类的主键 <br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012044227-f4b192a6-cf16-49fa-889e-514172fada6f.png#height=89&width=353)<br /> <br />3、AR基本CRUD<br />(1)插入操作<br /> 方法:boolean insert();<br /> 返回值:成功返回true,失败返回false<br /> 实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012044760-f21b972e-ea67-4510-ae8a-7a4b88310f5a.png#height=115&width=317)<br />(2)修改操作<br /> 方法:boolean updateById()<br /> 返回值:成功返回true,失败返回false<br /> 实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012045264-617d433b-2c8e-4806-951a-0475948ec631.png#height=119&width=337)<br />(3)查询操作<br /> 方法1:T selectById()<br /> 返回值:返回查询的结果对象<br /> 实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012045722-06ec6c90-31fd-4999-9752-58e0102560c8.png#height=91&width=305)<br /> <br /> 方法2:T selectById(Serializable id)<br /> 返回值:返回查询的结果对象<br /> 实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012046150-8ec1e687-4507-45af-a3cf-dd3dcb482283.png#height=73&width=294)<br /> 方法3:List<T> selectAll()<br /> 返回值:返回表中所有的数据<br /> 实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012046644-7b2395a1-f68a-4d34-b171-11bddd9f24a1.png#height=86&width=305)<br /> 方法4:List<T> selectList(Wrapper wrapper)<br /> 返回值:返回查询的结果对象<br /> 实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012047182-3a7e95cf-e3ca-4fd2-81c1-0aedbbe5ab02.png#height=101&width=323)<br /> 方法5:int selectCount(Wrapper wrapper)<br /> 作用:统计查询<br /> 返回值:返回统计的结果值<br /> 实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012047856-4ca2b50d-d9e1-49ce-a208-07a844736e70.png#height=73&width=307)<br /> <br />(4)删除操作(删除不存在的ID逻辑上属于成功)<br /> 方法1:boolean deleteById()<br /> 返回值:删除成功返回true,删除失败返回false。<br /> 实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012048513-3e688498-bd20-4d3e-8a37-788e43fd9ebe.png#height=61&width=270)<br /> 方法2:boolean deleteById(Serializable id)<br /> 返回值:删除成功返回true,删除失败返回false<br /> 实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012049383-1e5ffdfa-ebfa-4354-a40b-70bf5d061b46.png#height=47&width=252)<br /> 方法3:boolean delete(Wrapper wrapper)<br /> 返回值:删除成功返回true,删除失败返回false<br /> 实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012049952-411bef0b-b6d0-4e93-910b-5c69702b2b0e.png#height=78&width=281)<br />(5)复杂分页操作<br /> 方法:Page<T> selectPage(Page<T> page,Wrapper<T> wrapper)<br /> 实现:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012050436-dd4465de-d384-4050-a48b-9da41fe7e077.png#height=90&width=341)<br />4、AR小结<br />(1)AR模式提供了一种更加简便的方式实现CRUD操作,其本质还是调用的<br />Mybatis对应的方法。<br />(2)到此,我们简单领略了MP的魅力与高效率,MP提供了强大的代码生成器,<br />可以快速生成各类代码,真正的做到了即开即用。<br /> <br />六、代码生成器<br />1、MP的代码生成器和Mybatis的代码生成器:<br /> MP的代码生成器都是基于java代码来生成的。Mybatis基于xml文件<br /> Mybatis的代码生成器可生成:实体类,Mapper接口,Mapper映射文件<br /> MP的代码生成器可生成:实体类(是否支持AR),Mapper接口,Mapper映<br />射文件,Service层,Controller层<br />2、表及字段名策略选择<br /> 在MP中,建议数据库表名和表字段名采用驼峰命名方式,如果采用下划线<br />命名方式,请开启全局下划线开关(默认开启),如果表名字段名命名方法<br />不一致请注解指定,建议保持一致。<br /> <br />3、代码生成器依赖<br /> (1)模版引擎<br /> MP的代码生成器默认使用的是Apache的Velocity模版,也可以更<br />换别的模版引擎<br /><dependency><br /> <groupId>org.apache.velocity</groupId><br /> <artifactId>velocity-engine-core</artifactId><br /> <version>2.0</version><br /></dependency><br /> (2)加入slf4j,查看日志输出<br /><dependency><br /> <groupId>org.slf4j</groupId><br /> <artifactId>slf4j-api</artifactId><br /> <version>1.7.7</version><br /></dependency><br /><dependency><br /> <groupId>org.slf4j</groupId><br /> <artifactId>slf4j-log4j12</artifactId><br /> <version>1.7.7</version><br /></dependency><br /> <br />4、全局配置<br /> 类:GlobalConfig<br /> 方法:<br /> 1、GlobalConfig setActiveRecord(boolean); 是否支持AR模式<br /> 2、GlobalConfig setAuthor(String); 设置作者<br /> 3、GlobalConfig setOutputDir(String); 设置生成路径<br /> 4、GlobalConfig setFileOverride(boolean); 文件是否覆盖<br /> 5、GlobalConfig setIdType(IdType); 主键策略<br /> 6、GlobalConfig setServiceName(String); 设置生成的Service接<br />口的名字的首字母是否<br />为I<br /> 7、GlobalConfig setResultMap(boolean); 是否生成映射文件<br /> 8、GlobalConfig setBaseColumnList(boolean); 是否生成sql片段<br /> <br />5、数据源配置<br /> 类:DataSourceConfig<br /> 方法:<br /> 1、DataSourceConfig setDbType(DbType); 设置数据库的类型<br /> 2、DataSourceConfig setDriverName(String);<br /> 3、DataSourceConfig setUrl(String);<br /> 4、DataSourceConfig setUser(String);<br /> 5、DataSourceConfig setPassword(String);<br /> <br />6、策略配置<br /> 类:StrategyConfig<br /> 方法:<br /> 1、StrategyConfig setDbColumnUnderline(boolean);下划线命名<br /> 2、StrategyConfig setCapitalMode(boolean); 全局大写命名<br /> 3、StrategyConfig setNaming(NamingStrategy.underline_to_camel<br />); (下划线—驼峰)匹配<br /> 4、StrategyConfig setTablePrefix(String); 指定表名前缀<br /> 5、StrategyConfig setInclude(String …); 设置生成的表<br /> <br />7、包名策略配置<br /> 类:PackageConfig<br /> 方法:<br /> 1、PackageConfig setParent(String); 设置父包<br /> 2、PackageConfig setMapper(String); 设置Mapper所在的包<br /> 3、PackageConfig setController(String); 设置Controller的包<br /> 4、PackageConfig setEntity(String);设置实体类所在的包<br /> 5、PackageConfig setXml(String); 设置映射文件所在的包<br /> 6、PackageConfig setServiceImpl();设置Service实现类所在的包<br /> 7、PackageConfig setService();设置Service接口所在的包<br /> <br />8、整合配置<br /> 类:AutoGenerator<br /> 方法:<br /> 1、AutoGenerator setGlobalConfig(GlobalConfig);<br /> 2、AutoGenerator setDataSource(DataSourceConfig);<br /> 3、AutoGenerator setStrategy(StrategyConfig);<br /> 4、AutoGenerator setPackageInfo(PackageConfig);<br /> 5、AutoGenerator execute(); 执行<br /> <br />9、生成代码的解析<br /> EmployeeServiceImpl:<br />1、在ServiceImpl中已经完成了Mapper的注入,可以直接在<br />EmployeeServiceImpl中进行使用<br />2、在ServiceImpl中也帮我们提供了常用的CRUD方法,基本的一些CRUD<br />方法在Service中不需要我们定义<br /> <br /> <br />七、插件扩展<br />1、Mybatis插件机制简介<br />(1)插件机制:<br /> Mybatis通过插件(Interceptor)可以做到拦截四大对象相关方法的执<br />行,根据需求,完成相关数据的动态改变。<br /> 四大对象:<br /> Executor 执行器对象<br /> StatementHandler sql语句编译器对象<br /> ParameterHandler 参数处理器对象<br /> ResultSetHandler 结果集处理器对象<br />(2)插件原理<br /> 四大对象的每个对象在创建时,都会执行interceptorChain.pluginAll<br />(),会经过每个插件对象的plugin()方法,目的是为当前的四大对象创<br />建代理。代理对象就可以拦截到四大对象相关方法的执行,因为要执行<br />四大对象的方法需要经过代理。<br />(3)配置:<br /> 都是配置在sqlSessionFacotryBean的plugins属性中。(数组)<br /> <br />2、分页插件<br />PaginationInterceptor<br /> 配置:<br /> 1、可以在mybatis-config.xml中配置<br /> 2、在applicationContext.xml中配置:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012051021-20285d93-9967-4be2-b375-c6440b658cfc.png#height=68&width=301)<br /> 测试:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012051537-393b3998-bf94-408c-b478-8ecb8e14a957.png#height=79&width=336)<br /> Sql语句: SELECT id,last_name AS lastName,email,gender,age<br />FROM tbl_employee LIMIT 0,3<br /> <br />3、注册分页插件后Page对象的使用<br /> 总条数:getTotal();<br /> 当前页:getCurrent();<br />总页数:getPages();<br />每页显示的条数:getSize();<br />是否有上一页:hasPrevious();<br />是否有下一页:hasNext();<br />封装数据:setRecords(List<T> records);<br /> <br />4、执行分析插件<br /> (1)概述:<br />类:SqlExplainInterceptor<br /> 要求:Sql执行分析拦截器,支持Mysql 5.6.3以上版本<br /> 作用:分析DELETE,UPDATE语句,防止小白或者恶意进行DELETE<br />UPDATE全表操作。<br /> 只建议在开发环境中使用,不建议在生产环境使用<br /> (2)原理:在插件的底层,通过SQL语句分析命令:Explain分析当前的SQL<br />语句,根据结果集中的Extra列来断定当前斯否全表操作。<br /> (3)注册插件(配置):<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012052043-9dcbcc1d-a3c3-4908-8bc9-50dc7dd90b51.png#height=46&width=317)<br /> (4)测试:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012052541-bfcd9d02-299c-4fa3-a670-14625d0e0596.png#height=64&width=350)<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012053012-297a7a3d-b911-4320-a7a4-217707611172.png#height=26&width=334)<br /> <br />5、性能分析插件<br />(1)概述:<br />类:PerformanceInterceptor<br /> 作用:用于输出每条SQL语句及其执行时间<br /> 场合:开发环境使用,超过指定时间,停止运行,有助于发现问题<br />(2)注册插件(配置):<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012053559-f37e91a3-106e-4ffd-a569-faf1d91ee51c.png#height=56&width=333)<br /> (3)测试:<br /> 超出时间,sql语句还是能执行成功。<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012054001-4b5a1644-4a42-45a9-8de4-cef977e87d72.png#height=97&width=359)<br />6、乐观锁插件<br />(1)概述:<br /> 类:OptimisticLockerInterceptor<br /> 要求:当要更新一条数据时,希望这条记录没有被别人更新<br />原理:<br />取出记录时,获取当前version<br /> 更新时,带上这个version<br /> 执行更新时,set version=yourVersion+1 where version=<br />yourVersion<br /> 如果version不对,就更新失败<br /> @Version:用于注解实体字段,必须要有<br /> (2)注册插件:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012054204-396febe9-cbe2-437d-a4cb-5fb0498dc303.png#height=40&width=316)<br /> (3)测试:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012054564-d136ec7f-7c48-4e38-a1f6-d717e20e1450.png#height=106&width=307)<br /> <br />八、自定义全局操作<br />1、概述<br />根据MybatisPlus的AutoSqlInjector可以自定义各种你想要的sql,注入到全局中,就相当于时MybatisPlus自带的方法。<br />不需要在xml中写上相应的SQL语句,而是通过扩展AutoSqlInjector在加载Mybatis环境时就注入。<br /> <br />2、AutoSqlInjector<br />步骤:<br />(1)、在Mapper接口中定义相关的CRUD方法<br /> int deleteAll();<br />(2)、扩展AutoInjector的inject方法,实现Mapper接口中方法要注<br />入的SQL<br />![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012055055-da06896f-93a7-4269-910f-a8e452ed632f.png#height=195&width=415)<br /> (3)、在MP全局策略中,配置自定义注入器<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012055289-df13fdee-15e7-44c8-88bb-df40f1d72933.png#height=64&width=303)<br /> <br />3、自定义注入器的应用之逻辑删除<br /> 假删除、逻辑删除:并不会真正的从数据库中将数据删除掉,而是将当前被<br />删除的这条数据中的逻辑删除字段置为删除字段。<br /> (1)概述:<br />1、类:LogicSqlInjetor<br /> 2、logicDeleteValue:逻辑删除全局值<br /> 3、logicNotDeleteValue:逻辑未删除全局值<br /> 4、逻辑删除字段添加@TableLogic注解<br /> 5、会在mp自带查询和更新方法的sql后面,追加【逻辑删除字段】<br />=【LogicNotDeleteValue(默认值)】 删除方法:deleteById和<br />其它delete方法,底层SQL调用的是update tbl_xxx set<br />【逻辑删除字段】=【logicDeleteValue】<br />(2)配置注入器:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012055485-93a7ccd2-dadb-4c16-bd3b-c4ec842b69ba.png#height=90&width=348)<br />(3)创建数据表<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012055677-8a3267c4-5931-4a93-a699-30b192d8f3b0.png#height=65&width=157)1:代表未删除 -1:代表已删除 <br />(4)创建实体类和Mapper接口(略)<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012056120-e736eb94-49cb-4e99-ac13-e83065044254.png#height=77&width=297)<br />(5)测试:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012056304-0b39edd0-0790-46cd-bcb1-85fe48c61fd5.png#height=45&width=247)<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012056501-102a72fe-8212-4ebc-9728-ba9ffda03ac4.png#height=97&width=335)<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012056669-9e90c2bc-e2b4-490e-a32e-fe032f64e4ac.png#height=57&width=275)<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012057123-492f5f37-8500-4e74-9c57-4445e35f7933.png#height=118&width=248)<br /> <br />九、公共字段自动填充<br />1、概述:在更新或插入时,对没有的提供的数据,进行默认数据的填充。<br />2、元数据处理器接口<br /> 类:MetaObjectHandler<br /> 方法:<br /> 1、insertFill(MetaObject metaObject); 插入元对象字段填充<br /> 2、updateFill(MetaObject metaObject); 更新元对象字段填充<br /> 对象:<br /> MetaObject:是Mybatis用于更方便的访问对象的属性,给对象的属<br />性设置值的一个对象,还用于包装对象,支持Object、<br />Map、Collection等对象进行包装。<br /> 本质:获取对象的属性值或者给对象的属性设置值,最终是要通过<br />Reflector获取到属性的对应方法的invoker,最终invoker。<br />3、开发步骤<br />(1)注解填充自动 @TableField(fill=FieldFill.INSERT)<br /> 属性:fill<br /> 值:<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012057360-88e096f5-be98-4c4f-9caf-d465509e655b.png#height=74&width=304)<br />(2)自定义公共字段填充处理器<br /> 1、自定义类,继承MetaObjectHandler,实现方法<br /> 2、获取到需要被填充的字段的值<br /> getFieldValueByName(fieldname,metaObject);<br /> 3、判断字段是否为空<br /> 4、对字段进行填充<br /> SetFieldValueByName(fieldname,值,metaObject);<br />(3)MP全局注入自定义公共字段填充处理器<br /> 配置到全局配置类中。<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012057574-ddec6215-9e14-4538-b264-694f3affead9.png#height=61&width=342)<br /> <br />十、Oracle主键Sequence<br />Mysql:支持主键自增 IdType.AUTO<br />Oracle:序列(Sequence)<br />1、Oracle驱动依赖的问题<br /> 因为Oracle授权问题,不能从Maven仓库中下载Oracle驱动<br />2、Oracle的相关知识<br /> 创建序列:create sequence seq_user start with 100 increment by 2;<br /> 查询序列的下一个值:select seq_user.nextval from dual;<br /> 查询序列的当前值:select seq_user.currval from dual;<br />3、步骤:<br /> (1)实体类配置主键Sequence,@KeySequence(value=”序列<br />名”,clazz=xx.class 主键属性类型)<br />![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012057766-797174c8-98a4-4a8c-a93e-a6f6a5f9871c.png#height=38&width=415)<br />(2)全局MP主键生成策略:IdType.INPUT<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012058213-86950173-be23-4c68-a8a3-801d79e137cc.png#height=30&width=325)<br />(3)全局MP配置Oracle主键Sequence<br /> ![](https://cdn.nlark.com/yuque/0/2020/png/471109/1608012058435-15ee9fc3-cfb5-4ac0-a5eb-f752820aa7e8.png#height=56&width=331)<br /> (4)可以将@KeySequence定义在父类中,可实现多个子类对应的多个表公<br />用一个Sequence<br /> <br /> <br />十一、Idea快速开发插件<br />1、功能<br /> 根据接口中的方法自动生成xml结构<br />