永続化レイヤーインターフェース
本文では、MyBatis-Plus を使用した永続化操作の各種メソッドについて詳しく説明します。挿入、更新、削除、検索、ページネーションなどを含みます。本稿を通じて、MyBatis-Plus が提供する各種メソッドがどのようにデータ操作を行うか、およびそれらに対応する SQL 文について理解することができます。
Service インターフェース
IService は MyBatis-Plus が提供する汎用 Service 層インターフェースであり、挿入、削除、クエリ、ページングなどの一般的な CRUD 操作をカプセル化しています。IService インターフェースを継承することで、データベースに対する基本的な操作を迅速に実装でき、コードの簡潔さと保守性を維持できます。
IService インターフェース内のメソッド名は一定の規約に従って命名されています。例えば、get
は単一行のクエリに、remove
は削除に、list
はコレクションのクエリに、page
はページングクエリに使用され、これにより Mapper 層のメソッドとの混同を避けることができます。
save
// 插入一条记录(选择字段,策略插入)boolean save(T entity);// 插入(批量)boolean saveBatch(Collection<T> entityList);// 插入(批量)boolean saveBatch(Collection<T> entityList, int batchSize);
機能説明: レコードを挿入します。エンティティオブジェクトのフィールドに基づいて戦略的な挿入を行います。
戻り値: boolean、挿入操作が成功したかどうかを示します。
パラメータ説明:
型 | パラメータ名 | 説明 |
---|---|---|
T | entity | エンティティオブジェクト |
Collection<T> | entityList | エンティティオブジェクトのコレクション |
int | batchSize | 挿入バッチサイズ |
例(save):
// User エンティティオブジェクトがあると仮定User user = new User();user.setName("John Doe");user.setEmail("john.doe@example.com");boolean result = userService.save(user); // save メソッドを呼び出しif (result) { System.out.println("User saved successfully.");} else { System.out.println("Failed to save user.");}
生成される SQL:
INSERT INTO user (name, email) VALUES ('John Doe', 'john.doe@example.com')
例(saveBatch):
// 一連の User エンティティオブジェクトがあると仮定List<User> users = Arrays.asList( new User("Alice", "alice@example.com"), new User("Bob", "bob@example.com"), new User("Charlie", "charlie@example.com"));// デフォルトのバッチサイズで一括挿入を実行boolean result = userService.saveBatch(users); // saveBatch メソッドを呼び出し、デフォルトのバッチサイズを使用if (result) { System.out.println("Users saved successfully.");} else { System.out.println("Failed to save users.");}
生成される SQL(デフォルトのバッチサイズが 3 と仮定):
INSERT INTO user (name, email) VALUES('Alice', 'alice@example.com'),('Bob', 'bob@example.com'),('Charlie', 'charlie@example.com')
例(saveBatch でバッチサイズを指定):
// 一連の User エンティティオブジェクトがあると仮定List<User> users = Arrays.asList( new User("David", "david@example.com"), new User("Eve", "eve@example.com"), new User("Frank", "frank@example.com"), new User("Grace", "grace@example.com"));// バッチサイズを 2 に指定して一括挿入を実行boolean result = userService.saveBatch(users, 2); // saveBatch メソッドを呼び出し、バッチサイズを指定if (result) { System.out.println("Users saved successfully.");} else { System.out.println("Failed to save users.");}
生成される SQL(バッチサイズを 2 に指定):
-- 第1バッチINSERT INTO user (name, email) VALUES('David', 'david@example.com'),('Eve', 'eve@example.com')
-- 第2バッチINSERT INTO user (name, email) VALUES('Frank', 'frank@example.com'),('Grace', 'grace@example.com')
上記の例から、save シリーズのメソッドが Service 層でどのように一括挿入操作を行うか、およびそれらに対応する SQL 文を確認できます。これらのメソッドは挿入操作のコード記述を大幅に簡素化し、開発効率を向上させます。
saveOrUpdate
// TableId 注解属性值存在则更新记录,否插入一条记录boolean saveOrUpdate(T entity);// 批量修改插入boolean saveOrUpdateBatch(Collection<T> entityList);// 批量修改插入boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
機能説明: エンティティオブジェクトの主キーIDに基づいて判断し、存在する場合はレコードを更新、存在しない場合はレコードを挿入します。
戻り値: boolean、挿入または更新操作が成功したかどうかを示します。
パラメータ説明:
型 | パラメータ名 | 説明 |
---|---|---|
T | entity | エンティティオブジェクト |
Wrapper<T> | updateWrapper | エンティティオブジェクトをカプセル化する操作クラス UpdateWrapper |
Collection<T> | entityList | エンティティオブジェクトのコレクション |
int | batchSize | 挿入バッチサイズ |
例(saveOrUpdate):
// Userエンティティオブジェクトがあり、idがTableIdアノテーションの属性であると仮定User user = new User();user.setId(1);user.setName("John Doe");user.setEmail("john.doe@example.com");boolean result = userService.saveOrUpdate(user); // saveOrUpdateメソッドを呼び出しif (result) { System.out.println("ユーザーの更新または保存が成功しました。");} else { System.out.println("ユーザーの更新または保存に失敗しました。");}
生成されるSQL(idが1のレコードが存在すると仮定):
UPDATE user SET name = 'John Doe', email = 'john.doe@example.com' WHERE id = 1
生成されるSQL(idが1のレコードが存在しないと仮定):
INSERT INTO user (id, name, email) VALUES (1, 'John Doe', 'john.doe@example.com')
例(saveOrUpdateBatch):
// 各オブジェクトにid属性を持つUserエンティティオブジェクトのグループがあると仮定List<User> users = Arrays.asList( new User(1, "Alice", "alice@example.com"), new User(2, "Bob", "bob@example.com"), new User(3, "Charlie", "charlie@example.com"));// デフォルトのバッチサイズで一括更新挿入を実行boolean result = userService.saveOrUpdateBatch(users); // saveOrUpdateBatchメソッドを呼び出し、デフォルトのバッチサイズif (result) { System.out.println("ユーザーの一括更新または保存が成功しました。");} else { System.out.println("ユーザーの一括更新または保存に失敗しました。");}
生成されるSQL(idが1と2のレコードが存在し、idが3のレコードが存在しないと仮定):
UPDATE user SET name = 'Alice', email = 'alice@example.com' WHERE id = 1UPDATE user SET name = 'Bob', email = 'bob@example.com' WHERE id = 2INSERT INTO user (id, name, email) VALUES (3, 'Charlie', 'charlie@example.com')
例(saveOrUpdateBatch バッチサイズ指定):
// Userエンティティオブジェクトのグループがあると仮定List<User> users = Arrays.asList( new User(4, "David", "david@example.com"), new User(5, "Eve", "eve@example.com"), new User(6, "Frank", "frank@example.com"));// バッチサイズを2に指定して一括更新挿入を実行boolean result = userService.saveOrUpdateBatch(users, 2); // saveOrUpdateBatchメソッドを呼び出し、バッチサイズを指定if (result) { System.out.println("ユーザーの一括更新または保存が成功しました。");} else { System.out.println("ユーザーの一括更新または保存に失敗しました。");}
生成されるSQL(バッチサイズが2に指定されていると仮定):
-- 第1バッチUPDATE user SET name = 'David', email = 'david@example.com' WHERE id = 4UPDATE user SET name = 'Eve', email = 'eve@example.com' WHERE id = 5
-- 第2バッチINSERT INTO user (id, name, email) VALUES (6, 'Frank', 'frank@example.com')
上記の例から、saveOrUpdateシリーズのメソッドがService層でどのように一括更新挿入操作を実行するか、およびそれらに対応するSQL文を確認できます。これらのメソッドは、異なる条件に基づいて更新または挿入操作を実行する効率的なデータ操作方法を提供します。
remove
// 根据 queryWrapper 设置的条件,删除记录boolean remove(Wrapper<T> queryWrapper);// 根据 ID 删除boolean removeById(Serializable id);// 根据 columnMap 条件,删除记录boolean removeByMap(Map<String, Object> columnMap);// 删除(根据ID 批量删除)boolean removeByIds(Collection<? extends Serializable> idList);
機能説明: 指定された条件に一致するレコードを削除します。
戻り値: boolean、削除操作が成功したかどうかを示します。
パラメータ説明:
型 | パラメータ名 | 説明 |
---|---|---|
Wrapper<T> | queryWrapper | エンティティラッパークラス QueryWrapper |
Serializable | id | 主キー ID |
Map<String, Object> | columnMap | テーブルカラム map オブジェクト |
Collection<? extends Serializable> | idList | 主キー ID リスト |
例(remove):
// QueryWrapper オブジェクトがあり、削除条件を name = 'John Doe' に設定していると仮定QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "John Doe");boolean result = userService.remove(queryWrapper); // remove メソッドを呼び出しif (result) { System.out.println("Record deleted successfully.");} else { System.out.println("Failed to delete record.");}
生成される SQL:
DELETE FROM user WHERE name = 'John Doe'
例(removeById):
// ID が 1 のユーザーを削除すると仮定boolean result = userService.removeById(1); // removeById メソッドを呼び出しif (result) { System.out.println("User deleted successfully.");} else { System.out.println("Failed to delete user.");}
生成される SQL:
DELETE FROM user WHERE id = 1
例(removeByMap):
// columnMap があり、削除条件を age = 30 に設定していると仮定Map<String, Object> columnMap = new HashMap<>();columnMap.put("age", 30);boolean result = userService.removeByMap(columnMap); // removeByMap メソッドを呼び出しif (result) { System.out.println("Records deleted successfully.");} else { System.out.println("Failed to delete records.");}
生成される SQL:
DELETE FROM user WHERE age = 30
例(removeByIds):
// ID リストのグループがあり、ユーザーを一括削除すると仮定List<Integer> ids = Arrays.asList(1, 2, 3);boolean result = userService.removeByIds(ids); // removeByIds メソッドを呼び出しif (result) { System.out.println("Users deleted successfully.");} else { System.out.println("Failed to delete users.");}
生成される SQL:
DELETE FROM user WHERE id IN (1, 2, 3)
上記の例から、remove シリーズのメソッドが Service 層でどのように削除操作を行うか、およびそれらに対応する SQL 文を確認できます。これらのメソッドは柔軟なデータ操作方法を提供し、さまざまな条件に基づいて削除操作を行うことができます。
update
// 根据 UpdateWrapper 条件,更新记录 需要设置sqlsetboolean update(Wrapper<T> updateWrapper);// 根据 whereWrapper 条件,更新记录boolean update(T updateEntity, Wrapper<T> whereWrapper);// 根据 ID 选择修改boolean updateById(T entity);// 根据ID 批量更新boolean updateBatchById(Collection<T> entityList);// 根据ID 批量更新boolean updateBatchById(Collection<T> entityList, int batchSize);
機能説明: 指定された条件に基づいて、条件に一致するレコードを更新します。
戻り値: boolean、更新操作が成功したかどうかを示します。
パラメータ説明:
型 | パラメータ名 | 説明 |
---|---|---|
Wrapper<T> | updateWrapper | エンティティオブジェクトをカプセル化する操作クラス UpdateWrapper |
T | entity | エンティティオブジェクト |
Collection<T> | entityList | エンティティオブジェクトコレクション |
int | batchSize | 更新バッチ数 |
例(update UpdateWrapper 形式):
// UpdateWrapper オブジェクトがあり、更新条件を name = 'John Doe' に設定し、更新フィールドを email に設定していると仮定UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();updateWrapper.eq("name", "John Doe").set("email", "john.doe@newdomain.com");boolean result = userService.update(updateWrapper); // update メソッドを呼び出しif (result) { System.out.println("Record updated successfully.");} else { System.out.println("Failed to update record.");}
生成される SQL:
UPDATE user SET email = 'john.doe@newdomain.com' WHERE name = 'John Doe'
例(update WhereWrapper 形式):
// User エンティティオブジェクトがあり、更新フィールドを name に設定し、whereWrapper で更新条件を id = 1 に設定していると仮定User updateEntity = new User();updateEntity.setName("Updated Name");QueryWrapper<User> whereWrapper = new QueryWrapper<>();whereWrapper.eq("id", 1);boolean result = userService.update(updateEntity, whereWrapper); // update メソッドを呼び出しif (result) { System.out.println("Record updated successfully.");} else { System.out.println("Failed to update record.");}
生成される SQL:
UPDATE user SET name = 'Updated Name' WHERE id = 1
例(updateById):
// User エンティティオブジェクトがあり、更新フィールドを email に設定し、ID に基づいて更新していると仮定User updateEntity = new User();updateEntity.setId(1);updateEntity.setEmail("updated.email@example.com");boolean result = userService.updateById(updateEntity); // updateById メソッドを呼び出しif (result) { System.out.println("Record updated successfully.");} else { System.out.println("Failed to update record.");}
生成される SQL:
UPDATE user SET email = 'updated.email@example.com' WHERE id = 1
例(updateBatchById):
// 一連の User エンティティオブジェクトがあり、バッチ更新を実行していると仮定List<User> users = Arrays.asList( new User(1, null, "new.email1@example.com"), new User(2, null, "new.email2@example.com"));boolean result = userService.updateBatchById(users); // updateBatchById メソッドを呼び出し、デフォルトのバッチサイズを使用if (result) { System.out.println("Records updated successfully.");} else { System.out.println("Failed to update records.");}
生成される SQL(デフォルトのバッチサイズが 2 と仮定):
UPDATE user SET email = 'new.email1@example.com' WHERE id = 1UPDATE user SET email = 'new.email2@example.com' WHERE id = 2
例(updateBatchById バッチサイズ指定):
// 一連の User エンティティオブジェクトがあり、バッチ更新を実行し、バッチサイズを 1 に指定していると仮定List<User> users = Arrays.asList( new User(1, null, "new.email1@example.com"), new User(2, null, "new.email2@example.com"));boolean result = userService.updateBatchById(users, 1); // updateBatchById メソッドを呼び出し、バッチサイズを指定if (result) { System.out.println("Records updated successfully.");} else { System.out.println("Failed to update records.");}
生成される SQL(バッチサイズが 1 と指定されていると仮定):
-- 第1バッチUPDATE user SET email = 'new.email1@example.com' WHERE id = 1-- 第2バッチUPDATE user SET email = 'new.email2@example.com' WHERE id = 2
上記の例を通じて、update
シリーズのメソッドが Service 層でどのように更新操作を実行するか、およびそれらに対応する SQL 文を確認できます。これらのメソッドは、さまざまな条件に基づいて更新操作を実行するための柔軟なデータ操作方法を提供します。
get
// 根据 ID 查询T getById(Serializable id);// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")T getOne(Wrapper<T> queryWrapper);// 根据 Wrapper,查询一条记录T getOne(Wrapper<T> queryWrapper, boolean throwEx);// 根据 Wrapper,查询一条记录Map<String, Object> getMap(Wrapper<T> queryWrapper);// 根据 Wrapper,查询一条记录<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
機能説明: 指定された条件に基づいて一致するレコードを検索します。
戻り値: 検索結果。エンティティオブジェクト、Mapオブジェクト、またはその他の型である可能性があります。
パラメータ説明:
型 | パラメータ名 | 説明 |
---|---|---|
Serializable | id | 主キー ID |
Wrapper<T> | queryWrapper | エンティティオブジェクトをカプセル化する操作クラス QueryWrapper |
boolean | throwEx | 複数の結果がある場合に例外をスローするかどうか |
T | entity | エンティティオブジェクト |
Function<? super Object, V> | mapper | 変換関数 |
例(getById):
// ID が 1 のユーザーを検索する場合User user = userService.getById(1); // getById メソッドを呼び出すif (user != null) { System.out.println("User found: " + user);} else { System.out.println("User not found.");}
生成される SQL:
SELECT * FROM user WHERE id = 1
例(getOne):
// QueryWrapper オブジェクトがあり、検索条件を name = 'John Doe' に設定する場合QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "John Doe");User user = userService.getOne(queryWrapper); // getOne メソッドを呼び出すif (user != null) { System.out.println("User found: " + user);} else { System.out.println("User not found.");}
生成される SQL:
SELECT * FROM user WHERE name = 'John Doe'
例(getOne 例外をスローしない):
// QueryWrapper オブジェクトがあり、検索条件を name = 'John Doe' に設定し、例外をスローしない場合QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "John Doe");User user = userService.getOne(queryWrapper, false); // getOne メソッドを呼び出すif (user != null) { System.out.println("User found: " + user);} else { System.out.println("User not found.");}
生成される SQL:
SELECT * FROM user WHERE name = 'John Doe'
例(getMap):
// QueryWrapper オブジェクトがあり、検索条件を name = 'John Doe' に設定し、結果を Map にマッピングする場合QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "John Doe");Map<String, Object> userMap = userService.getMap(queryWrapper); // getMap メソッドを呼び出すif (userMap != null) { System.out.println("User found: " + userMap);} else { System.out.println("User not found.");}
生成される SQL:
SELECT * FROM user WHERE name = 'John Doe'
例(getObj):
// QueryWrapper オブジェクトがあり、検索条件を name = 'John Doe' に設定し、結果を String に変換する場合QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "John Doe");String userName = userService.getObj(queryWrapper, obj -> ((User) obj).getName()); // getObj メソッドを呼び出すif (userName != null) { System.out.println("User name found: " + userName);} else { System.out.println("User name not found.");}
生成される SQL:
SELECT * FROM user WHERE name = 'John Doe'
上記の例から、get
シリーズのメソッドが Service 層でどのように検索操作を行うか、およびそれらに対応する SQL 文を確認できます。これらのメソッドは、さまざまな条件に基づいて検索操作を実行できる柔軟なデータ検索方法を提供します。
list
// 查询所有List<T> list();// 查询列表List<T> list(Wrapper<T> queryWrapper);// 查询(根据ID 批量查询)Collection<T> listByIds(Collection<? extends Serializable> idList);// 查询(根据 columnMap 条件)Collection<T> listByMap(Map<String, Object> columnMap);// 查询所有列表List<Map<String, Object>> listMaps();// 查询列表List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);// 查询全部记录List<Object> listObjs();// 查询全部记录<V> List<V> listObjs(Function<? super Object, V> mapper);// 根据 Wrapper 条件,查询全部记录List<Object> listObjs(Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询全部记录<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
機能説明: 条件に一致するレコードを検索します。
戻り値: 検索結果。エンティティオブジェクト、Map オブジェクト、またはその他の型が返される可能性があります。
パラメータ説明:
型 | パラメータ名 | 説明 |
---|---|---|
Wrapper<T> | queryWrapper | エンティティオブジェクトをカプセル化する操作クラス QueryWrapper |
Collection<? extends Serializable> | idList | 主キー ID リスト |
Map<String, Object> | columnMap | テーブルフィールド map オブジェクト |
Function<? super Object, V> | mapper | 変換関数 |
例(list):
// すべてのユーザーを検索List<User> users = userService.list(); // list メソッドを呼び出すfor (User user : users) { System.out.println("User: " + user);}
生成される SQL:
SELECT * FROM user
例(list QueryWrapper 形式):
// QueryWrapper オブジェクトがあり、検索条件を age > 25 に設定していると仮定QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);List<User> users = userService.list(queryWrapper); // list メソッドを呼び出すfor (User user : users) { System.out.println("User: " + user);}
生成される SQL:
SELECT * FROM user WHERE age > 25
例(listByIds):
// ID リストのグループがあり、ユーザーを一括検索すると仮定List<Integer> ids = Arrays.asList(1, 2, 3);Collection<User> users = userService.listByIds(ids); // listByIds メソッドを呼び出すfor (User user : users) { System.out.println("User: " + user);}
生成される SQL:
SELECT * FROM user WHERE id IN (1, 2, 3)
例(listByMap):
// columnMap があり、検索条件を age = 30 に設定していると仮定Map<String, Object> columnMap = new HashMap<>();columnMap.put("age", 30);Collection<User> users = userService.listByMap(columnMap); // listByMap メソッドを呼び出すfor (User user : users) { System.out.println("User: " + user);}
生成される SQL:
SELECT * FROM user WHERE age = 30
例(listMaps):
// すべてのユーザーを検索し、結果を Map にマッピングList<Map<String, Object>> userMaps = userService.listMaps(); // listMaps メソッドを呼び出すfor (Map<String, Object> userMap : userMaps) { System.out.println("User Map: " + userMap);}
生成される SQL:
SELECT * FROM user
例(listMaps QueryWrapper 形式):
// QueryWrapper オブジェクトがあり、検索条件を age > 25 に設定し、結果を Map にマッピングすると仮定QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);List<Map<String, Object>> userMaps = userService.listMaps(queryWrapper); // listMaps メソッドを呼び出すfor (Map<String, Object> userMap : userMaps) { System.out.println("User Map: " + userMap);}
生成される SQL:
SELECT * FROM user WHERE age > 25
例(listObjs):
// すべてのユーザーを検索し、結果を String リストに変換List<String> userNames = userService.listObjs(obj -> ((User) obj).getName()); // listObjs メソッドを呼び出すfor (String userName : userNames) { System.out.println("User Name: " + userName);}
生成される SQL:
SELECT * FROM user
例(listObjs QueryWrapper 形式):
// QueryWrapper オブジェクトがあり、検索条件を age > 25 に設定し、結果を String リストに変換すると仮定QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);List<String> userNames = userService.listObjs(queryWrapper, obj -> ((User) obj).getName()); // listObjs メソッドを呼び出すfor (String userName : userNames) { System.out.println("User Name: " + userName);}
生成される SQL:
SELECT * FROM user WHERE age > 25
上記の例を通じて、list
シリーズのメソッドが Service 層でどのようにデータ検索操作を行うか、およびそれらに対応する SQL 文を確認できます。これらのメソッドは柔軟なデータ検索方法を提供し、さまざまな条件に基づいて検索操作を行うことができます。
page
// 无条件分页查询IPage<T> page(IPage<T> page);// 条件分页查询IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);// 无条件分页查询IPage<Map<String, Object>> pageMaps(IPage<T> page);// 条件分页查询IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);
機能説明: 条件に一致するレコードをページング検索します。
戻り値: ページング検索結果。レコードリストと総レコード数を含みます。
パラメータ説明:
型 | パラメータ名 | 説明 |
---|---|---|
IPage<T> | page | ページングオブジェクト |
Wrapper<T> | queryWrapper | エンティティオブジェクトをカプセル化する操作クラス QueryWrapper |
例(page):
// 假设要进行无条件的分页查询,每页显示10条记录,查询第1页IPage<User> page = new Page<>(1, 10);IPage<User> userPage = userService.page(page); // 调用 page 方法List<User> userList = userPage.getRecords();long total = userPage.getTotal();System.out.println("Total users: " + total);for (User user : userList) { System.out.println("User: " + user);}
生成される SQL:
SELECT * FROM user LIMIT 10 OFFSET 0
例(page QueryWrapper 形式):
// 假设有一个 QueryWrapper 对象,设置查询条件为 age > 25,进行有条件的分页查询IPage<User> page = new Page<>(1, 10);QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);IPage<User> userPage = userService.page(page, queryWrapper); // 调用 page 方法List<User> userList = userPage.getRecords();long total = userPage.getTotal();System.out.println("Total users (age > 25): " + total);for (User user : userList) { System.out.println("User: " + user);}
生成される SQL:
SELECT * FROM user WHERE age > 25 LIMIT 10 OFFSET 0
例(pageMaps):
// 假设要进行无条件的分页查询,并将结果映射为 Map,每页显示10条记录,查询第1页IPage<Map<String, Object>> page = new Page<>(1, 10);IPage<Map<String, Object>> userPageMaps = userService.pageMaps(page); // 调用 pageMaps 方法List<Map<String, Object>> userMapList = userPageMaps.getRecords();long total = userPageMaps.getTotal();System.out.println("Total users: " + total);for (Map<String, Object> userMap : userMapList) { System.out.println("User Map: " + userMap);}
生成される SQL:
SELECT * FROM user LIMIT 10 OFFSET 0
例(pageMaps QueryWrapper 形式):
// 假设有一个 QueryWrapper 对象,设置查询条件为 age > 25,进行有条件的分页查询,并将结果映射为 MapIPage<Map<String, Object>> page = new Page<>(1, 10);QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);IPage<Map<String, Object>> userPageMaps = userService.pageMaps(page, queryWrapper); // 调用 pageMaps 方法List<Map<String, Object>> userMapList = userPageMaps.getRecords();long total = userPageMaps.getTotal();System.out.println("Total users (age > 25): " + total);for (Map<String, Object> userMap : userMapList) { System.out.println("User Map: " + userMap);}
生成される SQL:
SELECT * FROM user WHERE age > 25 LIMIT 10 OFFSET 0
上記の例から、page
シリーズのメソッドが Service 層でどのようにページング検索操作を行うか、およびそれらに対応する SQL 文を確認できます。これらのメソッドは柔軟なデータ検索方法を提供し、さまざまな条件に基づいてページング検索操作を行うことができます。
count
// 查询总记录数int count();// 根据 Wrapper 条件,查询总记录数int count(Wrapper<T> queryWrapper);
//自3.4.3.2开始,返回值修改为long// 查询总记录数long count();// 根据 Wrapper 条件,查询总记录数long count(Wrapper<T> queryWrapper);
機能説明: 条件に一致するレコードの総数を取得します。
戻り値: 条件に一致するレコードの総数。
パラメータ説明:
型 | パラメータ名 | 説明 |
---|---|---|
Wrapper<T> | queryWrapper | エンティティオブジェクトをカプセル化する操作クラス QueryWrapper |
例(count):
// ユーザーテーブルの総レコード数を取得int totalUsers = userService.count(); // count メソッドを呼び出しSystem.out.println("Total users: " + totalUsers);
生成される SQL:
SELECT COUNT(*) FROM user
例(count QueryWrapper 形式):
// QueryWrapper オブジェクトを作成し、age > 25 という条件を設定して、条件に一致するユーザーの総数を取得QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);int totalUsers = userService.count(queryWrapper); // count メソッドを呼び出しSystem.out.println("Total users (age > 25): " + totalUsers);
生成される SQL:
SELECT COUNT(*) FROM user WHERE age > 25
上記の例から、count
メソッドが Service 層でどのようにレコード数の統計操作を行うか、およびそれらに対応する SQL 文を確認できます。これらのメソッドは、さまざまな条件に基づいてレコード数を統計する柔軟なデータ統計方法を提供します。
Mapper インターフェース
BaseMapper は MyBatis-Plus が提供する汎用 Mapper インターフェースであり、一連のよく使用されるデータベース操作メソッド(追加、削除、更新、検索など)をカプセル化しています。BaseMapper を継承することで、開発者は煩雑な SQL 文を記述することなく、迅速にデータベース操作を行うことができます。
insert
// 插入一条记录int insert(T entity);
機能説明: 1件のレコードを挿入します。
戻り値: int、挿入操作によって影響を受けた行数を表します。通常は 1 で、挿入成功を示します。
パラメータ説明:
型 | パラメータ名 | 説明 |
---|---|---|
T | entity | エンティティオブジェクト |
使用例(insert):
User user = new User();user.setName("John Doe");user.setEmail("john.doe@example.com");int rows = userMapper.insert(user); // insert メソッドを呼び出しif (rows > 0) { System.out.println("User inserted successfully.");} else { System.out.println("Failed to insert user.");}
生成される SQL:
INSERT INTO user (name, email) VALUES (?, ?)
上記の例から、insert
メソッドが Mapper 層でどのように挿入操作を行うか、およびそれに対応する SQL 文を確認できます。このメソッドは挿入操作の実装を簡素化し、開発者が手動で SQL 文を記述する必要をなくします。
delete
// 根据 entity 条件,删除记录int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);// 删除(根据ID 批量删除)int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);// 根据 ID 删除int deleteById(Serializable id);// 根据 columnMap 条件,删除记录int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
機能説明: 条件に一致するレコードを削除します。
戻り値: int、削除操作によって影響を受けた行数を示します。通常は 1 で、削除成功を表します。
パラメータ説明:
型 | パラメータ名 | 説明 |
---|---|---|
Wrapper<T> | wrapper | エンティティオブジェクト操作ラッパークラス(null 可) |
Collection<? extends Serializable> | idList | 主キー ID リスト(null および empty 不可) |
Serializable | id | 主キー ID |
Map<String, Object> | columnMap | テーブルカラム map オブジェクト |
例(delete):
// QueryWrapper オブジェクトがあり、検索条件を age > 25 に設定し、条件を満たすユーザーを削除する場合QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);int rows = userMapper.delete(queryWrapper); // delete メソッドを呼び出すif (rows > 0) { System.out.println("ユーザーの削除に成功しました。");} else { System.out.println("削除されたユーザーはありません。");}
生成される SQL:
DELETE FROM user WHERE age > 25
例(deleteBatchIds):
// ID リストのグループがあり、ユーザーを一括削除する場合List<Integer> ids = Arrays.asList(1, 2, 3);int rows = userMapper.deleteBatchIds(ids); // deleteBatchIds メソッドを呼び出すif (rows > 0) { System.out.println("ユーザーの削除に成功しました。");} else { System.out.println("削除されたユーザーはありません。");}
生成される SQL:
DELETE FROM user WHERE id IN (1, 2, 3)
例(deleteById):
// ID に基づいて単一のユーザーを削除する場合int userId = 1;int rows = userMapper.deleteById(userId); // deleteById メソッドを呼び出すif (rows > 0) { System.out.println("ユーザーの削除に成功しました。");} else { System.out.println("削除されたユーザーはありません。");}
生成される SQL:
DELETE FROM user WHERE id = 1
例(deleteByMap):
// columnMap があり、検索条件を age = 30 に設定し、条件を満たすユーザーを削除する場合Map<String, Object> columnMap = new HashMap<>();columnMap.put("age", 30);int rows = userMapper.deleteByMap(columnMap); // deleteByMap メソッドを呼び出すif (rows > 0) { System.out.println("ユーザーの削除に成功しました。");} else { System.out.println("削除されたユーザーはありません。");}
生成される SQL:
DELETE FROM user WHERE age = 30
上記の例を通して、delete
シリーズのメソッドが Mapper 層でどのように削除操作を行うか、およびそれらに対応する SQL 文を確認できます。これらのメソッドは、さまざまな条件に基づいた柔軟なデータ削除方法を提供します。
update
// 根据 whereWrapper 条件,更新记录int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);// 根据 ID 修改int updateById(@Param(Constants.ENTITY) T entity);
機能説明: 条件に一致するレコードを更新します。
戻り値: int、更新操作によって影響を受けた行数を表し、通常は 1(更新成功)です。
パラメータ説明:
型 | パラメータ名 | 説明 |
---|---|---|
T | entity | エンティティオブジェクト (set 条件値、null 可) |
Wrapper<T> | updateWrapper | エンティティオブジェクトをカプセル化する操作クラス(null 可、内部の entity は where 句の生成に使用) |
使用例(update):
// UpdateWrapper オブジェクトを作成し、検索条件を age > 25 に設定し、条件を満たすユーザーのメールアドレスを更新する場合UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();updateWrapper.gt("age", 25);User updateUser = new User();updateUser.setEmail("new.email@example.com");int rows = userMapper.update(updateUser, updateWrapper); // update メソッドを呼び出しif (rows > 0) { System.out.println("Users updated successfully.");} else { System.out.println("No users updated.");}
生成される SQL:
UPDATE user SET email = ? WHERE age > 25
使用例(updateById):
// ID が 1 のユーザーのメールアドレスを更新する場合User updateUser = new User();updateUser.setId(1);updateUser.setEmail("new.email@example.com");int rows = userMapper.updateById(updateUser); // updateById メソッドを呼び出しif (rows > 0) { System.out.println("User updated successfully.");} else { System.out.println("No user updated.");}
生成される SQL:
UPDATE user SET email = ? WHERE id = 1
上記の例から、update
系メソッドが Mapper 層でどのように更新操作を行うか、およびそれらに対応する SQL 文を確認できます。これらのメソッドは、さまざまな条件に基づいた柔軟なデータ更新方法を提供します。
select
// 根据 ID 查询T selectById(Serializable id);// 根据 entity 条件,查询一条记录T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据ID 批量查询)List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);// 根据 entity 条件,查询全部记录List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 查询(根据 columnMap 条件)List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);// 根据 Wrapper 条件,查询全部记录List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 entity 条件,查询全部记录(并翻页)IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询全部记录(并翻页)IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询总记录数Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
機能説明: 条件に一致するレコードを検索します。
戻り値: 検索結果。エンティティオブジェクト、Mapオブジェクト、またはその他の型である可能性があります。
パラメータ説明:
型 | パラメータ名 | 説明 |
---|---|---|
Serializable | id | 主キー ID |
Wrapper<T> | queryWrapper | エンティティオブジェクト封装操作クラス(null可) |
Collection<? extends Serializable> | idList | 主キー ID リスト(null および empty 不可) |
Map<String, Object> | columnMap | テーブルカラム map オブジェクト |
IPage<T> | page | ページネーション検索条件(RowBounds.DEFAULT 可) |
例(selectById):
// ID による単一ユーザー検索int userId = 1;User user = userMapper.selectById(userId); // selectById メソッドを呼び出すSystem.out.println("User: " + user);
生成される SQL:
SELECT * FROM user WHERE id = 1
例(selectOne):
// QueryWrapper オブジェクトを作成し、検索条件を age > 25 に設定して、条件に一致する1件のユーザーを検索QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);User user = userMapper.selectOne(queryWrapper); // selectOne メソッドを呼び出すSystem.out.println("User: " + user);
生成される SQL:
SELECT * FROM user WHERE age > 25
例(selectBatchIds):
// ID リストを使用してユーザーを一括検索List<Integer> ids = Arrays.asList(1, 2, 3);List<User> users = userMapper.selectBatchIds(ids); // selectBatchIds メソッドを呼び出すfor (User u : users) { System.out.println("User: " + u);}
生成される SQL:
SELECT * FROM user WHERE id IN (1, 2, 3)
例(selectList):
// QueryWrapper オブジェクトを作成し、検索条件を age > 25 に設定して、条件に一致するすべてのユーザーを検索QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);List<User> users = userMapper.selectList(queryWrapper); // selectList メソッドを呼び出すfor (User u : users) { System.out.println("User: " + u);}
生成される SQL:
SELECT * FROM user WHERE age > 25
例(selectByMap):
// columnMap を使用して、検索条件を age > 30 に設定し、条件に一致するユーザーを検索Map<String, Object> columnMap = new HashMap<>();columnMap.put("age", 30);List<User> users = userMapper.selectByMap(columnMap); // selectByMap メソッドを呼び出すfor (User u : users) { System.out.println("User: " + u);}
生成される SQL:
SELECT * FROM user WHERE age > 30
例(selectMaps):
// QueryWrapper オブジェクトを作成し、検索条件を age > 25 に設定して、条件に一致するすべてのユーザーを検索し、結果を Map にマッピングQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);List<Map<String, Object>> userMaps = userMapper.selectMaps(queryWrapper); // selectMaps メソッドを呼び出すfor (Map<String, Object> userMap : userMaps) { System.out.println("User Map: " + userMap);}
生成される SQL:
SELECT * FROM user WHERE age > 25
例(selectObjs):
// QueryWrapper オブジェクトを作成し、検索条件を age > 25 に設定して、条件に一致するすべてのユーザーを検索し、各レコードの最初のフィールドの値のみを返すQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);List<Object> userIds = userMapper.selectObjs(queryWrapper); // selectObjs メソッドを呼び出すfor (Object userId : userIds) { System.out.println("User ID: " + userId);}
生成される SQL:
SELECT id FROM user WHERE age > 25
例(selectPage):
// ページネーション検索を実行。1ページあたり10件、1ページ目を表示。検索条件は age > 25IPage<User> page = new Page<>(1, 10);QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);IPage<User> userPage = userMapper.selectPage(page, queryWrapper); // selectPage メソッドを呼び出すList<User> userList = userPage.getRecords();long total = userPage.getTotal();System.out.println("Total users (age > 25): " + total);for (User user : userList) { System.out.println("User: " + user);}
生成される SQL:
SELECT * FROM user WHERE age > 25 LIMIT 10 OFFSET 0
例(selectMapsPage):
// ページネーション検索を実行。1ページあたり10件、1ページ目を表示。検索条件は age > 25。結果を Map にマッピングIPage<Map<String, Object>> page = new Page<>(1, 10);QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);IPage<Map<String, Object>> userPageMaps = userMapper.selectMapsPage(page, queryWrapper); // selectMapsPage メソッドを呼び出すList<Map<String, Object>> userMapList = userPageMaps.getRecords();long total = userPageMaps.getTotal();System.out.println("Total users (age > 25): " + total);for (Map<String, Object> userMap : userMapList) { System.out.println("User Map: " + userMap);}
生成される SQL:
SELECT * FROM user WHERE age > 25 LIMIT 10 OFFSET 0
例(selectCount):
// QueryWrapper オブジェクトを作成し、検索条件を age > 25 に設定して、総レコード数を検索QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);Integer totalUsers = userMapper.selectCount(queryWrapper); // selectCount メソッドを呼び出すSystem.out.println("Total users (age > 25): " + totalUsers);
生成される SQL:
SELECT COUNT(*) FROM user WHERE age > 25
上記の例を通して、select
シリーズのメソッドが Mapper 層でどのように検索操作を実行するか、およびそれらに対応する SQL 文を確認できます。これらのメソッドは、単一レコード検索、一括検索、条件検索、ページネーション検索など、さまざまな条件に応じた柔軟なデータ検索方法を提供します。
Mapper 層オプションコンポーネント
オプションコンポーネントは、Mybatis-Plus が提供する拡張メソッドであり、com.baomidou.mybatisplus.extension.injector.methods
パッケージに配置されています。これらのメソッドは、SQL インジェクターと組み合わせて使用することで、Mapper インターフェースの機能を拡張します。
これらのオプションコンポーネントを使用する前に、SQL インジェクターが正しく設定されていることを確認してください。より詳細な使用例と情報については、公式サンプルおよびソースコードコメントを参照してください。
オプション機能の説明
alwaysUpdateSomeColumnById
int alwaysUpdateSomeColumnById(T entity);
ソースコード:alwaysUpdateSomeColumnById
機能:このメソッドは、更新操作時にエンティティオブジェクトの特定のフィールドに変更があるかどうかに関わらず、それらのフィールドを強制的に更新します。これは、タイムスタンプフィールドの更新など、特定のビジネスシナリオで非常に有用であり、毎回の更新操作でそのフィールドが確実に更新されるようにします。
使用シナリオ:レコードを更新するたびに、特定のフィールド(更新日時、バージョン番号など)を更新する必要がある場合に使用します。たとえそれらのフィールドがエンティティオブジェクトで変更されていなくても更新されます。
insertBatchSomeColumn
int insertBatchSomeColumn(List<T> entityList);
ソースコード:insertBatchSomeColumn
機能:このメソッドは、エンティティオブジェクトのバッチ挿入に使用されますが、エンティティオブジェクト内で指定された特定のフィールドのみを挿入します。これは、データをバッチ挿入する必要があるが、すべてのフィールドを挿入したくない場合に非常に有用です。
使用シナリオ:データをバッチ挿入する必要があり、エンティティオブジェクト内の一部のフィールドのみを挿入して、挿入効率を向上させたり、機密データを保護したりしたい場合に使用します。
logicDeleteByIdWithFill
int logicDeleteByIdWithFill(T entity);
ソースコード:logicDeleteByIdWithFill
機能:このメソッドは、レコードの論理削除とエンティティオブジェクト内の特定のフィールドの埋め込みに使用されます。論理削除とは、データベースから実際にレコードを削除するのではなく、特定のフィールド(deleted
フィールドなど)を更新して、レコードが削除済みであることをマークすることを意味します。
使用シナリオ:論理削除機能を実装する必要があり、削除操作時にエンティティオブジェクト内の特定のフィールド(削除日時、削除者など)を自動的に埋め込みたい場合に使用します。
使用上のヒント
- これらのオプションコンポーネントを使用する前に、プロジェクトで SQL インジェクターが正しく設定されていることを確認してください。
- これらのメソッドは通常、MyBatis-Plus が対応する SQL 文を認識して生成できるように、Mapper インターフェースで明示的に宣言する必要があります。
- 各オプションコンポーネントには特定の使用シナリオがあり、業務要件に基づいて適切なメソッドを選択してください。
- 実際の使用では、より複雑な機能を実現するために、エンティティオブジェクトのアノテーション(
@TableField
、@TableLogic
など)と組み合わせる必要がある場合があります。
これらのオプションコンポーネントを使用することで、MyBatis-Plus の機能をさらに拡張し、より多様な業務要件に対応することができます。
Chain
Chain は MyBatis-Plus が提供するチェーンプログラミングスタイルであり、開発者がより簡潔で直感的な方法でデータベース操作コードを記述できるようにします。Chain は query
と update
の 2 つのカテゴリに分かれており、それぞれ検索操作と更新操作に使用されます。各カテゴリはさらに、通常のチェーンスタイルとラムダチェーンスタイルの 2 つのスタイルに分かれており、ラムダチェーンスタイルは型安全な検索条件構築を提供しますが、Kotlin には対応していません。
使用手順
query
チェーン式のクエリ操作を提供し、メソッドを連続して呼び出すことでクエリ条件を構築できます。
// 链式查询 普通QueryChainWrapper<T> query();// 链式查询 lambda 式。注意:不支持 KotlinLambdaQueryChainWrapper<T> lambdaQuery();
使用例:
// 通常のチェーン式クエリの例query().eq("name", "John").list(); // name が "John" であるすべてのレコードを検索
// lambda チェーン式クエリの例lambdaQuery().eq(User::getAge, 30).one(); // 年齢が 30 の単一レコードを検索
update
チェーン式の更新操作を提供し、メソッドを連続して呼び出すことで更新条件を構築できます。
// 链式更改 普通UpdateChainWrapper<T> update();// 链式更改 lambda 式。注意:不支持 KotlinLambdaUpdateChainWrapper<T> lambdaUpdate();
使用例:
// 通常のチェーン式更新の例update().set("status", "inactive").eq("name", "John").update(); // name が "John" のレコードの status を "inactive" に更新
// lambda チェーン式更新の例User updateUser = new User();updateUser.setEmail("new.email@example.com");lambdaUpdate().set(User::getEmail, updateUser.getEmail()).eq(User::getId, 1).update(); // ID が 1 のユーザーのメールアドレスを更新
使用上のヒント
- チェーン操作は
QueryChainWrapper
またはUpdateChainWrapper
のインスタンスを返すことで、開発者がメソッドを連続して呼び出してクエリまたは更新条件を構築することを可能にします。 - ラムダ式を使用したチェーン操作は、型安全なクエリ条件の構築を提供します。メソッド参照
Entity::getId
などを使用することで、文字列のハードコーディングを回避し、コードの可読性と安全性を向上させます。 - チェーン操作を使用する際は、チェーンメソッドの呼び出し順序に注意してください。通常は条件を設定してから、クエリまたは更新操作を実行します。
- チェーン操作は
eq
、ne
、gt
、lt
、like
など、さまざまな条件構築メソッドをサポートしており、実際の要件に応じて適切なメソッドを選択できます。 - チェーン操作によって返される結果は、単一のレコード、複数のレコード、総レコード数など、最後に呼び出されたメソッドによって異なります。
Chain を使用することで、開発者はデータベース操作コードをより効率的に記述でき、同時にコードの明確さと保守性を維持できます。
ActiveRecord
ActiveRecord パターンは、エンティティクラスが直接データベースと対話できるようにするデザインパターンであり、エンティティクラスはドメインモデルであると同時にデータアクセスオブジェクトとして機能します。Mybatis-Plus では、エンティティクラスが Model
クラスを継承するだけで、強力な CRUD 操作機能を獲得できます。
使用手順
Model クラスを継承する
import com.baomidou.mybatisplus.extension.activerecord.Model;
public class User extends Model<User> { // エンティティクラスのフィールド定義... private Long id; private String name; private Integer age; // ... その他のフィールドと getter/setter メソッド}
CRUD メソッドを呼び出す
// 新しいユーザーを作成してデータベースに挿入User user = new User();user.setName("John Doe");user.setAge(30);boolean isInserted = user.insert(); // 戻り値は操作の成功可否を示します
// すべてのユーザーを検索List<User> allUsers = user.selectAll();
// ID に基づいてユーザー情報を更新user.setId(1L);user.setName("Updated Name");boolean isUpdated = user.updateById(); // 戻り値は操作の成功可否を示します
// ID に基づいてユーザーを削除boolean isDeleted = user.deleteById(); // 戻り値は操作の成功可否を示します
使用上のヒント
- ActiveRecord モードでは、エンティティクラスは直接
insert
、selectAll
、updateById
、deleteById
などのメソッドを呼び出してデータベース操作を行うことができます。 - エンティティクラスが
Model
クラスを継承すると、手動で SQL 文を記述することなく、一連のデータベース操作メソッドを自動的に利用できるようになります。 - エンティティクラス内のフィールドは、データベーステーブルの列に対応させる必要があります。通常、アノテーション(
@TableField
、@TableId
など)を使用して、フィールドと列のマッピング関係を指定します。 - 更新または削除操作を行う場合、通常はまずエンティティオブジェクトを検索し、その属性を変更した後、更新または削除メソッドを呼び出します。
- 挿入および更新操作は通常、操作が成功したかどうかを示すブール値を返します。
- 検索操作は、単一のエンティティオブジェクトやエンティティオブジェクトのリストなど、対応する検索結果を返します。
ActiveRecord パターンを使用することで、開発者はデータベース操作コードをより簡潔に記述でき、コードの明確さと保守性を維持できます。このパターンは、特に単純な CRUD 操作に適しており、重複コードの記述を大幅に削減することができます。
SimpleQuery
SimpleQuery は MyBatis-Plus が提供するユーティリティクラスであり、selectList
クエリ後の結果をラップし、Stream
ストリームとして処理できるようにすることで、API の呼び出しを簡素化します。
SimpleQuery の特徴の一つは peeks
パラメータです。これは可変引数で、型は Consumer...
であり、複数の操作を連続して追加できることを意味します。これらの操作は、クエリ結果が処理される際に順次実行されます。
SimpleQuery の使用方法は公式テストケースを参照してください。
使用手順
SimpleQuery ツールクラスの導入
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda;import com.baomidou.mybatisplus.core.toolkit.support.SimpleQuery;
SimpleQuery を使用したクエリ
// User エンティティクラスと対応する BaseMapper があると仮定List<Long> ids = SimpleQuery.list( Wrappers.lambdaQuery(User.class), // lambda クエリビルダーの使用 User::getId, // 抽出するフィールド、ここでは User の id System.out::println, // 最初の peek 操作、各ユーザーを出力 user -> userNames.add(user.getName()) // 2番目の peek 操作、各ユーザーの名前を userNames リストに追加);
使用上のヒント
- SimpleQuery ツールクラスは、クエリ結果を処理するための簡潔な方法を提供します。クエリ結果に対して複数の操作を適用することができ、これらの操作は追加された順序で順次実行されます。
- SimpleQuery を使用する際には、クエリビルダー(例:
Wrappers.lambdaQuery()
)、結果を抽出するためのフィールド(例:User::getId
)、および1つ以上のConsumer
型のpeek
操作を指定する必要があります。 peek
操作は、ログの出力、キャッシュの更新、通知の送信など、任意の副作用を持つ操作を実行するために使用できます。これらの操作はクエリ結果自体には影響しません。- SimpleQuery が返す結果は、すべてのクエリされたエンティティオブジェクトを含むリストであり、これらのオブジェクトにはすべての
peek
操作が適用されています。 - SimpleQuery を使用することで、クエリと結果処理のロジックを分離し、コードをより明確で保守しやすくすることができます。
SimpleQuery ツールクラスを使用することで、開発者はクエリ結果をより効率的に処理しながら、コードの簡潔さと可読性を維持できます。このツールクラスは、特にクエリ結果に対して複雑な処理が必要なシナリオに適しています。
機能詳細
keyMap
SimpleQuery の keyMap
メソッドは、データベースをクエリし、その結果を Map
としてカプセル化する便利な方法を提供します。この Map では、エンティティの特定のプロパティがキーとして、エンティティ自体が値として使用されます。このメソッドは、クエリ結果を処理する際に、ログの出力やキャッシュの更新などの追加の副作用操作を実行することもサポートしています。
メソッドシグネチャ
// テーブル内のレコードをクエリし、Map<プロパティ, エンティティ>としてカプセル化して返すMap<A, E> keyMap(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, Consumer<E>... peeks);
// テーブル内のレコードをクエリし、Map<プロパティ, エンティティ>としてカプセル化して返す(並列ストリームを考慮)Map<A, E> keyMap(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, boolean isParallel, Consumer<E>... peeks);
パラメータ説明
型 | パラメータ名 | 説明 |
---|---|---|
E | entity | エンティティオブジェクトの型。クエリ結果のエンティティ型です。 |
A | attribute | エンティティのプロパティ型。返される Map のキーの型でもあります。 |
LambdaQueryWrapper<E> | wrapper | ラムダ式をサポートする条件構築器。クエリ条件を構築するために使用します。 |
SFunction<E, A> | sFunction | エンティティ内のプロパティの getter メソッド参照。Map のキーの値を決定するために使用します。 |
boolean | isParallel | true に設定すると、基盤で並列ストリームを使用してクエリを実行し、大量のデータを処理する際の効率を向上させることができます。 |
Consumer<E>… | peeks | 可変長引数。クエリ結果を処理する際に実行する追加の操作(ログの出力、キャッシュの更新など)を指定するために使用します。 |
使用例
// User エンティティクラスと対応する BaseMapper があると仮定LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(User::getStatus, "active"); // ステータスが "active" のユーザーをクエリ
// keyMap メソッドを使用して結果をクエリし、カプセル化Map<String, User> userMap = SimpleQuery.keyMap( queryWrapper, // クエリ条件構築器 User::getUsername, // ユーザー名をキーとして使用 user -> System.out.println("Processing user: " + user.getUsername()) // 処理中のユーザー名を出力);
// 結果を走査for (Map.Entry<String, User> entry : userMap.entrySet()) { System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());}
使用上のヒント
keyMap
メソッドは、エンティティの特定のプロパティに基づいてエンティティを迅速に検索する必要があるシナリオに適しています。sFunction
パラメータを通じて、任意のエンティティプロパティをMap
のキーとして指定できます。これにより、クエリ結果へのアクセスがより直感的かつ効率的になります。peeks
パラメータを使用すると、クエリ結果を処理する際に追加の副作用操作を実行できます。これらの操作は最終的なMap
の結果に影響しません。- 大量のデータを処理する場合、
isParallel
パラメータをtrue
に設定して並列ストリームを有効にし、クエリ効率を向上させることを検討できます。
SimpleQuery の keyMap
メソッドを使用することで、開発者はクエリ結果をより効率的に処理し、使いやすいデータ構造にカプセル化できるとともに、追加の副作用操作を実行してコードをより簡潔かつ柔軟にすることができます。
map
SimpleQuery の map
メソッドは、データベースをクエリし、その結果を Map
としてカプセル化する便利な方法を提供します。この Map では、エンティティの特定のプロパティがキーとして、別のプロパティが値として使用されます。このメソッドは、クエリ結果を処理する際に、ログの出力やキャッシュの更新などの追加の副作用操作を実行することもサポートしています。
メソッドシグネチャ
// テーブル内のレコードをクエリし、Map<プロパティ, プロパティ>としてカプセル化して返すMap<A, P> map(LambdaQueryWrapper<E> wrapper, SFunction<E, A> keyFunc, SFunction<E, P> valueFunc, Consumer<E>... peeks);
// テーブル内のレコードをクエリし、Map<プロパティ, プロパティ>としてカプセル化して返す(並列ストリームを考慮)Map<A, P> map(LambdaQueryWrapper<E> wrapper, SFunction<E, A> keyFunc, SFunction<E, P> valueFunc, boolean isParallel, Consumer<E>... peeks);
パラメータ説明
型 | パラメータ名 | 説明 |
---|---|---|
E | entity | エンティティオブジェクトの型。クエリ結果のエンティティ型です。 |
A | attribute | エンティティのプロパティ型。返される Map のキーの型として使用されます。 |
P | attribute | エンティティのプロパティ型。返される Map の値の型として使用されます。 |
LambdaQueryWrapper<E> | wrapper | ラムダ式をサポートする条件構築器。クエリ条件を構築するために使用します。 |
SFunction<E, A> | keyFunc | エンティティ内のプロパティの getter メソッド参照。Map のキーの値を決定するために使用します。 |
SFunction<E, P> | valueFunc | エンティティ内のプロパティの getter メソッド参照。Map の値の値を決定するために使用します。 |
boolean | isParallel | true に設定すると、基盤で並列ストリームを使用してクエリを実行し、大量のデータを処理する際の効率を向上させることができます。 |
Consumer<E>… | peeks | 可変長引数。クエリ結果を処理する際に実行する追加の操作(ログの出力、キャッシュの更新など)を指定するために使用します。 |
使用例
// User エンティティクラスと対応する BaseMapper があると仮定LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(User::getStatus, "active"); // ステータスが "active" のユーザーをクエリ
// map メソッドを使用して結果をクエリし、カプセル化Map<String, Integer> userMap = SimpleQuery.map( queryWrapper, // クエリ条件構築器 User::getUsername, // ユーザー名をキーとして使用 User::getAge, // 年齢を値として使用 user -> System.out.println("Processing user: " + user.getUsername()) // 処理中のユーザー名を出力);
// 結果を走査for (Map.Entry<String, Integer> entry : userMap.entrySet()) { System.out.println("Username: " + entry.getKey() + ", Age: " + entry.getValue());}
使用上のヒント
map
メソッドは、エンティティの特定のプロパティに基づいて別のプロパティを迅速に検索する必要があるシナリオに適しています。keyFunc
およびvalueFunc
パラメータを通じて、任意のエンティティプロパティをMap
のキーと値として指定できます。これにより、クエリ結果へのアクセスがより直感的かつ効率的になります。peeks
パラメータを使用すると、クエリ結果を処理する際に追加の副作用操作を実行できます。これらの操作は最終的なMap
の結果に影響しません。- 大量のデータを処理する場合、
isParallel
パラメータをtrue
に設定して並列ストリームを有効にし、クエリ効率を向上させることを検討できます。
SimpleQuery の map
メソッドを使用することで、開発者はクエリ結果をより効率的に処理し、使いやすいデータ構造にカプセル化できるとともに、追加の副作用操作を実行してコードをより簡潔かつ柔軟にすることができます。
group
SimpleQuery の group
メソッドは、データベースをクエリし、その結果をエンティティの特定のプロパティでグループ化して Map
にカプセル化する便利な方法を提供します。このメソッドは、クエリ結果を処理する際に、ログの出力やキャッシュの更新などの追加の副作用操作を実行することもサポートしています。さらに、Collector
を使用してグループ化されたコレクションをさらに処理することもできます。
メソッドシグネチャ
// テーブル内のレコードをクエリし、Map<プロパティ, List<エンティティ>>としてカプセル化して返すMap<K, List<T>> group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Consumer<T>... peeks);
// テーブル内のレコードをクエリし、Map<プロパティ, List<エンティティ>>としてカプセル化して返す(並列ストリームを考慮)Map<K, List<T>> group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, boolean isParallel, Consumer<T>... peeks);
// テーブル内のレコードをクエリし、Map<プロパティ, グループ化後のコレクションに対する下流コレクタ>としてカプセル化して返すM group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Collector<? super T, A, D> downstream, Consumer<T>... peeks);
// テーブル内のレコードをクエリし、Map<プロパティ, グループ化後のコレクションに対する下流コレクタ>としてカプセル化して返す(並列ストリームを考慮)M group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Collector<? super T, A, D> downstream, boolean isParallel, Consumer<T>... peeks);
パラメータ説明
型 | パラメータ名 | 説明 |
---|---|---|
T | entity | エンティティオブジェクトの型。クエリ結果のエンティティ型です。 |
K | attribute | エンティティのプロパティ型。返される Map のキーの型として使用されます。 |
D | - | 下流コレクタの戻り値の型。Map の値の型として使用されます。 |
A | - | 下流操作の中間型。Collector の中間結果に使用されます。 |
M | - | 最終的に返される Map<K, D> の型。 |
LambdaQueryWrapper<T> | wrapper | ラムダ式をサポートする条件構築器。クエリ条件を構築するために使用します。 |
SFunction<T, K> | sFunction | グループ化の基準。エンティティ内のプロパティの getter メソッド参照。Map のキーの値を決定するために使用します。 |
Collector<T, A, D> | downstream | 下流コレクタ。グループ化されたコレクションをさらに処理するために使用します。 |
boolean | isParallel | true に設定すると、基盤で並列ストリームを使用してクエリを実行し、大量のデータを処理する際の効率を向上させることができます。 |
Consumer<T>… | peeks | 可変長引数。クエリ結果を処理する際に実行する追加の操作(ログの出力、キャッシュの更新など)を指定するために使用します。 |
使用例
// User エンティティクラスと対応する BaseMapper があると仮定LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(User::getStatus, "active"); // ステータスが "active" のユーザーをクエリ
// group メソッドを使用して結果をクエリし、カプセル化(ユーザー名でグループ化)Map<String, List<User>> userGroup = SimpleQuery.group( queryWrapper, // クエリ条件構築器 User::getUsername, // ユーザー名をグループ化キーとして使用 user -> System.out.println("Processing user: " + user.getUsername()) // 処理中のユーザー名を出力);
// 結果を走査for (Map.Entry<String, List<User>> entry : userGroup.entrySet()) { System.out.println("Username: " + entry.getKey()); for (User user : entry.getValue()) { System.out.println(" - User: " + user); }}
使用上のヒント
group
メソッドは、エンティティの特定のプロパティに基づいてクエリ結果をグループ化する必要があるシナリオに適しています。sFunction
パラメータを通じて、任意のエンティティプロパティをグループ化の基準として指定できます。これにより、クエリ結果の編成がより柔軟になります。downstream
パラメータを使用すると、Collector
を使用してグループ化されたコレクションをさらに処理(カウント、合計、平均値の計算など)できます。peeks
パラメータを使用すると、クエリ結果を処理する際に追加の副作用操作を実行できます。これらの操作は最終的なMap
の結果に影響しません。- 大量のデータを処理する場合、
isParallel
パラメータをtrue
に設定して並列ストリームを有効にし、クエリ効率を向上させることを検討できます。
SimpleQuery の group
メソッドを使用することで、開発者はクエリ結果をより効率的に処理し、特定のプロパティでグループ化できるとともに、追加の副作用操作を実行してコードをより簡潔かつ柔軟にすることができます。
list
SimpleQuery の list
メソッドは、データベースをクエリし、その結果を List
としてカプセル化する便利な方法を提供します。このリストの要素は、エンティティの特定のプロパティです。このメソッドは、クエリ結果を処理する際に、ログの出力やキャッシュの更新などの追加の副作用操作を実行することもサポートしています。
メソッドシグネチャ
// テーブル内のレコードをクエリし、List<プロパティ>としてカプセル化して返すList<A> list(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, Consumer<E>... peeks);
// テーブル内のレコードをクエリし、List<プロパティ>としてカプセル化して返す(並列ストリームを考慮)List<A> list(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, boolean isParallel, Consumer<E>... peeks);
パラメータ説明
型 | パラメータ名 | 説明 |
---|---|---|
E | entity | エンティティオブジェクトの型。クエリ結果のエンティティ型です。 |
A | attribute | エンティティのプロパティ型。返される List の要素の型として使用されます。 |
LambdaQueryWrapper<E> | wrapper | ラムダ式をサポートする条件構築器。クエリ条件を構築するために使用します。 |
SFunction<E, A> | sFunction | エンティティ内のプロパティの getter メソッド参照。List の要素の値を決定するために使用します。 |
boolean | isParallel | true に設定すると、基盤で並列ストリームを使用してクエリを実行し、大量のデータを処理する際の効率を向上させることができます。 |
Consumer<E>… | peeks | 可変長引数。クエリ結果を処理する際に実行する追加の操作(ログの出力、キャッシュの更新など)を指定するために使用します。 |
使用例
// User エンティティクラスと対応する BaseMapper があると仮定LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(User::getStatus, "active"); // ステータスが "active" のユーザーをクエリ
// list メソッドを使用して結果をクエリし、カプセル化(すべてのユーザーのユーザー名を抽出)List<String> userNames = SimpleQuery.list( queryWrapper, // クエリ条件構築器 User::getUsername, // ユーザー名をリスト要素として抽出 user -> System.out.println("Processing user: " + user.getUsername()) // 処理中のユーザー名を出力);
// 結果を走査for (String username : userNames) { System.out.println("Username: " + username);}
使用上のヒント
list
メソッドは、エンティティの特定のプロパティに基づいてリストを迅速に取得する必要があるシナリオに適しています。sFunction
パラメータを通じて、任意のエンティティプロパティをList
の要素として指定できます。これにより、クエリ結果へのアクセスがより直感的かつ効率的になります。peeks
パラメータを使用すると、クエリ結果を処理する際に追加の副作用操作を実行できます。これらの操作は最終的なList
の結果に影響しません。- 大量のデータを処理する場合、
isParallel
パラメータをtrue
に設定して並列ストリームを有効にし、クエリ効率を向上させることを検討できます。
SimpleQuery の list
メソッドを使用することで、開発者はクエリ結果をより効率的に処理し、使いやすいデータ構造にカプセル化できるとともに、追加の副作用操作を実行してコードをより簡潔かつ柔軟にすることができます。
Db Kit
Db Kit は MyBatis-Plus が提供するツールクラスであり、開発者が静的な呼び出し方式で CRUD 操作を実行できるようにします。これにより、Spring 環境下で発生する可能性のある Service の循環注入問題を回避し、コードを簡素化し、開発効率を向上させます。
Db Kit の完全な使用方法については、公式テストケースを参照してください。
使用例
// 假设有一个 User 实体类和对应的 BaseMapper
// 根据 id 查询单个实体User user = Db.getById(1L, User.class);
// 根据 id 查询多个实体List<User> userList = Db.listByIds(Arrays.asList(1L, 2L, 3L), User.class);
// 根据条件构造器查询LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery(User.class) .eq(User::getStatus, "active");List<User> activeUsers = Db.list(queryWrapper);
// 插入新实体User newUser = new User();newUser.setUsername("newUser");newUser.setAge(25);boolean isInserted = Db.insert(newUser);
// 根据 id 更新实体User updateUser = new User();updateUser.setId(1L);updateUser.setUsername("updatedUser");boolean isUpdated = Db.updateById(updateUser);
// 根据条件构造器更新LambdaUpdateWrapper<User> updateWrapper = Wrappers.lambdaUpdate(User.class) .set(User::getAge, 30) .eq(User::getUsername, "updatedUser");boolean isUpdatedByWrapper = Db.update(null, updateWrapper);
// 根据 id 删除实体boolean isDeleted = Db.removeById(1L);
// 根据条件构造器删除LambdaDeleteWrapper<User> deleteWrapper = Wrappers.lambdaDelete(User.class) .eq(User::getStatus, "inactive");boolean isDeletedByWrapper = Db.remove(deleteWrapper);
// 批量插入List<User> batchUsers = Arrays.asList( new User("user1", 20), new User("user2", 22), new User("user3", 24));boolean isBatchInserted = Db.saveBatch(batchUsers);
// 批量更新List<User> batchUpdateUsers = Arrays.asList( new User(1L, "user1", 21), new User(2L, "user2", 23), new User(3L, "user3", 25));boolean isBatchUpdated = Db.updateBatchById(batchUpdateUsers);
使用上のヒント
- Db Kit は一連の静的メソッドを提供しており、Service 層を経由せずに直接呼び出してデータベース操作を行うことができ、コード構造を簡素化します。
- Db Kit を使用する際は、特に Wrapper を使用する場合に、エンティティクラスまたはエンティティオブジェクトを指定する必要があるなど、渡されるパラメータが正しいことを確認してください。
- バッチ挿入や更新などのバッチ操作では、効率を向上させるために、Db Kit が提供するバッチメソッドを使用することを推奨します。
- ループ内で Db Kit のメソッドを頻繁に呼び出すことは避けてください。これはパフォーマンスの問題を引き起こす可能性があります。
Db Kit を使用することで、開発者はコードの簡潔さと可読性を維持しながら、より効率的にデータベース操作を実行できます。このようなユーティリティクラスは、特に単純な CRUD 操作に適しており、重複コードの記述を大幅に削減できます。