MyBatis-Plus
2021-04-22 20:29:17 39 举报
AI智能生成
MyBatis-Plus的基本入门使用,还有几个插件的使用示例
作者其他创作
大纲/内容
官网
https://mp.baomidou.com/
快速入门
https://mp.baomidou.com/guide/
本质
就是mybatis的升级,只是在mybatis的基础上做了提升,支持完全的向下兼容
这个图可以很好的解释
开始入门Demo
导入依赖
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2"> <!--mybatis-plus依赖--><br> <dependency><br> <groupId>com.baomidou</groupId><br> <artifactId>mybatis-plus-boot-starter</artifactId><br> <version>3.0.5</version><br> </dependency></font><br></pre>
只导入这一个依赖,不要再导入mybatis了,避免版本冲突
连接数据库
导入mysql依赖
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2"> <!--mysql连接依赖--><br> <dependency><br> <groupId>mysql</groupId><br> <artifactId>mysql-connector-java</artifactId><br> </dependency></font><br></pre>
配置application.properties
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2"># 数据库配置<br>spring.datasource.url=jdbc:mysql://localhost:3306/sbs?useSSL=false&useUnicode=true&characterEncoding=utf-8&</font><b style=""><font color="#f384ae">serverTimezone=UTC</font></b><font color="#cfd0d2"><br>spring.datasource.username=root # 时区配置,mysql8必须配置<br>spring.datasource.password=root<br>spring.datasource.driver-class-name=</font><b style=""><font color="#f15a23">com.mysql.cj.jdbc.Driver # 这是mysql8的版本驱动,完全支持向下兼容</font></b><br></pre>
编写pojo类
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2">package com.xiaoye.entity;<br><br>import lombok.AllArgsConstructor;<br>import lombok.Data;<br>import lombok.NoArgsConstructor;<br><br>import java.time.LocalDateTime;<br><br>/**<br> * @author 小也<br> * @create 2021/4/22 13:53<br> */<br>@Data<br>@AllArgsConstructor<br>@NoArgsConstructor<br>public class SysUser {<br> private Long id;<br> private String username;<br> private String password;<br> private String nickname;<br> private Long gender;<br> private Long age;<br> private Long clazzId;<br> private Long isDelete;<br> private Long version;<br> private LocalDateTime bjtCreate;<br> private LocalDateTime bjtModified; <br><br>}</font><br></pre>
编写mapper接口
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2">package com.xiaoye.mapper;<br><br>import com.baomidou.mybatisplus.core.mapper.BaseMapper;<br>import com.xiaoye.entity.SysUser;<br>import org.apache.ibatis.annotations.Mapper;<br><br>/**<br> * @author 小也<br> * @create 2021/4/22 13:56<br> */<br>@Mapper<br>public interface SysUserMapper </font><b style=""><font color="#f384ae">extends BaseMapper<SysUser></font></b><font color="#cfd0d2"> { <br> //只要集成了BaseMapper这个父类就可以直接使用很多的单表操作了 <br>}</font><br></pre>
BaseMapper
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2">//<br>// Source code recreated from a .class file by IntelliJ IDEA<br>// (powered by FernFlower decompiler)<br>//<br><br>package com.baomidou.mybatisplus.core.mapper;<br><br>import com.baomidou.mybatisplus.core.conditions.Wrapper;<br>import com.baomidou.mybatisplus.core.metadata.IPage;<br>import java.io.Serializable;<br>import java.util.Collection;<br>import java.util.List;<br>import java.util.Map;<br>import org.apache.ibatis.annotations.Param;<br><br>public interface BaseMapper<T> {<br> int insert(T var1);<br><br> int deleteById(Serializable var1);<br><br> int deleteByMap(@Param("cm") Map<String, Object> var1);<br><br> int delete(@Param("ew") Wrapper<T> var1);<br><br> int deleteBatchIds(@Param("coll") Collection<? extends Serializable> var1);<br><br> int updateById(@Param("et") T var1);<br><br> int update(@Param("et") T var1, @Param("ew") Wrapper<T> var2);<br><br> T selectById(Serializable var1);<br><br> List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> var1);<br><br> List<T> selectByMap(@Param("cm") Map<String, Object> var1);<br><br> T selectOne(@Param("ew") Wrapper<T> var1);<br><br> Integer selectCount(@Param("ew") Wrapper<T> var1);<br><br> List<T> selectList(@Param("ew") Wrapper<T> var1);<br><br> List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> var1);<br><br> List<Object> selectObjs(@Param("ew") Wrapper<T> var1);<br><br> IPage<T> selectPage(IPage<T> var1, @Param("ew") Wrapper<T> var2);<br><br> IPage<Map<String, Object>> selectMapsPage(IPage<T> var1, @Param("ew") Wrapper<T> var2);<br>}</font><br></pre>
在主启动类上扫描mapper接口
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2">package com.xiaoye;<br><br>import org.mybatis.spring.annotation.MapperScan;<br>import org.springframework.boot.SpringApplication;<br>import org.springframework.boot.autoconfigure.SpringBootApplication;<br><br>/**<br> * @author 22944<br> */<br>@SpringBootApplication<br></font><b style=""><font color="#f384ae">@MapperScan("com.xiaoye.mapper")</font></b><font color="#cfd0d2"><br>public class Springboot04MybatisPlusApplication {<br><br> public static void main(String[] args) {<br> SpringApplication.run(Springboot04MybatisPlusApplication.class, args);<br> }<br><br>}</font><br></pre>
开启mybatis-plus的日志
配置application.properties配置文件
# 开启日志输出<br>mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl<br>
测试一波
测试代码
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2">package com.xiaoye;<br><br>import com.baomidou.mybatisplus.core.conditions.Wrapper;<br>import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;<br>import com.xiaoye.entity.SysUser;<br>import com.xiaoye.mapper.SysUserMapper;<br>import org.junit.jupiter.api.Test;<br>import org.springframework.beans.factory.annotation.Autowired;<br>import org.springframework.boot.test.context.SpringBootTest;<br><br>import java.util.List;<br><br>@SpringBootTest<br>class Springboot04MybatisPlusApplicationTests {<br><br></font><b style=""><font color="#f15a23"> @Autowired<br> private SysUserMapper sysUserMapper;</font></b><font color="#cfd0d2"><br><br><br> @Test<br> void contextLoads() {<br></font><b style=""><font color="#f384ae"> QueryWrapper<SysUser> wrapper = new QueryWrapper<>();<br> wrapper.eq("id",1).like("nickname","ye").le("age",30).ge("gender","1");</font></b><font color="#cfd0d2"><br><br> </font><b style=""><font color="#c41230">List<SysUser> users = sysUserMapper.selectList(wrapper);</font></b><font color="#cfd0d2"><br><br> for (SysUser user : users) {<br> System.out.println(user.toString());<br> }<br><br> }<br><br>}</font><br></pre>
QueryWrapper
QueryWrapper是mybatis-plus自带的条件查询器,我们可以使用这个QueryWrapper来构造查询条件
eq("数据库列名","值")
要求某行的该列值和传入的值<b><font color="#f384ae">完全相等</font></b>才能查出来
like("数据库列名","值")
要求某行的该列值<b><font color="#f384ae">包含</font></b>传入的值才能查出来
le("数据库列名","值")
要求某行的该列值<b><font color="#f384ae">小于等于</font></b>传入的值才能查出来
ge("数据库列名","值")
要求某行的该列值<b><font color="#f384ae">大于等于</font></b>传入的值才能查出来
测试结果
mybatis-plus会帮我们自动生成简单的sql并拼接,对于单表操作可以说很友好了,但是对于多表联查还是需要自己手动写的
主键自增
数据库明明设置了主键自增,为什么添加数据的时候却给了一串很长的随机数呢?
其实这是mybatis-plus帮我们生成的主键id,采用的是twitter的雪花算法,用毫秒数、机器编号等参数形成的唯一id
我们想要变成我们想要的1,2,3,4,5这种简单的自增也很简单,添加一个注解就好了
乐观锁
简介
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式
取出记录时,获取当前version
更新时,带上这个version
执行更新时, set version = newVersion where version = oldVersion
如果version不对,就更新失败
实际操作一下
实体类中需要在相对应得字段上添加@Version注解
编写配置类(来自官网)
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2">// Spring Boot 方式<br></font><b style=""><font color="#f384ae">@Configuration<br>@MapperScan("按需修改")</font></b><font color="#cfd0d2"><br>public class MybatisPlusConfig {<br> /**<br> * 旧版<br> */<br> @Bean<br> public OptimisticLockerInterceptor optimisticLockerInterceptor() {<br> return new OptimisticLockerInterceptor();<br> }<br> <br> /**<br> * 新版<br> */<br> @Bean<br> public MybatisPlusInterceptor mybatisPlusInterceptor() {<br> MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();<br> mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());<br> return mybatisPlusInterceptor;<br> }<br>}</font><br></pre>
测试乐观锁
普通情况下(单线程操作)
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2"> @Test<br> void OptimisticLockTest(){<br> //1、查询用户,拿到版本号<br> SysUser user = sysUserMapper.selectById(1);<br> //2、执行更新操作<br> user.setAge(18);<br> sysUserMapper.updateById(user);<br> }</font><br></pre>
结果
多线程情况下
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2"> @Test<br> void OptimisticLockTest(){<br> //线程A<br> SysUser user1 = sysUserMapper.selectById(1);<br> user1.setAge(18);<br><br><br> //线程B执行<br> SysUser user2 = sysUserMapper.selectById(1);<br> user2.setAge(30);<br> sysUserMapper.updateById(user2);<br><br><br> //线程A继续执行更新操作<br> sysUserMapper.updateById(user1);<br> }</font><br></pre>
结果
时间戳
阿里巴巴Java开发手册上明确表示了数据库建表的时候必须要有创建时间(gmt_create)、修改时间(gmt_modified)字段
我们来实际使用一下
数据库建表加上这两个字段,并且类型设置timestamp
创建时间
默认时现在操作的时间,并且不再更新
修改时间
默认是现在的操作时间,并且会因为数据更新而更新时间戳
上面的操作在数据库中操作以及完全可以玩的来了,但是实际开发我却发现更新不生效
所以我查了很多资料,发现解决方式有两种,一种是加注解,一种是加注解和配置类
既然一个注解可以解决的事情,我为什么还要加配置类呢?完事收工
分页查询
我们首先想到的应该是学过的limit关键字,在数据库层面实现分页查询
现在我们使用mybatis-plus自带的分页插件来实现分页查询
简单的Page实现
代码
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2"> @Test<br> void limitPageTest(){<br> Page<SysUser> page = new Page<>(2,1);<br> sysUserMapper.selectPage(page,null);<br><br> page.getRecords().forEach(System.out::println);<br> }</font><br></pre>
效果
一共三条记录,现在显示页面大小为1,第二页的记录
逻辑删除
之前写逻辑删除的时候每次写sql都要手动拼接is_delete = 0,现在mybatis-plus帮我们封装好了
逻辑删除字段添加注解
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2"> </font><b style=""><font color="#f384ae">@TableLogic</font></b><font color="#cfd0d2"><br> private Integer isDelete; </font><br></pre>
配置拦截器
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2">package com.xiaoye.config;<br><br>import com.baomidou.mybatisplus.core.injector.ISqlInjector;<br>import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;<br>import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;<br>import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;<br>import org.mybatis.spring.annotation.MapperScan;<br>import org.springframework.context.annotation.Bean;<br>import org.springframework.context.annotation.Configuration;<br><br>/**<br> * @author 小也<br> * @create 2021/4/22 16:40<br> */<br>@MapperScan("com.xiaoye.mapper")<br>@Configuration<br>public class MybatisPlusConfig {<br><br> /**<br> * 乐观锁<br> * @return<br> */<br> @Bean<br> public OptimisticLockerInterceptor optimisticLockerInterceptor(){<br> return new OptimisticLockerInterceptor();<br> }<br><br> /**<br> * 分页组件<br> * @return<br> */<br> @Bean<br> public PaginationInterceptor paginationInterceptor(){return new PaginationInterceptor();}<br><br> </font><b style=""><font color="#f15a23">/**<br> * 逻辑删除<br> * @return<br> */<br> @Bean<br> public ISqlInjector iSqlInjector(){return new LogicSqlInjector();}</font></b><font color="#cfd0d2"><br><br>}</font><br></pre>
application.properties配置文件里配置逻辑删除的代号
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2"># 开启日志输出<br>mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl<br></font><b style=""><font color="#f384ae">#逻辑删除,未删除是0,已删除是1<br>mybatis-plus.global-config.db-config.logic-not-delete-value=0<br>mybatis-plus.global-config.db-config.logic-delete-value=1</font></b><br></pre>
开始测试
测试代码
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2"> @Test<br> void logicDeleteTest(){<br> sysUserMapper.deleteById(1);<br> }</font><br></pre>
测试结果
先执行删除操作
再次查询发现已经查不到了
我们可以通过navicat看到实际上只是更改了is_delete的值,并没有真的删除
性能分析插件
性能分析插件就是记录每条sql执行的时间,超时就会停止运行
导入插件,注册组件
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2"> @Bean<br> public PerformanceInterceptor performanceInterceptor(){<br> PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();<br> </font><b style=""><font color="#f384ae">//这里是毫秒数,设置sql执行的最大时间,超时就停止<br> performanceInterceptor.setMaxTime(100);</font></b><font color="#cfd0d2"><br> //开启sql格式化<br> performanceInterceptor.setFormat(true);<br> return performanceInterceptor;<br> }</font><br></pre>
开始测试
这个很常用,可以有效找到慢查询
自动代码生成
AutoGenerator类<br>
可能报错<br>
导入依赖即可
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2"> <!--模板引擎--><br> <dependency><br> <groupId>org.apache.velocity</groupId><br> <artifactId>velocity-engine-core</artifactId><br> <version>2.0</version><br> </dependency></font><br></pre>
源码
<pre style="background-color: rgb(43, 43, 43); font-family: "JetBrains Mono", monospace; font-size: 9.8pt;"><font color="#cfd0d2">package com.xiaoye.util;<br><br>import com.baomidou.mybatisplus.annotation.DbType;<br>import com.baomidou.mybatisplus.annotation.FieldFill;<br>import com.baomidou.mybatisplus.annotation.IdType;<br>import com.baomidou.mybatisplus.generator.AutoGenerator;<br>import com.baomidou.mybatisplus.generator.config.DataSourceConfig;<br>import com.baomidou.mybatisplus.generator.config.GlobalConfig;<br>import com.baomidou.mybatisplus.generator.config.PackageConfig;<br>import com.baomidou.mybatisplus.generator.config.StrategyConfig;<br>import com.baomidou.mybatisplus.generator.config.po.TableFill;<br>import com.baomidou.mybatisplus.generator.config.rules.DateType;<br>import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;<br><br>import java.util.ArrayList;<br><br>/**<br> * @author 小也<br> * @create 2021/4/22 19:37<br> */<br>public class AutoCoding {<br> private static final String DATA_SOURCE_DRIVER = "com.mysql.cj.jdbc.Driver";<br> private static final String DATA_SOURCE_URL = "jdbc:mysql://localhost:3306/sbs?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC";<br> private static final String DATA_SOURCE_USERNAME = "root";<br> private static final String DATA_SOURCE_PASSWORD = "root";<br> private static final String MODULE_NAME = "sys";<br> private static final String MODULE_PARENT_NAME = "com.xiaoye";<br> private static final String TABLE_NAME = "sys_user";<br> private static final String LOGIC_DELETE_NAME = "is_delete";<br> private static final String GMT_CREATE = "bjt_create";<br> private static final String GMT_MODIFIED = "bjt_modified";<br> private static final String OPTIMISTIC_LOCK_NAME = "version";<br><br> public static void main(String[] args) {<br> //创建自动代码生成对象<br> AutoGenerator autoGenerator = new AutoGenerator();<br><br> //1、全局配置<br><br> GlobalConfig globalConfig = new GlobalConfig();<br> //设置作者<br> globalConfig.setAuthor("xiaoye");<br> //获取当前项目路径<br> String properties = System.getProperty("user.dir");<br> //设置输出路径<br> globalConfig.setOutputDir(properties + "/src/main/java");<br> //不要打开资源管理器<br> globalConfig.setOpen(false);<br> //不覆盖原文件<br> globalConfig.setFileOverride(false);<br> //service接口不带I前缀<br> globalConfig.setServiceName("%sService");<br> //设置id自增<br> globalConfig.setIdType(IdType.AUTO);<br> //设置时间格式<br> globalConfig.setDateType(DateType.TIME_PACK);<br> //配置swagger2文档<br> globalConfig.setSwagger2(true);<br> //设置mapper.xml生成一个RestMap<br> globalConfig.setBaseResultMap(true);<br><br> autoGenerator.setGlobalConfig(globalConfig);<br><br><br><br> //2、数据源配置<br><br> DataSourceConfig dataSourceConfig = new DataSourceConfig();<br> dataSourceConfig.setDbType(DbType.MYSQL);<br> dataSourceConfig.setDriverName(DATA_SOURCE_DRIVER);<br> dataSourceConfig.setUrl(DATA_SOURCE_URL);<br> dataSourceConfig.setUsername(DATA_SOURCE_USERNAME);<br> dataSourceConfig.setPassword(DATA_SOURCE_PASSWORD);<br><br> autoGenerator.setDataSource(dataSourceConfig);<br><br><br><br> //3、生成包配置<br> PackageConfig packageConfig = new PackageConfig();<br><br> packageConfig.setModuleName(MODULE_NAME);<br> packageConfig.setParent(MODULE_PARENT_NAME);<br> packageConfig.setEntity("entity");<br> packageConfig.setMapper("mapper");<br> packageConfig.setService("service");<br> packageConfig.setController("controller");<br><br> autoGenerator.setPackageInfo(packageConfig);<br><br><br><br><br> //4、策略配置<br> StrategyConfig strategyConfig = new StrategyConfig();<br><br> //要映射的表名<br> strategyConfig.setInclude(TABLE_NAME);<br> //下划线转驼峰命名<br> strategyConfig.setNaming(NamingStrategy.underline_to_camel);<br> //下划线转驼峰命名<br> strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);<br> //开启lombok<br> strategyConfig.setEntityLombokModel(true);<br> //开启逻辑删除名字<br> strategyConfig.setLogicDeleteFieldName(LOGIC_DELETE_NAME);<br><br> //自动填充设置<br> TableFill bjtCreate = new TableFill(GMT_CREATE, FieldFill.INSERT);<br> TableFill bjtModified = new TableFill(GMT_MODIFIED, FieldFill.INSERT_UPDATE);<br> ArrayList<TableFill> tableFieldList = new ArrayList<>();<br> tableFieldList.add(bjtCreate);<br> tableFieldList.add(bjtModified);<br> strategyConfig.setTableFillList(tableFieldList);<br><br> //乐观锁配置<br> strategyConfig.setVersionFieldName(OPTIMISTIC_LOCK_NAME);<br> //restFul风格<br> strategyConfig.setRestControllerStyle(true);<br> //下划线url<br> strategyConfig.setControllerMappingHyphenStyle(true);<br><br> autoGenerator.setStrategy(strategyConfig);<br><br><br> //开始执行代码生成<br> autoGenerator.execute();<br> }<br>}</font><br></pre>
0 条评论
下一页