快速入门
创建表
sql
create database mybatis_plus;
use mybatis_plus;
create table user(
id bigint(20) not null comment '主键ID',
name varchar(30) default null comment '姓名',
age int(11) default null comment '年龄',
email varchar(50) default null comment '邮箱',
primary key (id)
)engine =InnoDB default charset =utf8;
添加数据
sql
INSERT INTO `user` (id, name, age, email) VALUES
(1, 'Jone', 18, '[email protected]'),
(2, 'Jack', 20, '[email protected]'),
(3, 'Tom', 28, '[email protected]'),
(4, 'Sandy', 21, '[email protected]'),
(5, 'Billie', 24, '[email protected]');
导依赖
xml
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
<scope>runtime</scope>
</dependency>
配置文件
xml
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
yaml
spring:
# 配置数据源信息
datasource:
# 配置数据源类型
type: com.zaxxer.hikari.HikariDataSource
# 配置连接数据库的各个信息
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
username: root
password: 20050606a
实体类
java
package com.wang.mybatisplusexe.pojo;
import lombok.Data;
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
java
package com.wang.mybatisplusexe.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wang.mybatisplusexe.pojo.User;
public interface UserMapper extends BaseMapper<User> {
}
java
package com.wang.mybatisplusexe;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
//扫描mapper接口所在的包
@MapperScan("com.wang.mybatisplusexe.mapper")
public class MybatisPlusExeApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisPlusExeApplication.class, args);
}
}
java
@SpringBootTest
public class MyBatisPlusTest {
@Autowired
private UserMapper userMapper;
@Test
public void testSelectList() {
//通过条件构造器查询一个list集合,若没有条件,则可以设置null为参数
List<User> list = userMapper.selectList(null);
list.forEach(System.out::println);
}
@Test
public void testInsert() {
//实现新增用户信息
//INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
User user = new User();
user.setName("张三");
user.setAge(23);
user.setEmail("[email protected]");
int insert = userMapper.insert(user);
System.out.println(insert);
System.out.println("id:" + user.getId());
}
@Test
public void testDelete() {
//通过id删除用户信息
//DELETE FROM user WHERE id=?
// int result = userMapper.deleteById(1860660370114965506L);
// System.out.println("result:" + result);
//根据map集合中所设置的条件删除用户信息
//DELETE FROM user WHERE name = ? AND age = ?
// HashMap<String, Object> map = new HashMap<>();
// map.put("name","张三");
// map.put("age",23);
// int result = userMapper.deleteByMap(map);
// System.out.println("result:" + result);
//通过多个id实现批量删除
//DELETE FROM user WHERE id IN ( ? , ? , ? )
List<Long> list = Arrays.asList(1L, 2L, 3L);
int result = userMapper.deleteBatchIds(list);
System.out.println("result" + result);
}
@Test
public void testUpdate(){
//修改用户信息
//UPDATE user SET name=?, email=? WHERE id=?
User user = new User();
user.setId(4L);
user.setName("李四");
user.setEmail("[email protected]");
int result = userMapper.updateById(user);
System.out.println("result"+result);
}
@Test
public void testSelect(){
//SELECT id,name,age,email FROM user WHERE id=?
//通过id查询用户信息
/*User user = userMapper.selectById(1L);
System.out.println(user);*/
//根据多个id查询多个用户信息
//SELECT id,name,age,email FROM user WHERE id IN ( ? , ? , ? )
// List<Long> list = Arrays.asList(1L, 2L, 3L);
// List<User> users = userMapper.selectBatchIds(list);
// users.forEach(System.out::println);
//根据map集合中的条件查询用户信息
//SELECT id,name,age,email FROM user WHERE name = ? AND age = ?
// HashMap<String, Object> map = new HashMap<>();
// map.put("name", "Jack");
// map.put("age", 20);
// List<User> list = userMapper.selectByMap(map);
// list.forEach(System.out::println);
//查询所有数据
//SELECT id,name,age,email FROM user
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
}
加日志
yaml
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
自定义功能
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wang.mybatisplusexe.mapper.UserMapper">
<!--Map<String,Object> selectMapById(Long id);-->
<select id="selectMapById" resultType="map">
select id,name,age,email from user where id=#{id}
</select>
</mapper>
java
package com.wang.mybatisplusexe.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wang.mybatisplusexe.pojo.User;
import org.springframework.stereotype.Repository;
import java.util.Map;
@Repository
public interface UserMapper extends BaseMapper<User> {
/**
* 根据id查询用户信息为map集合
*/
Map<String,Object> selectMapById(Long id);
}
通用Service接口
java
package com.wang.mybatisplusexe.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.wang.mybatisplusexe.pojo.User;
public interface UserService extends IService<User> {
}
java
package com.wang.mybatisplusexe.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wang.mybatisplusexe.mapper.UserMapper;
import com.wang.mybatisplusexe.pojo.User;
import com.wang.mybatisplusexe.service.UserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {
}
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wang.mybatisplusexe.mapper.UserMapper">
<!--Map<String,Object> selectMapById(Long id);-->
<select id="selectMapById" resultType="map">
select id,name,age,email from user where id=#{id}
</select>
</mapper>
java
@SpringBootTest
public class MyBatisPlusServiceTest {
@Autowired
private UserService userService;
@Test
public void testGetCount(){
//查询总记录数
//SELECT COUNT( * ) FROM user
long count = userService.count();
System.out.println(count);
}
@Test
public void testInsertMore(){
//批量添加
//INSERT INTO user ( id, name, age ) VALUES ( ?, ?, ? )
ArrayList<User> list = new ArrayList<>();
for(int i=0;i<=10;i++){
User user = new User();
user.setName("wang"+i);
user.setAge(20+i);
list.add(user);
}
boolean b = userService.saveBatch(list);
System.out.println(b);
}
}
常用注解
java
@Data
//设置实体类所对应的表名
@TableName("t_user")
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
yaml
# 设置MyBatis-Plus的全局配置
global-config:
db-config:
# 设置实体类所在的表的统一前缀
table-prefix: t_
java
@Data
//设置实体类所对应的表名
//@TableName("t_user")
public class User {
//将属性所对应的字段指定为主键
//@TableId注解的value属性用于指定主键的字段
//@TableId注解的type属性设置主键生成策略
@TableId(value = "uid",type = IdType.AUTO)
private Long id;
//指定属性所对应的字段名
@TableField("user_name")
private String name;
private Integer age;
private String email;
@TableLogic
private Integer isDeleted;
}
yaml
# 设置统一的主键生成策略
id-type: auto
雪花算法

条件构造器
QueryWrapper
java
@SpringBootTest
public class MyBatisPlusWrapperTest {
@Autowired
private UserMapper userMapper;
@Test
public void test01(){
//查询用户名包含a,年龄在20到30之间,邮箱信息不为null的用户信息
//SELECT uid AS id,user_name AS name,age,email,is_deleted
// FROM t_user WHERE is_deleted=0
// AND (user_name LIKE ? AND age BETWEEN ?
// AND ? AND email IS NOT NULL)
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("user_name","a")
.between("age",20,30)
.isNotNull("email");
List<User> list = userMapper.selectList(queryWrapper);
list.forEach(System.out::println);
}
}
java
@Test
public void test02(){
//查询用户信息,按照年龄的降序排序,若年龄相同,则按照id升序排序
//SELECT uid AS id,user_name AS name,age,email,is_deleted
//FROM t_user WHERE is_deleted=0 ORDER BY age DESC,uid ASC
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("age")
.orderByAsc("uid");
List<User> list = userMapper.selectList(queryWrapper);
list.forEach(System.out::println);
}
java
@Test
public void test03(){
//删除邮箱地址为null的用户信息
//UPDATE t_user SET is_deleted=1
//WHERE is_deleted=0 AND (email IS NULL)
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.isNull("email");
int result = userMapper.delete(queryWrapper);
System.out.println("result"+result);
}
java
@Test
public void test04(){
//将(年龄大于20并且用户名中包含有a)或邮箱为null的用户信息修改
//UPDATE t_user SET user_name=?, email=? WHERE is_deleted=0
// AND (age > ? AND user_name LIKE ? OR email IS NULL)
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age",20)
.like("user_name","a")
.or()
.isNull("email");
User user=new User();
user.setName("小明");
user.setEmail("[email protected]");
int result = userMapper.update(user, queryWrapper);
System.out.println("result"+result);
}
java
@Test
public void test05() {
//将用户名中包含有a并且(年龄大于20或邮箱为null)的用户信息修改
//lambda中的条件优先执行
//UPDATE t_user SET user_name=?, email=? WHERE is_deleted=0
//AND (user_name LIKE ? AND (age > ? OR email IS NULL))
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("user_name", "a")
.and(i->i.gt("age", 20).or().isNull("email"));
User user = new User();
user.setName("小红");
user.setEmail("[email protected]");
int result = userMapper.update(user, queryWrapper);
System.out.println("result" + result);
}
java
@Test
public void test06(){
//查询用户的用户名、年龄、邮箱信息
//SELECT user_name,age,email FROM t_user WHERE is_deleted=0
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("user_name","age","email");
List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);
maps.forEach(System.out::println);
}
java
@Test
public void test07() {
//查询id小于等于100的用户信息
//SELECT uid AS id,user_name AS name,age,email,is_deleted
// FROM t_user WHERE is_deleted=0
// AND (uid IN (select uid from t_user where uid<=100))
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.inSql("uid", "select uid from t_user where uid<=100");
List<User> list = userMapper.selectList(queryWrapper);
list.forEach(System.out::println);
}
UpdateWrapper
java
@Test
public void test08(){
//将用户名中包含有a并且(年龄大于20或邮箱为null)的用户信息修改
//UPDATE t_user SET user_name=?,email=?
//WHERE is_deleted=0
//AND (user_name LIKE ? AND (age > ? OR email IS NULL))
UpdateWrapper<User> updateWrapper=new UpdateWrapper<>();
updateWrapper.like("user_name", "a")
.and(e->e.gt("age",20).or().isNull("email"));
updateWrapper.set("user_name","小黑").set("email","[email protected]");
int result = userMapper.update(null, updateWrapper);
System.out.println("result" + result);
}
condition
java
@Test
public void test09(){
// SELECT uid AS id,user_name AS name,age,email,is_deleted
// FROM t_user WHERE is_deleted=0 AND (age >= ? AND age <= ?)
String userName="";
Integer ageBegin=20;
Integer ageEnd=30;
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
if(StringUtils.isNotBlank(userName)){
//isNotBlank判断某个字符串是否不为空字符串、不为null、不为空白符
queryWrapper.like("user_name",userName);
}
if(ageBegin!=null){
queryWrapper.ge("age",ageBegin);
}
if(ageEnd!=null){
queryWrapper.le("age",ageEnd);
}
List<User> list = userMapper.selectList(queryWrapper);
list.forEach(System.out::println);
}
java
@Test
public void test10(){
//SELECT uid AS id,user_name AS name,age,email,is_deleted
//FROM t_user WHERE is_deleted=0 AND (user_name LIKE ?)
String username="a";
Integer ageBegin=null;
Integer ageEnd=null;
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
queryWrapper.like(StringUtils.isNotBlank(username),"user_name",username)
.ge(ageBegin!=null,"age",ageBegin)
.le(ageEnd!=null,"age",ageEnd);
List<User> list = userMapper.selectList(queryWrapper);
list.forEach(System.out::println);
}
lambdaQueryWrapper
java
@Test
public void test11(){
String username="a";
Integer ageBegin=null;
Integer ageEnd=30;
LambdaQueryWrapper<User> queryWrapper=new LambdaQueryWrapper<>();
queryWrapper.like(StringUtils.isNotBlank(username),User::getName,username)
.ge(ageBegin!=null,User::getAge,ageBegin)
.le(ageEnd!=null,User::getAge,ageEnd);
List<User> list = userMapper.selectList(queryWrapper);
list.forEach(System.out::println);
}
lambdaUpdateWrapper
java
@Test
public void test12(){
//将用户名中包含有a并且(年龄大于20或邮箱为null)的用户信息修改
//UPDATE t_user SET user_name=?,email=?
//WHERE is_deleted=0
//AND (user_name LIKE ? AND (age > ? OR email IS NULL))
LambdaUpdateWrapper<User> updateWrapper=new LambdaUpdateWrapper<>();
updateWrapper.like(User::getName, "a")
.and(e->e.gt(User::getAge,20).or().isNull(User::getEmail));
updateWrapper.set(User::getName,"小黑").set(User::getEmail,"[email protected]");
int result = userMapper.update(null, updateWrapper);
System.out.println("result" + result);
}
插件
分页插件
配置类
java
@Configuration
//扫描mapper接口所在的包
@MapperScan("com.wang.mybatisplusexe.mapper")
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
测试
java
@SpringBootTest
public class MyBatisPlusPluginsTest {
@Autowired
private UserMapper userMapper;
@Test
public void testPage() {
//SELECT uid AS id,user_name AS name,age,email,is_deleted
//FROM t_user WHERE is_deleted=0 LIMIT ?
Page<User> page = new Page<>(1, 3);
userMapper.selectPage(page, null);
System.out.println(page);
}
}
java
@Test
public void testPage() {
//SELECT uid AS id,user_name AS name,age,email,is_deleted
//FROM t_user WHERE is_deleted=0 LIMIT ?
Page<User> page = new Page<>(1, 3);
userMapper.selectPage(page, null);
System.out.println(page.getRecords());
System.out.println(page.getPages());
System.out.println(page.getTotal());
System.out.println(page.hasNext());
System.out.println(page.hasPrevious());
}
自定义分页功能
java
@Repository
public interface UserMapper extends BaseMapper<User> {
/**
* 根据id查询用户信息为map集合
*/
Map<String, Object> selectMapById(Long id);
/**
* 根据年龄查询用户并分页
* @param page MyBatis-Plus所提供的分页对象,必须位于第一个参数的位置
* @param age
* @return
*/
Page<User> selectPageVo(@Param("page") Page<User> page, @Param("age") Integer age);
}
properties
# 配置类型别名所对应的包
type-aliases-package: com.wang.mybatisplusexe.pojo
java
<!-- Page<User> selectPageVo(@Param("page") Page<User> page, @Param("age") Integer age);-->
<select id="selectPageVo" resultType="com.wang.mybatisplusexe.pojo.User">
select uid, user_name, age, email
from t_user
where age > #{age}
</select>
java
@Test
public void testPageVo(){
//select uid, user_name, age, email from t_user where age > ? LIMIT ?
Page<User> page = new Page<>(1, 3);
userMapper.selectPageVo(page,20);
System.out.println(page.getRecords());
System.out.println(page.getPages());
System.out.println(page.getTotal());
System.out.println(page.hasNext());
System.out.println(page.hasPrevious());
}
乐观锁插件
java
@Configuration
//扫描mapper接口所在的包
@MapperScan("com.wang.mybatisplusexe.mapper")
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
java
@Repository
public interface ProductMapper extends BaseMapper<Product> {
}
java
@Data
public class Product {
private Long id;
private String name;
private Integer price;
@Version//标识乐观锁版本号字段
private Integer version;
}
java
@Test
public void testProduct(){
//小李查询商品价格
Product productLi=productMapper.selectById(1);
System.out.println("小李查询的商品价格:"+productLi.getPrice());
//小王查询商品价格
Product productWang = productMapper.selectById(1);
System.out.println("小王查询的商品价格"+productWang.getPrice());
//小李将商品价格+50
productLi.setPrice(productLi.getPrice()+50);
productMapper.updateById(productLi);
//小王将商品价格-30
productWang.setPrice(productWang.getPrice()-30);
int result = productMapper.updateById(productWang);
if(result==0){
//操作失败,重试
Product productNew = productMapper.selectById(1);
productNew.setPrice(productNew.getPrice()-30);
productMapper.updateById(productNew);
}
//老板查询商品价格
Product productBoss = productMapper.selectById(1);
System.out.println("老板查询的商品价格"+productBoss.getPrice());
}
通用枚举
yaml
# 扫描通用枚举的包
type-enums-package: com.wang.mybatisplusexe.enums
java
@Getter
public enum SexEnum {
MALE(1, "男"),
FEMALE(2, "女");
@EnumValue//将注解所标识的属性的值存储到数据库中
private Integer sex;
private String sexName;
SexEnum(Integer sex, String sexName) {
this.sex = sex;
this.sexName = sexName;
}
}
java
@SpringBootTest
public class MyBatisPlusEnumTest {
@Autowired
private UserMapper userMapper;
@Test
public void test(){
User user = new User();
user.setName("admin");
user.setAge(33);
user.setSex(SexEnum.MALE);
int result = userMapper.insert(user);
System.out.println("result:"+result);
}
}
代码生成器
xml
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.9</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.32</version>
</dependency>
java
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false",
"root",
"20050606a")
.globalConfig(builder -> builder
.author("wang")
.outputDir("D://code//text")
.commentDate("2024-11-27")
)
.packageConfig(builder -> builder
.parent("com.wang")
.entity("entity")
.mapper("mapper")
.service("service")
.serviceImpl("service.impl")
.xml("mapper.xml")
)
.strategyConfig(builder -> builder
.entityBuilder()
.enableLombok()
)
.templateEngine(new FreemarkerTemplateEngine())
.execute();
}
多数据源
xml
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
yaml
spring:
# 配置数据源信息
datasource:
dynamic:
# 设置默认的数据源或者数据源组,默认值即为master
primary: master
# 严格匹配数据源,默认false.true未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
master:
url: jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 20050606a
slave_1:
url: jdbc:mysql://localhost:3306/mybatis_plus_1?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 20050606a
java
@Service
@DS("slave_1")
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
}
java
@Service
@DS("master")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
java
@SpringBootTest
class MybatisPlusDatasourceApplicationTests {
@Autowired
private ProductService productService;
@Autowired
private UserService userService;
@Test
public void test() {
System.out.println(productService.getById(1));
System.out.println(userService.getById(1));
}
}
MyBatisX插件
MyBatis-Plus为我们提供了强大的mapper和service模板,能够大大的提高开发效率。
但是在真正开发过程中,MyBatis-Plus并不能为我们解决所有问题,例如一些复杂的SQL,多表联查,我们就需要自己去编写代码和SQL语句,我们该如何快速的解决这个问题呢,这个时候可以使用MyBatisX插件。
MyBatisX一款基于IDEA的快速开发插件,为效率而生。