一、基本环境
1、导依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!-- 数据库驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!-- mybatis-plus --> <!-- mybatis-plus 是自己开发,并非官方的! --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.0.5</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
2、数据库
3、实体类:
@Data @AllArgsConstructor @NoArgsConstructor public class User { private Long id; private String name; private Integer age; private String email; private Date createTime; private Date updateTime; private Integer version; private Integer del; }
mapper:mapper需要去继承mp的BaseMapper接口。之后在service层调用其中的实现方法即可
@Mapper public interface UserMapper extends BaseMapper<User> { }
启动类:
@MapperScan("com.mp.mpdemo.mapper") @SpringBootApplication public class MpDemoApplication { public static void main(String[] args) { SpringApplication.run(MpDemoApplication.class, args); } }
4、yml/properties文件
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 # 配置日志,控制台可以看见执行的sql语句 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
此时测试一下是否成功:
@Service public class UserServiceImpl implements UserService { @Autowired UserMapper userMapper; public void sel(){ // 查询全部用户 List<User> users = userMapper.selectList(null); System.out.println("查询所有用户:"+users); } }
最后执行方法结果
二、表属性的一些设置约束
我们将上面的实体类利用mp的注解配置一下:
@Data @AllArgsConstructor @NoArgsConstructor @TableName(value = "user") //1、表名 public class User { @TableId(value = "id",type = IdType.AUTO) //2、主键,及其插入模式 private Long id; private String name; private Integer age; private String email; @TableField(value = "create_time",fill = FieldFill.INSERT) //3、不同名的自动填充属性 private Date createTime; @TableField(value = "update_time",fill = FieldFill.INSERT_UPDATE) private Date updateTime; @TableField(fill = FieldFill.INSERT)//自动填充,默认乐观锁初始值为1 @Version //4、乐观锁属性 private Integer version; @TableLogic(value = "0",delval = "1") //5、逻辑删除 @TableField(fill = FieldFill.INSERT)//自动填充 private int del; @TableField(exist = false) //6、不在表中的属性 private String abc; }
1、配置表名映射
【@TableName 】 @TableName 用于定义表名 注: 常用属性: value 用于定义表名
像上面的实体类中表名配置使用:@TableName(value = "user")
注意:如果表名相同则可以不用配置。
2、主键配置
【@TableId】 @TableId 用于定义表的主键 注: 常用属性: value 用于定义主键字段名 type 用于定义主键类型(主键策略 IdType) 主键策略: IdType.AUTO 主键自增,系统分配,不需要手动输入 IdType.NONE 未设置主键 IdType.INPUT 需要自己输入 主键值。 IdType.ASSIGN_ID 系统分配 ID,用于数值型数据(Long,对应 mysql 中 BIGINT 类型)。 IdType.ASSIGN_UUID 系统分配 UUID,用于字符串型数据(String,对应 mysql 中 varchar(32) 类型)。
像上面的主键配置我配置了为默认值,value可以配置不同命名的映射,可以根据自己的需求配置不同值:
@TableId(value = "id",type = IdType.AUTO) //2、主键,及其插入模式 private Long id;
3、非主键的表字段配置:这里会有自动填充、是否为表属性、命名映射
【@TableField】 @TableField 用于定义表的非主键字段。 注: 常用属性: value 用于定义非主键字段名 exist 用于指明是否为数据表的字段, true 表示是,false 为不是。 fill 用于指定字段填充策略(FieldFill)。 字段填充策略:(一般用于填充 创建时间、修改时间等字段) FieldFill.DEFAULT 默认不填充 FieldFill.INSERT 插入时填充 FieldFill.UPDATE 更新时填充 FieldFill.INSERT_UPDATE 插入、更新时填充。
上面的实体类中,我设置了两个时间属性的自动填充、指定不为表属性、命名映射的配置:
@TableField(value = "create_time",fill = FieldFill.INSERT) //3、不同名的自动填充属性,插入是自动填充 private Date createTime; @TableField(value = "update_time",fill = FieldFill.INSERT_UPDATE)//插入和更新时自动插入。 private Date updateTime; @TableField(exist = false) //6、不在表中的属性 private String abc;
此时自动填充除了要在实体类中加上注解外还需要告诉spring要自动注入什么值:
编写一个配置类来说明要注入的值:
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; import java.util.Date; @Slf4j @Component // 一定不要忘记把处理器加到IOC容器中! public class MyMetaObjectHandler implements MetaObjectHandler { // 插入时的填充策略 @Override public void insertFill(MetaObject metaObject) { log.info("start insert fill....."); // setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject 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); } }
测试:执行下面的代码
//插入数据 //createTime和updateTime不设置,使用自动填充 //del使用自动填充的1/0 User user = new User(); user.setAge(11); user.setEmail("123@qq.com"); user.setName("aaa"); user.setVersion(1); userMapper.insert(user);
此时发现createTime、updateTime都自动注入了。
4、逻辑删除:
【@TableLogic】 @TableLogic 用于定义表的字段进行逻辑删除(非物理删除) 注: 常用属性: value 用于定义未删除时字段的值 delval 用于定义删除时字段的值
上面的实体类:
@TableLogic(value = "0",delval = "1") //5、逻辑删除 @TableField(fill = FieldFill.INSERT) private int del;
此时还要去配置插入时默认为0,在前面自动填充createTime的配置类MyMetaObjectHandler 加上del属性的自动填充配置:(该拦截器和注解@TableField联合使用,注解会触发此拦截器,从而给deleted属性进行默认赋值)
@Slf4j @Component // 一定不要忘记把处理器加到IOC容器中! public class MyMetaObjectHandler implements MetaObjectHandler { // 插入时的填充策略 @Override public void insertFill(MetaObject metaObject) { log.info("start insert fill....."); // setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject //1、这是createTime、updateTime的注入值配置 this.setFieldValByName("createTime",new Date(),metaObject); this.setFieldValByName("updateTime",new Date(),metaObject); //2、这是del属性注入值的配置 this.setFieldValByName("del", 0,metaObject); } // 更新时的填充策略 @Override public void updateFill(MetaObject metaObject) { log.info("start update fill....."); this.setFieldValByName("updateTime",new Date(),metaObject); } }
再向spring中注入逻辑删除组件(该拦截器和逻辑删除注解@TableLogic联合使用,@TableLogic逻辑删除注解会触发此拦截器,从而对数据进行逻辑删除,即把deleted置为1)
@Configuration // 配置类 public class MybatisPlusConfig { @Bean public ISqlInjector sqlInjector() { return new LogicSqlInjector(); } }
测试:先向数据库插入数据,再进行逻辑删除
User user = new User(); user.setAge(11); user.setEmail("123@qq.com"); user.setName("aaa"); user.setVersion(1); userMapper.insert(user); userMapper.deleteById(Long.valueOf(11));
控制台:
查看数据库:
5、乐观锁配置:
【@Version】 @Version 用于字段实现乐观锁
上面的实体类:
@Version //4、乐观锁属性 private Integer version;
此时上面的实体类常用的mp注解都配置好了,下面对这些配置进行检验。
再向MybatisPlusConfig中配置一个组件:
/** * 乐观锁插件 * @return 乐观锁插件的实例 */ @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); }
此时进行测试:往数据库中插入数据,不进行手动赋值version
//先往其中插入一条数据 User user = new User(); user.setAge(11); user.setEmail("1888@qq.com"); user.setName("aaa"); userMapper.insert(user); //更新这条数据 user.setAge(18); userMapper.update(user,null);
控制台:
(乐观锁和逻辑删除需要配置组件+自动值注入的配置)
6、分页插件
往MybatisPlusConfig配置类中加入分页组件/插件
/** * 分页插件 * @return 分页插件的实例 */ @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); }
测试用法:执行下面代码,先new一个Page对象,并且设置两个参数——查询第几页、每页数据量。
Page<User> userPage = new Page<User>(1,2);//查询第一页,每页数据为2条 userMapper.selectPage(userPage,null);
控制台打印:
注意:
MybatisPlus3.4版本后的分页和乐观锁使用失效,查了一下新的使用方式,在配置类中进行如下编写,将分页和乐观锁写在一起了。
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//分页插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());//乐观锁插件
return interceptor;
}
三、curd操作
一、Mapper接口的curd
二、Service接口的curd