序章
MyBatis-Plus (新しいウィンドウが開きます) (略して MP) は、 MyBatis (新しいウィンドウが開きます)の拡張ツール
特性
侵入なし: 機能強化のみで変更はありません。導入しても既存のプロジェクトには影響せず、シルクのようにスムーズです。
低損失: 基本的な CURD は起動時に自動的に挿入され、パフォーマンスは基本的に損失がなく、オブジェクト指向の操作が直接実行されます。
強力な CRUD 操作: 汎用マッパーと汎用サービスが組み込まれており、単一テーブルに対する CRUD 操作のほとんどがわずかな設定で実現でき、さまざまな使用ニーズを満たす強力な条件コンストラクターがあります。
Lambdaフォーム呼び出しのサポート:Lambda式を介して、さまざまなクエリ条件を記述するのが便利で、フィールドのタイプミスを心配する必要はありません
自動主キー生成をサポート: 最大 4 つの主キー戦略 (分散固有 ID ジェネレーター - シーケンスを含む) をサポートし、主キーの問題を完全に解決するために自由に構成できます。
ActiveRecord モードのサポート: ActiveRecord フォーム呼び出しをサポートします。エンティティ クラスは Model クラスを継承するだけで強力な CRUD 操作を実行できます。
カスタムのグローバル一般操作をサポート: グローバル一般メソッド インジェクションをサポート (一度書いたらどこでも使用可能)
組み込みのコード ジェネレーター: コードまたは Maven プラグインを使用して、マッパー、モデル、サービス、コントローラー レイヤー コード、サポート テンプレート エンジン、およびその他のカスタム構成を迅速に生成します。
組み込みのページング プラグイン: MyBatis の物理ページングに基づいており、開発者は特定の操作を気にする必要はありません。プラグインの設定後、ページングの記述は通常のリスト クエリと同等です。
ページング プラグインは複数のデータベースをサポートします。MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer およびその他のデータベースをサポートします。
組み込みのパフォーマンス分析プラグイン: SQL ステートメントとその実行時間を出力できます。遅いクエリを迅速に発見できるため、開発およびテスト中にこの機能を有効にすることをお勧めします。
組み込みのグローバル インターセプト プラグイン: テーブル全体に対する削除および更新操作のインテリジェントな分析とブロックを提供し、誤操作を防ぐためにインターセプト ルールをカスタマイズすることもできます。
サポートデータベース
CRUD に MyBatis を使用でき、標準 SQL をサポートするデータベース。具体的なサポートは次のとおりです。以下のリストにない場合は、サポートについてチュートリアル PR のページネーション部分を確認してください。
MySQL、Oracle、DB2、H2、HSQL、SQLite、PostgreSQL、SQLServer、Phoenix、Gauss、ClickHouse、Sybase、OceanBase、Firebird、Cubrid、Goldilocks、csiidb、informix、TDengine、redshift
大蒙データベース、徐谷データベース、人民大学金倉データベース、南達総合(華岳)データベース、南達総合データベース、神通データベース、漢高データベース、友宣データベース
クイックスタート
依存関係を追加する
新しい MyBatis-Plus 3.0 バージョンは JDK8 に基づいており、ラムダ呼び出しを提供するため、MP3.0 のインストールと統合の要件は次のとおりです。
JDK 8+
Maven または Gradle
Spring Boot プロジェクト
メイブン:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>最新版本</version>
</dependency>
春のプロジェクト
メイブン:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>最新版本</version>
</dependency>
構成
H2 データベースの関連する設定を application.yml 設定ファイルに追加します。
# DataSource Config
spring:
datasource:
driver-class-name: org.h2.Driver
schema: classpath:db/schema-h2.sql
username: root
password: test
sql:
init:
schema-locations: classpath:db/schema-h2.sql
data-locations: classpath:db/data-h2.sql
@MapperScan アノテーションを Spring Boot スタートアップ クラスに追加して、Mapper フォルダーをスキャンします。
@SpringBootApplication
@MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
ページ
方法 1:
mybatis-plusのサービスページインターフェースを使用する
@GetMapping("/pageList")
@ApiOperation(value = "分页列表", notes = "query和user")
public R<IPage<User>> pageList(@ApiIgnore User user, Query query) {
//无条件分页
IPage<User> pages = userService.page(Condition.getPage(query));
//有条件分页
IPage<User> pages = userService.page(Condition.getPage(query), Wrappers.lambdaQuery(user));
return R.data(pages);
}
方法 2:
カスタム SQL ページネーション
コントローラー層のコード:
@GetMapping("/pageList")
@ApiOperation(value = "分页列表", notes = "query和user")
public R<IPage<User>> pageList(@ApiIgnore User user, Query query) {
IPage<User> pages = userService.selectUserPage(Condition.getPage(query), user);
return R.data(pages);
}
サービスでカスタム ページング SQL マッパー メソッドを呼び出す
@Override
public IPage<User> selectUserPage(IPage<User> page, User user) {
return page.setRecords(baseMapper.selectUserPage(page, user));
}
マッパー ページング インターフェイスを定義します。
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gis.spacedata.bladex.domain.entity.system.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.List;
public interface UserMapper extends BaseMapper<User> {
List<User> selectUserPage(IPage<User> page, @Param("user") User user);
}
mybatis XML:
<select id="selectUserPage" resultMap="userResultMap">
select * from blade_user where is_deleted = 0
<if test="user.tenantId!=null and user.tenantId != ''">
and tenant_id = #{user.tenantId}
</if>
<if test="user.account!=null and user.account != ''">
and account like CONCAT('%',#{user.account},'%')
</if>
<if test="user.realName!=null and user.realName != ''">
and real_name like CONCAT('%',#{user.realName},'%')
</if>
<if test="user.roleId!=null and user.roleId != ''">
and CAST(#{user.roleId} AS VARCHAR)= ANY(STRING_TO_ARRAY(role_id, ','))
</if>
ORDER BY id
</select>
条件ツールクラス:
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springblade.core.launch.constant.TokenConstant;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import java.util.Map;
/**
* 分页工具
*
* @author Chill
*/
public class Condition {
/**
* 转化成mybatis plus中的Page
*
* @param query 查询条件
* @return IPage
*/
public static <T> IPage<T> getPage(Query query) {
Page<T> page = new Page<>(Func.toInt(query.getCurrent(), 1), Func.toInt(query.getSize(), 10));
page.setAsc(Func.toStrArray(SqlKeyword.filter(query.getAscs())));
page.setDesc(Func.toStrArray(SqlKeyword.filter(query.getDescs())));
return page;
}
/**
* 获取mybatis plus中的QueryWrapper
*
* @param entity 实体
* @param <T> 类型
* @return QueryWrapper
*/
public static <T> QueryWrapper<T> getQueryWrapper(T entity) {
return new QueryWrapper<>(entity);
}
/**
* 获取mybatis plus中的QueryWrapper
*
* @param query 查询条件
* @param clazz 实体类
* @param <T> 类型
* @return QueryWrapper
*/
public static <T> QueryWrapper<T> getQueryWrapper(Map<String, Object> query, Class<T> clazz) {
Kv exclude = Kv.create().set(TokenConstant.HEADER, TokenConstant.HEADER)
.set("current", "current").set("size", "size").set("ascs", "ascs").set("descs", "descs");
return getQueryWrapper(query, exclude, clazz);
}
/**
* 获取mybatis plus中的QueryWrapper
*
* @param query 查询条件
* @param exclude 排除的查询条件
* @param clazz 实体类
* @param <T> 类型
* @return QueryWrapper
*/
public static <T> QueryWrapper<T> getQueryWrapper(Map<String, Object> query, Map<String, Object> exclude, Class<T> clazz) {
exclude.forEach((k, v) -> query.remove(k));
QueryWrapper<T> qw = new QueryWrapper<>();
qw.setEntity(BeanUtil.newInstance(clazz));
SqlKeyword.buildCondition(query, qw);
return qw;
}
}
方法 3:
mybatis-plusを使用したDBクラス
例証します:
静的呼び出しを使用して CRUD メソッドを実行し、Spring 環境でのサービス ループ インジェクションを回避し、コードを簡素化し、効率を向上させます。
プロジェクト内の対応するエンティティに注入する必要がある BaseMapper
完全な使用方法を参照:テストケース(新しいウィンドウが開きます)
パラメータ Wrapper の場合、対応する Mapper を見つけるために、Wrapper に Entity または EntityClass を渡す必要があります。
ループ内で呼び出すことは推奨されません。バッチで保存する場合は、構築後に Db.saveBatch(data) を使用してデータを保存することをお勧めします。
@Test
void testPage() {
IPage<Entity> page = Db.page(new Page<>(1, 1), Entity.class);
Assertions.assertEquals(2, page.getTotal());
page = Db.page(new Page<>(1, 1), Wrappers.lambdaQuery(Entity.class));
Assertions.assertEquals(1, page.getRecords().size());
}
ページネーションプラグイン
奇妙なのは、クエリするデータがまだすべてのデータであり、ページング効果が達成されていないことです。
ページングの原理はどこまでが限界であることは誰もが知っています。
つまり、このクエリ ステートメントの後に where 条件を追加するだけで、このステートメントをインターセプトして where 条件を追加できます。これは、AOP アイデアの撤回でもあります (元のコードを強化するだけで、変更はありません)。
プラグイン本体MybatisPlusInterceptor
このプラグインはコア プラグインであり、現在 Executor#query、Executor#update、StatementHandler#prepare メソッドをプロキシします。
インナーインターセプター
弊社が提供するプラグインは、このインターフェースに基づいた機能を実装します。
現在利用可能な機能:
自動ページネーション: PaginationInnerInterceptor
マルチテナント: TenantLineInnerInterceptor
動的テーブル名: DynamicTableNameInnerInterceptor
オプティミスティック ロック: OptimisticLockerInnerInterceptor
SQL プロパティ: IllegalSQLInnerInterceptor
テーブル全体の更新と削除を防止: Block AttackInnerInterceptor
ページネーションプラグインの設定
Spring トランザクション、MybatisPlus ページング プラグイン、Mybatis パッケージ スキャンおよびその他の構成
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* spring事务、MybatisPlus分页插件、mybatis包扫描等配置
*
* @author tarzan liu
* @since JDK1.8
* @date 2021年5月11日
*/
@EnableTransactionManagement
@Configuration
@MapperScan(basePackages = "com.tarzan.**.mapper")
public class MybatisPlusConfig {
/**
* 分页插件
*/
@Bean
public MybatisPlusInterceptor paginationInterceptor() {
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
paginationInnerInterceptor.setMaxLimit(-1L);
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);
return mybatisPlusInterceptor;
}
}
コード内の paginationInnerInterceptor.setMaxLimit(-1L); は、最大ページ数に制限がないことを意味しており、デフォルトでは、最大制限は 1 ページあたり 500 個のデータです。