Mybatis_Plus笔记
1.添加mp启动器
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
2.添加mysql驱动,Druid启动器
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>
3.配置数据源
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver #mysql connector 6以上版本使用,url需要配置serverTimezone
url: jdbc:mysql://localhost:3306/db704b?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 123456
type: com.alibaba.druid.pool.DruidDataSource #连接池类型
initial-size: 5 #数据库连接池初始化的时候连接初始化连接数量;其会在应用程序第一次进行CRUD的时候进行初始化,所以初始化数量并不是越多越好,数量越多第一次操作数据库就会越慢;
min-idle: 5 #最小空闲连接数
max-active: 20 #最大可连接数
max-wait: 60000 #连接池连接用完时,新的请求等待时间
#检查连接空间时间超过minEvictableIdleTimeMillis的连接断开,直到剩余连接数量为min-idle,代表1分钟检查一次
timeBetweenEvictionRunsMillis: 60000 #控制空闲连接数的回收周期,控制回收泄露连接的周期,连接的空闲时间大于该值testWhileIdle才起作用
minEvictableIdleTimeMillis: 300000 #连接池连接可空闲时间
validationQuery: SELECT user() #验证数据库连接是否成功
testWhileIdle: true #在检查空闲连接时同时也检查连接可用性
testOnBorrow: false #取得连接时检查连接可用性
testOnReturn: false #返还连接时检查连接可用性
poolPreparedStatements: true #是否缓存prepareStatement
4.SpringBoot整合mp打印日志到控制台
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #仅用于测试
注意点:
mybatis原生启动器与mp启动器可共存,但建议不要同时出现;
两个启动器都引入了mybatis核心包,有各自的自动配置类,在配置类中都注册SqlSessionFactory对象到spring容器,如果两者同时存在,则MybatisPlusAutoConfiguration生效。
实体类与表名一致,属性名与字段名一致,主键命名为id;
所谓的命名一致,是指数据库命名习惯采用下划线分割多单词命名;实体类使用驼峰命名;
在入门案例中,建议主键命名为id,因为mp默认把属性名为id的当做主键使用;
实体类中属性不能比数据库表多;
在入门案例中,实体类属性与数据库字段保持一致,因为mp根据实体类生成sql语句。
mp常用注解
@TableName
作用:表名注解。
场景:当实体类名与表名不一致时,使用此注解指定表名。如果类名与表名一致,此注解可以省略
@TableName("sys_user")
public class User {
}
@TableId
作用:标注实体类的主键字段。
场景1:当主键字段名称不叫id时,使用@TableId指定主键列对应的属性名。一般主键列命名为id,且使用雪花算法id作为主键值,此注解可以省略。
场景2:对insert语句,指定id的自动生成策略。默认type=IdType.ASSIGN_ID,支持如下策略:
type = IdType.ASSIGN_ID 对于insert操作,mp自动生成雪花算法id赋值到对象中。
type = IdType.AUTO 要求数据库主键自增,int类型主键支持自增
type = IdType.ASSIGN_UUID 随机uuid作为主键,一般不使用,太长。
type = IdType.INPUT mp框架不再生成id,需要开发人员在insert之前手工设置id
@TableField
作用:非主键字段注解
场景1:字段名与属性名不一致;此注解的value属性指定字段名;
场景2:实体类的属性不属于表的字段时,此注解必用;此注解exist = false指定不是数据库表字段;
场景3:用在条件查询上,condition属性指定like非等值查询,配合QueryWrapper条件构建器使用;
@TableField(value="pos_name",condition = SqlCondition.LIKE)
场景4:用在条件查询上,whereStrategy属性指定非null非""属性作为查询条件,配合QueryWrapper条件构建器使用;
@TableField(whereStrategy = FieldStrategy.NOT_EMPTY)
@Version
作用:乐观锁注解,配合mp的乐观锁插件使用
场景:当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁原始实现方式:
数据库添加version字段,默认值1,int类型;
取出记录时,获取当前 version
更新时,带上这个 version
执行更新时, set version = newVersion where version = oldVersion
如果 version 不对,就更新失败
mp提供了乐观锁插件,对update语句进行重写,再mp中使用乐观锁分为两步:
1.全局配置乐观锁插件:OptimisticLockerInnerInterceptor到SqlSessionFactory
2.实体类的version属性上添加@Version注解。
@TableLogic
作用:逻辑删除注解。
项目开发中,重要数据会提供逻辑删除功能,但同时也一定会提供物理删除功能。
mp中的逻辑删除不要用,因为会造成所有select都会带上flag=0条件,无法查询逻辑删除后的数据。
条件构建器
条件构建器是mp提供的用于进行复杂条件查询与复杂修改数据的方法。
QueryWrapper一般用来做数据查询,继承自AbstractWrapper,新增了select方法;
UpdateWrapper一般用来做数据修改,继承自AbstractWrapper,新增了set方法;
AbstractWrapper是两者的父类,定义了各种条件定义方法。
AbstractWrapper
eq = ===》equals
ne != not equals
ge >= gao
gt >
le <= low |less equals
lt <
between 在。。。。之间
like
in where (id) in ()
isNull where id is null
isNotNull
orderBy 排序
QueryWrapper 封装查询条件:我们演示
select 查询
UpdateWrapper 更新条件
set
测试QueryWrapper
@SpringBootTest
@Slf4j
class SpringBootMpApplicationTests {
@Resource
private UserMapper userMapper;
@Test
void contextLoads() {
User user = userMapper.selectById(4);
log.info(user.toString());
}
@Test
public void testList() {
List<User> users = userMapper.selectList(null);
users.forEach(user -> {
log.info(user.toString());
});
}
@Test
public void testBatchList() {
ArrayList<Integer> idList = new ArrayList<>();
idList.add(1);
idList.add(4);
List<User> users = userMapper.selectBatchIds(idList);
users.forEach(user -> {
log.info(user.toString());
});
}
@Test
void insert() {
User user = new User();
// Id 自增
user
.setBirthday(LocalDateTime.now())
.setPassword("123456")
.setPhone("110110")
.setCreateBy(1)
.setCreateTime(LocalDateTime.now())
.setUsername("Mybatis_Plus")
.setUpdateBy(1);
int rows = userMapper.insert(user);
log.info("rows===="+rows);
}
@Test
void updateById() {
User user = new User();
user.setUserId(15);
user.setUsername("javasm-update");
int rows = userMapper.updateById(user);
log.info("rows:"+rows);
}
@Test
public void testQueryWrapper() {
QueryWrapper queryWrapper = new QueryWrapper<User>();
queryWrapper.likeLeft("username", "天才");
List list = userMapper.selectList(queryWrapper);
list.forEach(user -> {
System.out.println(user.toString());
});
}
@Test
void queryWrapper1() {
User user = new User();
user.setUsername("天才");
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(user);
List<User> users = userMapper.selectList(userQueryWrapper);
users.forEach(System.out::println);
}
@Test
void queryWrapper() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", "1", "2", "5").like("username", "运营人员").orderByDesc("id");
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
@Test
void queryWrapper5() {
LambdaQueryWrapper<User> lambda = new LambdaQueryWrapper<>();
lambda.in(User::getUserId, "1", "2", "5").eq(User::getUsername, "运营人员").orderByDesc(User::getUserId);
List<User> userList = userMapper.selectList(lambda);
userList.forEach(user -> {
log.info(user.toString());
});
}
测试UpdateWrapper
@Test
void updateWrapper1() {
// 根据user对象进行set修改, 对非null属性进行set
User user = new User();
user.setPassword("789100");
UpdateWrapper updateWrapper = new UpdateWrapper<>();
updateWrapper.set("password", "132456");
updateWrapper.eq("username", "天才");
int update = userMapper.update(null, updateWrapper);
}
}
内置插件
乐观锁插件
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//添加乐观锁插件,配合@Version注解指定实体类的乐观锁字段
//在调用mybatis-plus的update方法时,自动进行乐观锁实现
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
public class SysUser {
@Version
private Integer version;//乐观锁字段
}
测试:
@Test
void updateById() {
// User user = userMapper.selectById(5);
User user = new User();
user.setId(5);
user.setUsername("重紫333");
user.setVersion(1);
int rows = userMapper.updateById(user); // update user set username = '重紫' ,version= 2 ,where version = 1
log.info("rows:" + rows);
}
评论区