一、依賴及配置
使用下面的SQL創建數據庫與添加數據
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)
);
DELETE FROM user;
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');
1、在idea中創建一個SpringBoot項目,在pom.xml中添需要的依賴
添加MyBatis-Plus、mysql連接驅動、lombok的依賴
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
2、配置數據庫連接
application.yml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/mp
username: root
password: 1234
3、在啟動類中添加注解 @MapperScan 掃描Mapper接口包
@SpringBootApplication
@MapperScan("com.jikedaquan.study.mp.mapper")
public class MpApplication {
public static void main(String[] args) {
SpringApplication.run(MpApplication.class, args);
}
}
4、編寫實體類,使用lombok
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
5、編寫UserMapper接口
UserMapper接口繼承MyBatis-Plus提供的BaseMapper接口即可擁有CRUD的方法,泛型中填寫操作的實體類,這里為User
public interface UserMapper extends BaseMapper<User> {
}
6、測試查詢數據
@RunWith(SpringRunner.class)
@SpringBootTest
public class MpApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
public void contextLoads() {
List<User> userList = userMapper.selectList(null);//條件為null時查詢所有數據
userList.forEach(System.out::println);
}
}
二、日志配置
配置日志到控制台輸出
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
三、主鍵生成策略
MyBatis-Plus提供了多種主鍵生成策略以應對不同的場景
策略 | 說明 |
---|---|
AUTO | 數據庫ID自增 |
NONE | 該類型為未設置主鍵類型 |
INPUT | 用戶輸入ID,該類型可以通過自己注冊自動填充插件進行填充 |
ID_WORKER | 全局唯一ID (idWorker) |
UUID | 全局唯一ID (UUID) |
ID_WORKER_STR | 字符串全局唯一ID (idWorker 的字符串表示) |
1、注解控制主鍵生成策略
在實體類的主鍵字段上添加注解(自增時注意配合數據庫設置)
@Data
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
}
2、全局配置控制主鍵生成策略
application.yml
mybatis-plus:
global-config:
db-config:
id-type: id_worker
四、自動填充
在常用業務中有些屬性需要配置一些默認值,MyBatis-Plus提供了實現此功能的插件。在這里修改user表添加 create_time
字段和 update_time
字段,在User類中添加對應屬性。
1、為需要自動填充的屬性添加注解 @TableField
提供了4種自動填充策略:DEFAULT,默認不處理。INSERT,插入填充字段。UPDATE,更新填充字段。INSERT_UPDATE,插入和更新填充字段。
@Data
public class User {
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;
}
2、實現字段填充控制器,編寫自定義填充規則
實現 MetaObjectHandler 接口,實現 insertFill 和 updateFill 方法,此處的 create_time
和update_time
字段需要插入時填充值, 只有 update_time
字段在修改時需要填充,所以策略如下。
//需要將自定義填充控制器注冊為組件
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
private static final Logger LOGGER= LoggerFactory.getLogger(MyMetaObjectHandler.class);
//insert操作時要填充的字段
@Override
public void insertFill(MetaObject metaObject) {
LOGGER.info("start insert fill ...");
//根據屬性名字設置要填充的值
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
}
//update操作時要填充的字段
@Override
public void updateFill(MetaObject metaObject) {
LOGGER.info("start insert fill ...");
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
3、插入數據測試
@RunWith(SpringRunner.class)
@SpringBootTest
public class CRUDTest {
@Autowired
private UserMapper userMapper;
@Test
public void testInsert(){
User user = new User();
user.setName("jack11");
user.setAge(20);
user.setEmail("4849111@qq.com");
int result= userMapper.insert(user);
System.out.println(result);
System.out.println(user);
}
}
4、修改數據測試
@Test
public void testUpdate(){
User user = new User();
user.setId(2L);
user.setName("Jackie");
int result = userMapper.updateById(user);
System.out.println(result);
}
一次插入數據后,
create_time
和update_time
都被填充了設置的時間,做update操作后只有update_time
的進行了填充修改。
五、樂觀鎖插件
樂觀鎖的核心原理就是提交版本必須等於記錄當前版本才能執行更新
意圖:
- 當要更新一條記錄的時候,希望這條記錄沒有被別人更新
樂觀鎖實現方式:
- 取出記錄時,獲取當前version
- 更新時,帶上這個version
- 執行更新時, set version = newVersion where version = oldVersion
- 如果version不對,就更新失敗
1、添加version到表和類中,為屬性添加 @Version 注解
@Version
private Integer version;
2、配置插件
@Configuration
public class MyBatisPlusConfig {
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
}
3、測試修改的兩種情況
@Test
public void testOptimisticLocker1() {
User user = userMapper.selectById(1128212430124097543L);
user.setName("修改后");
int result = userMapper.updateById(user);
if (result == 1) {
System.out.println("修改成功");
} else {
System.out.println("修改失敗");
}
}
@Test
public void testOptimisticLocker2() {
User user = userMapper.selectById(1128212430124097543L);
user.setName("修改后");
user.setVersion(user.getVersion()-1);//測試舊版本
int result = userMapper.updateById(user);
if (result == 1) {
System.out.println("修改成功");
} else {
System.out.println("修改失敗");
}
}
六、分頁插件
啟用分頁插件和啟用樂觀鎖插件都是通過注冊一個Bean完成
1、啟用分頁插件
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
2、測試分頁查詢
@Test
public void testSelectPage(){
//構建分頁條件第二頁每頁顯示3條
Page<User> page=new Page<>(2,3);
//使用分頁條件查詢,不使用其他條件
userMapper.selectPage(page, null);
//獲取分頁后查詢出的記錄
List<User> records = page.getRecords();
records.forEach(System.out::println);
System.out.println("是否有下一頁:"+page.hasNext());
System.out.println("是否有上一頁:"+page.hasPrevious());
System.out.println("總記錄數:"+page.getTotal());
}
七、邏輯刪除插件
有些數據希望不再展示,但在物理上仍然存在,這時可以使用邏輯刪除。邏輯刪除就是在表中添加一個邏輯字段(在上面基礎上添加字段 deleted
),刪除的實質操作就是操作這個邏輯值,在查詢、修改時根據此邏輯值進行近一步操作。
1、啟用邏輯刪除插件
@Bean
public LogicSqlInjector logicSqlInjector(){
return new LogicSqlInjector();
}
2、添加邏輯映射配置
mybatis-plus:
global-config:
db-config:
logic-delete-value: 1 # 邏輯已刪除值(默認為 1)
logic-not-delete-value: 0 # 邏輯未刪除值(默認為 0)
3、邏輯字段添加注解 @TableLogic
@TableLogic
private Integer deleted;
4、測試邏輯刪除
@Test
public void testLogicDelete(){
int result=userMapper.deleteById(1L);
System.out.println(result);
}
觀察日志可以看到生成的sql是update語句
八、性能分析插件
在開發和測試時觀察sql執行耗時
1、配置SpringBoot為開發環境
spring:
profiles:
active: dev
2、啟用插件
@Bean
@Profile({"dev","test"}) //設置 dev test 環境開啟
public PerformanceInterceptor performanceInterceptor(){
return new PerformanceInterceptor();
}
九、CRUD其他操作
@Test
public void testSelectById() {
User user = userMapper.selectById(1L);
System.out.println(user);
}
@Test
public void testSelectBatchIds() {
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
users.forEach(System.out::println);
}
@Test
public void testSelectByMap() {
Map<String, Object> param = new HashMap<>();
param.put("name", "jack");
param.put("age", 18);
List<User> users = userMapper.selectByMap(param);
users.forEach(System.out::println);
}
@Test
public void testSelectMap(){
Page<User> page = new Page<>(2, 3);
IPage<Map<String, Object>> mapIPage = userMapper.selectMapsPage(page, null);
}
@Test
public void testDeleteById(){
int result = userMapper.deleteById(1L);
System.out.println(result);
}
@Test
public void testDeleteBatchIds(){
int result = userMapper.deleteBatchIds(Arrays.asList(2L,3L,4L));
System.out.println(result);
}
歡迎熱愛技術的小伙伴和我交流