1つ、挿入
1
、挿入操作
@RunWith(SpringRunner.class)
@SpringBootTest
public class CRUDTests {
@Autowired
private UserMapper userMapper;
@Test
public void testInsert(){
User user = new User();
user.setName("Helen");
user.setAge(18);
user.setEmail("[email protected]");
int result = userMapper.insert(user);
System.out.println(result); //影响的行数
System.out.println(user); //id自动回填
}
}
注:データベースの挿入ID値のデフォルトは次のとおりです。グローバルに一意のID
2.主キー戦略
(1)ID_WORKER
MyBatis-Plusのデフォルトの主キー戦略は次のとおりです。ID_WORKERグローバル一意ID
参考資料:分散システムの一意のID生成スキームの概要:https://www.cnblogs.com/haoxinyue/p/5208136.html
(2)自己インクリメント戦略
主キーを自動インクリメントするには、次の主キー戦略を構成する必要があります
。データテーブルを作成するときに主キーの自動インクリメントを設定する必要があります。エンティティフィールドで@TableId(type = IdType.AUTO)を構成します。
@TableId(type = IdType.AUTO)
private Long id;
すべてのエンティティの構成に影響を与えるために、グローバル主キー構成を設定できます
#全局设置主键生成策略
mybatis-plus.global-config.db-config.id-type=auto
その他の主な戦略:IdTypeのソースコードを分析して知る
@Getter
public enum IdType {
/**
* 数据库ID自增
*/
AUTO(0),
/**
* 该类型为未设置主键类型
*/
NONE(1),
/**
* 用户输入ID
* 该类型可以通过自己注册自动填充插件进行填充
*/
INPUT(2),
/* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
/**
* 全局唯一ID (idWorker)
*/
ID_WORKER(3),
/**
* 全局唯一ID (UUID)
*/
UUID(4),
/**
* 字符串全局唯一ID (idWorker 的字符串表示)
*/
ID_WORKER_STR(5);
private int key;
IdType(int key) {
this.key = key;
}
}
二、更新
1.IDに従って操作を更新します
注:更新中に生成されるSQLは、自動的に動的SQLになります。UPDATEuserSET age =?WHERE id =?
@Test
public void testUpdateById(){
User user = new User();
user.setId(1L);
user.setAge(28);
int result = userMapper.updateById(user);
System.out.println(result);
}
2.自動充填
プロジェクトで頻繁に遭遇するデータもあり、レコードの作成時間や新しい時間など、毎回同じ方法で入力されます。
MyBatis Plusの自動入力機能を使用して、次のフィールドの割り当てを完了することができます。
(1)データベーステーブルに自動入力フィールドを追加します
Userテーブルにdatetimeタイプcreate_time、update_timeの新しいフィールドを追加します
(2)エンティティに注釈を追加します
@Data
public class User {
......
@TableField(fill = FieldFill.INSERT)
private Date createTime;
//@TableField(fill = FieldFill.UPDATE)
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
}
(3)メタオブジェクトプロセッサインターフェイスを実装する
注:@Componentアノテーションを追加することを忘れないでください
package com.atguigu.mybatisplus.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(MyMetaObjectHandler.class);
@Override
public void insertFill(MetaObject metaObject) {
LOGGER.info("start insert fill ....");
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
LOGGER.info("start update fill ....");
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}
(4)テスト
3.楽観的ロック
主なアプリケーションシナリオ:レコードを更新する場合、このレコードが他のユーザーによって更新されていないことを期待します。つまり、更新はスレッドセーフなデータを実現することです。
楽観的ロックの実装:
レコードが取得されたとき、現在のバージョンが
更新されたとき、バージョン
行がこのバージョンで更新されたとき、set version = newVersion where version = oldVersion
バージョンが正しくない場合、更新の実行は失敗します
(1)バージョンフィールドをデータベースに追加します
ALTER TABLE `user` ADD COLUMN `version` INT
(2)バージョンフィールドをエンティティクラスに追加します
そして@Versionアノテーションを追加します
@Version
@TableField(fill = FieldFill.INSERT)
private Integer version;
(3)バージョンの挿入デフォルト値をメタオブジェクトハンドラインターフェイスに追加します
@Override
public void insertFill(MetaObject metaObject) {
......
this.setFieldValByName("version", 1, metaObject);
}
特記事項:
サポートされているデータ型は、int、Integer、long、Long、Date、Timestamp、LocalDateTimeのみです。
整数型では、newVersion = oldVersion + 1
newVersionがエンティティに書き戻されます
。updateById(id)とupdate(entity、wrapper)のみ)メソッドは
update(entity、wrapper)メソッドでサポートされており、ラッパーは再利用できません!!!
(4)MybatisPlusConfigにBeanを登録します
構成クラスを作成する
package com.atguigu.mybatisplus.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement
@Configuration
@MapperScan("com.atguigu.mybatis_plus.mapper")
public class MybatisPlusConfig {
/**
* 乐观锁插件
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
(5)テスト楽観的ロックは正常に変更できます
テスト後、出力されたsqlステートメントを分析し、バージョンの値に1を追加します
/**
* 测试 乐观锁插件
*/
@Test
public void testOptimisticLocker() {
//查询
User user = userMapper.selectById(1L);
//修改数据
user.setName("Helen Yao");
user.setEmail("[email protected]");
//执行更新
userMapper.updateById(user);
}
(5)楽観的ロックの変更のテストに失敗しました
/**
* 测试乐观锁插件 失败
*/
@Test
public void testOptimisticLockerFail() {
//查询
User user = userMapper.selectById(1L);
//修改数据
user.setName("Helen Yao1");
user.setEmail("[email protected]");
//模拟取出数据后,数据库中version实际数据比取出的值大,即已被其它线程修改并更新了version
user.setVersion(user.getVersion() - 1);
//执行更新
userMapper.updateById(user);
}
3、選択
1.IDに基づいてレコードをクエリします
@Test
public void testSelectById(){
User user = userMapper.selectById(1L);
System.out.println(user);
}
2.複数のIDを介したバッチクエリ
動的SQLのforeach関数を完了しました
@Test
public void testSelectBatchIds(){
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
users.forEach(System.out::println);
}
3.単純な条件クエリ
マップを介してクエリ条件をカプセル化する
@Test
public void testSelectByMap(){
HashMap<String, Object> map = new HashMap<>();
map.put("name", "Helen");
map.put("age", 18);
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}
注:マップ内のキーは、データベース内の列名に対応しています。たとえば、データベースuser_id、エンティティクラスはuserIdである場合、マップのキーはuser_idを入力する必要があります
4.ページングMyBatisPlusにはページングプラグインが付属しており、ページング機能は簡単な構成で実現できます。
(1)構成クラスを作成します
このとき、メインクラスの@MapperScanスキャンアノテーションを削除できます
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
(2)selectPageページングをテストする
テスト:最終的にページオブジェクトを介して関連データを取得します
@Test
public void testSelectPage() {
Page<User> page = new Page<>(1,5);
userMapper.selectPage(page, null);
page.getRecords().forEach(System.out::println);
System.out.println(page.getCurrent());
System.out.println(page.getPages());
System.out.println(page.getSize());
System.out.println(page.getTotal());
System.out.println(page.hasNext());
System.out.println(page.hasPrevious());
}
コンソールのSQLステートメントは次のように出力します:SELECT id、name、age、email、create_time、update_time FROM user LIMIT 0,5
(3)selectMapsPageページングをテストします。結果セットはMapです。
@Test
public void testSelectMapsPage() {
Page<User> page = new Page<>(1, 5);
IPage<Map<String, Object>> mapIPage = userMapper.selectMapsPage(page, null);
//注意:此行必须使用 mapIPage 获取记录列表,否则会有数据类型转换错误
mapIPage.getRecords().forEach(System.out::println);
System.out.println(page.getCurrent());
System.out.println(page.getPages());
System.out.println(page.getSize());
System.out.println(page.getTotal());
System.out.println(page.hasNext());
System.out.println(page.hasPrevious());
}
四、delete
1.IDに基づいてレコードを削除します
@Test
public void testDeleteById(){
int result = userMapper.deleteById(8L);
System.out.println(result);
}
2.バッチ削除
@Test
public void testDeleteBatchIds() {
int result = userMapper.deleteBatchIds(Arrays.asList(8, 9, 10));
System.out.println(result);
}
3.単純なクエリの削除
@Test
public void testDeleteByMap() {
HashMap<String, Object> map = new HashMap<>();
map.put("name", "Helen");
map.put("age", 18);
int result = userMapper.deleteByMap(map);
System.out.println(result);
}
4.トゥームストーン
物理的削除:実際の削除、対応するデータはデータベースから削除され、削除されたデータは後で照会できません
論理的削除:誤った削除、対応するデータのフィールドの状態を「削除された状態」に変更すると、データベースでこのデータレコードを引き続き確認できます。
(1)削除したフィールドをデータベースに追加します
ALTER TABLE `user` ADD COLUMN `deleted` boolean
(2)削除したフィールドをエンティティクラスに追加します
そして、@ TableLogicアノテーションと@TableField(fill = FieldFill.INSERT)アノテーションを追加します
@TableLogic
@TableField(fill = FieldFill.INSERT)
private Integer deleted;
(3)削除された挿入デフォルト値をメタオブジェクトハンドラインターフェイスに追加します
@Override
public void insertFill(MetaObject metaObject) {
......
this.setFieldValByName("deleted", 0, metaObject);
}
(4)Application.properties結合構成
これはデフォルト値です。デフォルト値がmpdefaultと同じである場合、この構成は必要ありません。
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
(5)MybatisPlusConfigにBeanを登録します
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
(6)テストロジックの削除
テスト後、データが削除されておらず、削除されたフィールドの値が0から1に変更されていることがわかります。
テスト後に出力されたSQLステートメントを分析します。これは更新です。
注:論理的削除を実行するために選択する前に、削除されたデータの削除済みフィールドの値が0である必要があります。
/**
* 测试 逻辑删除
*/
@Test
public void testLogicDelete() {
int result = userMapper.deleteById(1L);
System.out.println(result);
}
(7)論理削除をテストした後のクエリ
MyBatis Plusのクエリ操作でも、論理削除フィールドの判断が自動的に追加されます
/**
* 测试 逻辑删除后的查询:
* 不包括被逻辑删除的记录
*/
@Test
public void testLogicDeleteSelect() {
User user = new User();
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
テスト後に出力されたSQLステートメントを分析し
ます。これにはWHEREdeleted = 0 SELECT id、name、age、email、create_time、update_time、deletedFROMユーザーWHEREdeleted = 0が含まれます。
5、パフォーマンス分析
パフォーマンス分析インターセプターは、各SQLステートメントとその実行時間を出力するために使用されます。
開発環境で使用されるSQLパフォーマンス実行分析は、指定された時間を超えると実行を停止します。問題を見つけるのを手伝ってください
1.プラグインを構成します
(1)パラメータの説明
パラメータ:maxTime:SQL実行の最大時間。超過すると自動的に実行を停止します。これは、問題の検出に役立ちます。
パラメータ:format:SQLがフォーマットされているかどうか、デフォルトはfalseです。
(2)MybatisPlusConfigで構成します
/**
* SQL 执行性能分析插件
* 开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长
*/
@Bean
@Profile({"dev","test"})// 设置 dev test 环境开启
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(100);//ms,超过此处设置的ms则sql不执行
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
(3)SpringBootでの開発環境のセットアップ
#环境设置:dev、test、prod
spring.profiles.active=dev
環境ごとに異なる構成ファイルapplication-dev.properties、application-test.properties、application-prod.propertiesを作成できます
test1、test2などの環境名をカスタマイズすることもできます。
2.テスト
(1)定期テスト
/**
* 测试 性能分析插件
*/
@Test
public void testPerformance() {
User user = new User();
user.setName("我是Helen");
user.setEmail("[email protected]");
user.setAge(18);
userMapper.insert(user);
}
出力:
(2)maxTimeを小さい値に変更した後、再度テストします
performanceInterceptor.setMaxTime(5);//ms,超过此处设置的ms不执行
実行時間が長すぎると、例外がスローされます。SQLの実行時間が長すぎると、次のように
出力されます。
6、その他
複雑な条件クエリを実行する場合は、条件ビルダーWapperを使用する必要があります。これには、次のメソッド
1、delete
2、selectOne
3、selectCountが含まれます。
4、selectList
5、selectMaps
6、selectObjs
7、更新