1、快速上手
1、新建maven工程(Springboot)
pom.xml添加依赖:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
2、创建实体类
实体类User是根据数据表来创建。
表结构:
User类:
package com.southwind.mybatisplus.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class User {
private Integer id;
private String username;
private Integer age;
}
3、创建mapper接口
mapper接口继承BaseMapper接口,并且泛型就是上面创建的实体类。
由BaseMapper接口的实现类来自动完成增删查改操作。
package com.southwind.mybatisplus.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.southwind.mybatisplus.entity.User;
public interface UserMapper extends BaseMapper<User> {
}
4、配置文件application.yml
datasource配置与数据库连接的信息。
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&useUnicode=true&charaterEncoding=UTF-8
username: root
password: 1234
mybatis-plus:
configuration:
# 输出sql语句
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
6、启动类添加@MapperScan
必须在启动类中加@MapperScan(src)注解,否则无法加载mapper bean
package com.southwind.mybatisplus;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.southwind.mybatisplus.mapper")
public class MybatisplusApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisplusApplication.class, args);
}
}
7、测试类
package com.southwind.mybatisplus.mapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class UserMapperTest {
@Autowired
private UserMapper mapper;
@Test
void test(){
mapper.selectList(null).forEach(System.out::println);
}
}
8、输出
可以看到,MyBatis Plus比MyBatis简直省心太多了,不需要写每个实体类的接口和配置文件,只需要把实体类和接口写出来即可。并且接口也不用手动写方法,只要继承BaseMapper即可。
2、MP常用注解
@TableName
映射数据库的表名
使用@TableName(value = “user”)后,当前类会映射user表。
如果类名就是User的话直接对应user表,可以不加
package com.southwind.mybatisplus.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
@Data
@TableName(value = "user")
public class Account{
private Long id;
private String username;
private Interger age;
}
@TableId
设置主键映射,value映射主键字段名
@TableId( value = "id",type = IdType.ASSIGN_ID)
private Long id;
type设置主键类型以及主键的生成策略
type值 | 描述 |
---|---|
AUTO | 数据库自动自增 |
NONE | MP通过雪花算法设置主键 |
INPUT | 手动赋值 |
ASSIGN_ID | MP分配id。数据类型有Long,Interger,String |
ASSIGN_UUID | 分配UUID,必须是String类型 |
@TableField
映射非主键字段,同样value值映射字段名
@TableField(value = "username",select = false,exist = false)
private String name;
select:表示是否查询该字段。false表示不查询,默认为true查询。
exist:表示是否为数据库字段。如果该成员变量在数据库中没有对应的字段,同时实体类要求有该变量,就将其exist值赋为false。默认为true。
fill:表示是否自动填充。(将对象存进数据库时,由MyBatis Plus自动给某些字段赋值。比如create_time和update_time)
实现自动填充:
1、给表添加create_time和update_time字段,数据类型为datetime
2、实体类中添加成员变量create_time和update_time
FieldFill是枚举,值有DEFAULT、INSERT、UPDATE、INSERT_UPDATE
DEFAULT:默认不处理
INSERT:插入时处理
UPDATE:更新时处理
INSERT_UPDATE:插入以及更新时处理
package com.southwind.mybatisplus.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.southwind.mybatisplus.enums.AgeEnum;
import com.southwind.mybatisplus.enums.StatusEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Date;
@Data
@TableName(value = "user")
public class User {
@TableId( value = "id",type = IdType.ASSIGN_ID)
private Long id;
@TableField(value = "username",select = false)
private String name;
private AgeEnum age;
@TableField(exist = false)
private String gender;
@TableField(fill = FieldFill.INSERT)
private Date create_time;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date update_time;
}
3、创建自动填充处理器
package com.southwind.mybatisplus.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
//当监听到insert或update操作时,添加时间
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("create_time",new Date(),metaObject);
this.setFieldValByName("update_time",new Date(),metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("update_time",new Date(),metaObject);
}
}
4、测试
@Test
void save(){
User user = new User();
user.setName("克里夫");
user.setAge(39);
user.setGender("男");
mapper.insert(user);
}
数据库:
@Version
标记乐观锁,通过version字段来保证数据的安全性,当修改数据时,会以version作为条件,当条件成立时才会修改成功。
1、给数据库表添加version字段,默认值为1
2、实体类添加version成员变量,并且添加@Version注解
package com.southwind.mybatisplus.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.southwind.mybatisplus.enums.AgeEnum;
import com.southwind.mybatisplus.enums.StatusEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Date;
@Data
@TableName(value = "user")
public class User {
@TableId( value = "id",type = IdType.ASSIGN_ID)
private Long id;
@TableField(value = "username",select = false)
private String name;
private Integer age;
@TableField(exist = false)
private String gender;
@TableField(fill = FieldFill.INSERT)
private Date create_time;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date update_time;
@Version
private Integer version;
}
3、注册配置类
package com.southwind.mybatisplus.config;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
}
4、测试代码
@Test
void update(){
User user = mapper.selectById(5);
user.setName("测试1");
User user1 = mapper.selectById(5);
user1.setName("测试2");
mapper.updateById(user1);
mapper.updateById(user);
}
由于user1比user提交的更早一些,因此user1成功更新,版本号+1。因此user1无法成功插入。
@EnumValue
方法1:通用枚举类注解,将数据库字段映射成实体类的枚举类型成员变量。
(1)数据库添加status字段,默认为1
(2)StatusEnum 类
设置枚举。status为0则休息,status为1则上班
package com.southwind.mybatisplus.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
public enum StatusEnum {
WORK(1,"上班"),
REST(0,"休息");
StatusEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
@EnumValue
private Integer code;
private String msg;
}
(3)实体类
status数据类型为StatusEnum
package com.southwind.mybatisplus.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.southwind.mybatisplus.enums.AgeEnum;
import com.southwind.mybatisplus.enums.StatusEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Date;
@Data
@TableName(value = "user")
public class User {
@TableId( value = "id",type = IdType.ASSIGN_ID)
private Long id;
@TableField(value = "username",select = false)
private String name;
private Integer age;
@TableField(exist = false)
private String gender;
@TableField(fill = FieldFill.INSERT)
private Date create_time;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date update_time;
@Version
private Integer version;
private StatusEnum status;
}
(4)application.yml
添加:
type-enums-package:
com.southwind.mybatisplus.enums
(5)测试方法
@Test
void test(){
mapper.selectList(null).forEach(System.out::println);
}
控制台输出:
数据库:
方法2:实现接口
(1)实现类设置枚举字段为enum
private StatusEnum age;
(2)枚举类
1、2、3分别指向一岁,两岁,三岁。
package com.southwind.mybatisplus.enums;
import com.baomidou.mybatisplus.core.enums.IEnum;
public enum AgeEnum implements IEnum<Integer> {
ONE(1,"一岁"),
TWO(2,"两岁"),
THREE(3,"三岁"),
;
private Integer code;
private String msg;
AgeEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
@Override
public Integer getValue() {
return this.code;
}
}
@TableLogic
逻辑删除:不实际删除,而是标记删除。
1、数据表添加deleted字段,默认为0
2、实体类属性添加注解
@TableLogic
private Integer deleted;
3、application.yml添加配置
global-config:
db-config:
logic-not-delete-value: 0
logic-delete-value: 1
3、查询
@Test
void select(){
//不加条件 全部查询
mapper.selectList(null);
//通过id查
mapper.selectById(1);
//通过多个id查
mapper.selectBatchIds(Arrays.asList(2,3,4)).forEach(System.out::println);
//通过Map查
//selectByMap只能做等值判断,逻辑判断得用wrapper
Map<String,Object> map = new HashMap<>();
map.put("id",4);
mapper.selectByMap(map).forEach(System.out::println);
//通过wrapper查
QueryWrapper wrapper = new QueryWrapper();
//一个条件相等
wrapper.eq("username","张三");
//多个条件相等,存在map里,调用wrapper的allEq
Map<String,Object> map = new HashMap<>();
map.put("username","张三");
map.put("age","1");
wrapper.allEq(map);
//小于某条件 less than
wrapper.lt("age","20");
//小于等于某条件 less than
wrapper.le("age","20");
//大于某条件 great than
wrapper.gt("age","20");
//大于等于某条件 great than
wrapper.ge("age","20");
//不等于
wrapper.ne("age","20");
//模糊查询
wrapper.like("username","牛");
//左模糊
wrapper.likeLeft("username","牛");
//右模糊
wrapper.likeRight("username","牛");
//INSQL
wrapper.inSql("id","select id from user where id < 4");
wrapper.inSql("age","select age from user where age < 30");
System.out.println(mapper.selectList(wrapper));
//升序
wrapper.orderByAsc("age");
//降序
wrapper.orderByDesc("age");
wrapper.having("id > 3");
mapper.selectList(wrapper).forEach(System.out::println);
}
QueryWrapper wrapper = new QueryWrapper();
wrapper.gt("id",1);
//selectCount 输出符合条件的个数
System.out.println(mapper.selectCount(wrapper));
//selectMaps 将查询的结果集封装到map中
mapper.selectMaps(wrapper).forEach(System.out::println);
//selectPage 分页查询
Page<User> page = new Page<>(2,2);
Page<User> result = mapper.selectPage(page,null);
System.out.println("result.getSize()= "+result.getSize());
System.out.println("result.getTotal()= "+result.getTotal());
result.getRecords().forEach(System.out::println);
//selectMapsPage 把分页查询结果存放在泛型为Map的page中
Page<Map<String,Object>> page1 = new Page<>(1,2);
mapper.selectMapsPage(page1,null).getRecords().forEach(System.out::println);
//selectObjs 取出所有主键
mapper.selectObjs(null).forEach(System.out::println);
wrapper.eq("id",1);
System.out.println(mapper.selectOne(wrapper));
自定义SQL(多表关联查询)
1、展示数据的VO类
package com.southwind.mybatisplus.entity;
import lombok.Data;
@Data
public class ProductVO {
private Integer category;
private Integer count;
private String description;
private Integer userId;
private String username;
}
2、Mapper类中添加
package com.southwind.mybatisplus.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.southwind.mybatisplus.entity.ProductVO;
import com.southwind.mybatisplus.entity.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserMapper extends BaseMapper<User> {
@Select("select p.*,u.username from product p,user u where u.id = p.user_id and u.id = #{id};")
List<ProductVO> productVOList(Integer id);
}
4、添加
User user = mapper.selectById(7);
user.setName("晓红");
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("age",37);
mapper.update(user,wrapper);
5、删除
//根据id删除
mapper.deleteById(6);
//根据多个id删除
mapper.deleteBatchIds(Arrays.asList(2,4));
//通过wrapper删除
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("age",25);
mapper.delete(wrapper);
//通过map删除
Map<String,Object> map = new HashMap<>();
map.put("id",4);
mapper.deleteByMap(map);
6、修改
User user = mapper.selectById(7);
user.setName("晓红");
//通过wrapper更新,一定要加wrapper条件,不然会全部更新
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("age",37);
mapper.update(user,wrapper);
//直接更新
mapper.updateById(user);
7、MyBatisPlus自动生成
MyBatisPlus可以自动生成controller,entity,mapper和service类。
1、pom.xml导入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.6.2</version>
</dependency>
2、设置启动类
package com.southwind.mybatisplus.mapper;
import com.baomidou.mybatisplus.annotation.DbType;
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;
public class Main {
public static void main(String[] args) {
//创建generator对象
AutoGenerator autoGenerator = new AutoGenerator();
//数据源
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setDbType(DbType.MYSQL);
dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&useUnicode=true&charaterEncoding=UTF-8");
dataSourceConfig.setSchemaName("user");
dataSourceConfig.setUsername("root");
dataSourceConfig.setPassword("1234");
dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
autoGenerator.setDataSource(dataSourceConfig);
//全局配置
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java");
globalConfig.setOpen(false);
globalConfig.setAuthor("southwind");
globalConfig.setServiceName("%sService");
autoGenerator.setGlobalConfig(globalConfig);
//包信息 设置自动生成的包的存放位置
PackageConfig packageConfig = new PackageConfig();
packageConfig.setParent("com.southwind.mybatisplus");
packageConfig.setModuleName("generator");
packageConfig.setController("controller");
packageConfig.setService("service");
packageConfig.setServiceImpl("service.impl");
packageConfig.setMapper("mapper");
packageConfig.setEntity("entity");
autoGenerator.setPackageInfo(packageConfig);
//配置策略
StrategyConfig strategyConfig = new StrategyConfig();
//自动添加lombok注解
strategyConfig.setEntityLombokModel(true);
//选定需要添加的表 默认为所有表
strategyConfig.setInclude("user");
autoGenerator.setStrategy(strategyConfig);
autoGenerator.execute();
}
}
总结
使用起来会发现MyBatisPlus确实要比MyBatis更方便一点,