MyBatisPlus
快速入门
1.创建数据库mybatisplus
2.创建user表并插入数据
DROP TABLE IF EXISTS user;
CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT \'主键ID\',
name VARCHAR(30) NULL DEFAULT NULL COMMENT \'姓名\',
age INT(11) NULL DEFAULT NULL COMMENT \'年龄\',
email VARCHAR(50) NULL DEFAULT NULL COMMENT \'邮箱\',
PRIMARY KEY (id)
);
INSERT INTO user (id, name, age, email) VALUES
(1, \'Jone\', 18, \'test1@baomidou.com\'),
(2, \'Jack\', 20, \'test2@baomidou.com\'),
(3, \'Tom\', 28, \'test3@baomidou.com\'),
(4, \'Sandy\', 21, \'test4@baomidou.com\'),
(5, \'Billie\', 24, \'test5@baomidou.com\');
-- 真实开发中一般还需要version(乐观锁)、deleted(逻辑删除)、gmt_create、gmt_modified
3.初始化SpringBoot项目
4.导入依赖
尽量不要同时导入mybatis和mybatisplus的依赖
<!-- 数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
5.连接数据库
application.properties
# mysql 5 驱动不同 com.mysql.jdbc.Driver
# mysql 8 驱动不同com.mysql.cj.jdbc.Driver、需要增加时区的配置serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus? useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
6.传统方式pojo-dao(连接mybatis,配置mapper.xml文件)-service-controller
6.使用MyBatisPlus
- pojo
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
- mapper接口
@Repository//持久层
public interface UserMapper extends BaseMapper<User> {
}
- 测试类
首先在主类中配置mapper扫描
@MapperScan(\"com.xust.mapper\")
@SpringBootTest
class MybatisPlusApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
void contextLoads() {
//参数是一个Wrapper,条件构造器,这里先不用
List<User> users=userMapper.selectList(null);
users.forEach(System.out::println);
}
}
配置日志
在开发中使用,通过日志查看sql如何执行
applicatiohn.properties
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
CRUD扩展
插入
@SpringBootTest
class MybatisPlusApplicationTests {
// 测试插入
@Test
public void testInsert() {
User user = new User();
user.setName(\"xust\");
user.setAge(3);
user.setEmail(\"24736743@qq.com\");
int result = userMapper.insert(user); // 帮我们自动生成id
System.out.println(result); // 受影响的行数
System.out.println(user); // 发现,id会自动回填
}
}
更新
@SpringBootTest
class MybatisPlusApplicationTests {
@Autowired
private UserMapper userMapper;
//测试更新
@Test
public void testUpdate(){
User user = new User();
user.setId(1L);
user.setName(\"xxx\");
userMapper.updateById(user);
}
}
自动填充
创建时间、修改时间!这些个操作一遍都是自动化完成的,我们不希望手动更新
我这里使用的是SQLyog
数据库级别操作
代码级别操作
1.首先恢复清除数据库中默认值和更新效果
2.实体类字段属性上需要增加注解
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@TableId(type = IdType.INPUT) //一旦手动输入id后就需要自己配置id了
private Long id;
private String name;
private Integer age;
private String email;
@TableField(fill= FieldFill.INSERT) //插入时自动填充
private Date createTime;
@TableField(fill= FieldFill.INSERT_UPDATE) //插入和更新时自动填充
private Date updateTime;
}
3.编写处理器来处理这个注解
@Slf4j
@Component //将处理器加入到IOC容器中
public class MyMetaObjectHandler implements MetaObjectHandler {
//插入时的填充策略
@Override
public void insertFill(MetaObject metaObject) {
log.info(\"start insert fill...........\");
this.setFieldValByName(\"createTime\",new Date(),metaObject);
this.setFieldValByName(\"updateTime\",new Date(),metaObject);
}
//更新时的填充策略
@Override
public void updateFill(MetaObject metaObject) {
log.info(\"start update fill...........\");
this.setFieldValByName(\"updateTime\",new Date(),metaObject);
}
}
乐观锁
意图:
当更新一条数据时,希望这条数据没有被其他人更新。
- 乐观锁:它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题,再次更新值测试
- 悲观锁:它总是认为总是出现问题,无论干什么都会上锁!再去操作
乐观锁实现方式:
- 取出记录时,获取当前version
- 更新时带上version
- 执行更新时,set version=newVersion where version=oldVersion
- 如果version不对,就更新失败
乐观锁:1、先查询,获得版本号 version = 1
-- A
update user set name = \"kuangshen\", version = version + 1
where id = 2 and version = 1
-- B 线程抢先完成,这个时候 version = 2,会导致 A 修改失败!
update user set name = \"kuangshen\", version = version + 1
where id = 2 and version = 1
测试
1. 数据库添加version字段
2.实体类加对应字段
@Version //乐观锁Version注解
private Integer version;
3.注册组件
@EnableTransactionManagement
@Configuration // 配置类
public class MyBatisPlusConfig { // 注册乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
4.测试
@SpringBootTest
class MybatisPlusApplicationTests {
@Autowired
private UserMapper userMapper;
//测试乐观锁成功
@Test
public void testOptimisticLocker(){
//查询用户信息
User user = userMapper.selectById(1L);
//修改用户信息
user.setName(\"yyy\");
user.setEmail(\"111@qq.com\");
//执行更新操作
userMapper.updateById(user);
}
//测试乐观锁失败
@Test
public void testOptimisticLocker2(){
//A
User user = userMapper.selectById(1L);
user.setName(\"yyy1\");
user.setEmail(\"123@qq.com\");
//B,模拟另外一个线程执行了插队操作
User user2 = userMapper.selectById(1L);
user2.setName(\"yyy2\");
user2.setEmail(\"222@qq.com\");
//B执行更新
userMapper.updateById(user2);
//A执行更新,如果没有乐观锁就会更新
userMapper.updateById(user);
}
}
查询操作
@SpringBootTest
class MybatisPlusApplicationTests {
@Autowired
private UserMapper userMapper;
// 测试查询
@Test
public void testSelectById() {
User user = userMapper.selectById(1L);
System.out.println(user);
}
// 测试批量查询!
@Test
public void testSelectByBatchId() {
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
users.forEach(System.out::println);
}
// 按条件查询之使用map操作
@Test
public void testSelectByBatchIds() {
HashMap<String, Object> map = new HashMap<>();
// 自定义要查询
map.put(\"name\", \"ccc\");
map.put(\"age\", 3);
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}
}
分页查询
1.配置拦截器组件
MyBatisPlusConfig.java
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
2.直接使用Page对象
@SpringBootTest
class MybatisPlusApplicationTests {
@Autowired
private UserMapper userMapper;
//测试分页查询
@Test
public void testPage(){
//参数一:当前页
//参数二:显示条数
Page<User> page=new Page<>(1,3);
userMapper.selectPage(page,null);
//打印当前页
page.getRecords().forEach(System.out::println);
//打印总数
System.out.println(page.getTotal());
}
}
删除操作
根据id删除
@SpringBootTest
class MybatisPlusApplicationTests {
@Autowired
private UserMapper userMapper;
//测试删除
@Test
public void testDeleteById() {
userMapper.deleteById(1579436224978829314L);
}
//批量删除
@Test
public void testDeleteBatchId() {
userMapper.deleteBatchIds(Arrays.asList(1579459015811768322L, 1579459015811768324L));
}
//条件删除map操作
@Test
public void testDeleteMap() {
HashMap<String, Object> map = new HashMap<>();
map.put(\"name\", \"ccc\");
userMapper.deleteByMap(map);
}
}
逻辑删除
物理删除:从数据库中直接移除
逻辑删除:在数据库中没有直接移除,通过一个变量使其失效
1.在数据库表中增加一个deleted字段,为0表示没删
2.实体类中增加属性
@TableLogic //逻辑删除
private Integer deleted;
3.配置
MyBatisPlusConfig.java
// 逻辑删除组件!
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
application.properties
# 配置逻辑删除
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
4.测试
执行之前的删除操作,实际上进行的是update操作
性能分析插件
平时开发时会遇到一些慢SQL
作用:性能分析拦截器,用于输出每条 SQL 语句及其执行时间
在测试和开发环境下使用
1.设置开发环境
application.properties
spring.profiles.active=dev
2.导入插件
MyBatisPlusConfig.java
@Bean
@Profile({\"dev\",\"test\"}) //设置在dev、test环境开启,保证效率
public PerformanceInterceptor performanceInterceptor(){
PerformanceInterceptor performanceInterceptor=new PerformanceInterceptor();
performanceInterceptor.setMaxTime(100); //设置SQL执行的最大时间,超过则不执行
performanceInterceptor.setFormat(true); //是否开启格式化,让SQL查看起来更方便
return performanceInterceptor;
}
条件构造器(Wrapper)
比较重要,写复杂的SQL可以用它来代替
@SpringBootTest
public class WrapperTest {
@Autowired
private UserMapper userMapper;
@Test
void contextLoads() {
//查询name不为空,email不为空,且年龄大于等于12的
QueryWrapper<User> wrapper=new QueryWrapper<>();
wrapper.isNotNull(\"name\")
.isNotNull(\"email\")
.ge(\"age\",12);
userMapper.selectList(wrapper);
}
@Test
void test2() {
//查询name为Tom的
QueryWrapper<User> wrapper=new QueryWrapper<>();
wrapper.eq(\"name\",\"Tom\");
User user = userMapper.selectOne(wrapper);
System.out.println(user);
}
@Test
void test3() {
//查询年龄20~30的人
QueryWrapper<User> wrapper=new QueryWrapper<>();
wrapper.between(\"age\",20,30);
Integer count= userMapper.selectCount(wrapper);//查询结果数
System.out.println(count);
}
//模糊查询
@Test
void test4() {
//name中不包含o,且email以t开头
QueryWrapper<User> wrapper=new QueryWrapper<>();
wrapper.notLike(\"name\",\"o\")
.likeRight(\"email\",\"t\"); //相当于t%
List<Map<String, Object>> maps= userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
@Test
void test5() {
QueryWrapper<User> wrapper=new QueryWrapper<>();
//id在子查询中查出来
wrapper.inSql(\"id\",\"select id from user where id<3\");
List<Object> objects = userMapper.selectObjs(wrapper);
objects.forEach(System.out::println);
}
@Test
void test6() {
QueryWrapper<User> wrapper=new QueryWrapper<>();
//通过id进行排序
wrapper.orderByDesc(\"id\");
List<User> list = userMapper.selectList(wrapper);
list.forEach(System.out::println);
}
}
代码生成器
1.引入相关依赖,配置好数据库
2.写生成器
package com.xust;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.ArrayList;
/**
* @Description: 代码生成器
* @Author: XiePengXiong
* @Date: 2022/10/11 19:46
*/
public class generator {
public static void main(String[] args) {
//构建代码生成器对象
AutoGenerator mpg = new AutoGenerator();
//配置策略
//1.全局配置************************************************************************************************************
GlobalConfig gc = new GlobalConfig(); //generator包下的
String projectPath = System.getProperty(\"user.dir\"); //获取当前项目路径
gc.setOutputDir(projectPath + \"/src/main/java\"); //输出目录
gc.setAuthor(\"xpx\"); //作者
gc.setOpen(false); //生成后是否打开资源管理器(文件夹)
gc.setFileOverride(false); //是否覆盖上次生成的
gc.setServiceName(\"%sService\"); //去Service的I前缀
gc.setIdType(IdType.ID_WORKER); //生成策略
gc.setDateType(DateType.ONLY_DATE); //日期类型
gc.setSwagger2(true); //Swagger
mpg.setGlobalConfig(gc); //将全局配置放入生成器中
//2.设置数据源************************************************************************************************************
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl(\"jdbc:mysql://localhost:3306/kuang_community? useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8\");
dsc.setDriverName(\"com.mysql.cj.jdbc.Driver\");
dsc.setUsername(\"root\");
dsc.setPassword(\"xpx24167830\");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
//3、包的配置************************************************************************************************************
PackageConfig pc = new PackageConfig();
pc.setModuleName(\"blog\");
pc.setParent(\"com.xust\");
pc.setEntity(\"pojo\");
pc.setMapper(\"mapper\");
pc.setService(\"service\");
pc.setController(\"controller\");
mpg.setPackageInfo(pc);
//4、策略配置************************************************************************************************************
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude(\"blog_tags\", \"course\", \"links\", \"sys_settings\", \"user_record\", \" user_say\"); // 设置要映射的表名
strategy.setNaming(NamingStrategy.underline_to_camel); //下划线转驼峰命名
strategy.setColumnNaming(NamingStrategy.underline_to_camel); //下划线转驼峰命名
strategy.setEntityLombokModel(true); // 自动lombok;
strategy.setLogicDeleteFieldName(\"deleted\"); // 逻辑删除
// 自动填充配置
TableFill gmtCreate = new TableFill(\"gmt_create\", FieldFill.INSERT); //创建时间
TableFill gmtModified = new TableFill(\"gmt_modified\", FieldFill.INSERT_UPDATE); //修改时间
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(gmtCreate);
tableFills.add(gmtModified);
strategy.setTableFillList(tableFills);
// 乐观锁
strategy.setVersionFieldName(\"version\");
strategy.setRestControllerStyle(true); //开启驼峰命名
strategy.setControllerMappingHyphenStyle(true); // url转换成下划线localhost:8080/hello_id_2
mpg.setStrategy(strategy);
//执行
mpg.execute();
}
}
来源:https://www.cnblogs.com/LoginX/p/Login_X55.html
本站部分图文来源于网络,如有侵权请联系删除。