記事ディレクトリ
序文
これまでに、MyBatis とは何か、MyBatis を使用する必要がある理由、MyBatis 環境の作成方法を学び、単体テストを使用してコード関数をテストする方法について学びました。そこで今日の記事では、MyBatis の基本的な操作について説明します。
MyBatis を記述するにはアノテーションと XML メソッドの 2 つの方法がありますが、ここでは両方のメソッドについて皆さんのために書きます。
注釈モードで MyBatis を書く
MyBatis ログを印刷する
私たち開発者にとってログの重要性については前回の記事でも触れましたが、MyBatis フレームワークを使用するプロセスでは、MyBatis コードの実行中に生成されるログも確認できます。
では、MyBatis ログを印刷するにはどうすればよいでしょうか? MyBatis コードの実行中に生成されるログを知る必要があることを Spring に伝えるために、構成ファイルに構成項目を追加する必要があります。
mybatis:
configuration: # 配置打印 MyBatis⽇志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
この設定を追加した後、プロジェクトを開始すると、MyBatis の実行中のログが表示されることがわかります。
パラメータの受け渡し
ID 4 のユーザーの情報をクエリする必要がある場合、対応する SQL ステートメントは でありselect * from userinfo where id=4;
、MyBatis に対応するとします。
@Select("select * from userinfo where id=4")
public UserInfo getById();
ただし、このように SQL ステートメントを記述すると、クエリの条件がハードコーディングされていることがわかります。では、ユーザーから渡されたパラメーターに基づいて、指定された条件でデータをクエリする方法はあるでしょうか? 答えは「はい」です。これには、MyBatis でのパラメーターの受け渡しに関する知識が必要です。
MyBatis は#{}
メソッド内のパラメータを取得するために使用します。このメソッドを呼び出してパラメータを渡すと、#{}
これを使用して渡されたパラメータを SQL ステートメントに渡すことができます。
@Select("select * from userinfo where id=#{id}")
public UserInfo getById1(int id);
@Test
void getById1() {
UserInfo userInfo = userInfoMapper.getById1(3);
log.info(userInfo.toString());
}
マッパー インターフェイス型のメソッドに共通の型パラメーターが 1 つしかない場合、#{…} 内の属性名は無造作に記述できますが、それでもパラメーター名との一貫性を保つことをお勧めします。
@Select("select * from userinfo where id=#{userid}")
public UserInfo getById1(Integer id);
もちろん、メソッドのパラメータの名前が良くないと思われる場合は、 を使用して@Param
メソッドのパラメータの名前を変更することもできますが、 を使用して@Param
パラメータの名前を変更する場合、#{…} 内の属性名は同じでなければなりません別名として。
@Select("select * from userinfo where id=#{userid}")
public UserInfo getById1(@Param("userid") Integer id);
@Select("select * from userinfo where id=#{id}")
public UserInfo getById1(@Param("userid") Integer id);
MyBatis はオペレーションを追加します
データベースの主な操作は追加、削除、変更、クエリだけですが、MyBatis を使ってデータベースの追加、削除、変更、クエリを実現するにはどうすればよいでしょうか?
MyBatis は操作を追加するためにアノテーションを使用する必要があります@Insert
。
@Insert("insert into userinfo (username, `password`, age, gender, phone)" +
"values (#{username}, #{password}, #{age}, #{gender}, #{phone})")
public Integer insert(UserInfo userInfo);
@Test
void insert() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("小美");
userInfo.setPassword("小美");
userInfo.setAge(18);
userInfo.setGender(2);
userInfo.setPhone("3139812381");
int ret = userInfoMapper.insert(userInfo);
log.info(ret + "行被更新");
}
ここでは、挿入されたデータを Java オブジェクトにカプセル化してパラメータとして渡すか、各情報をパラメータとして渡すかを選択できます。Java オブジェクトの形式でパラメータとして渡される場合、Java オブジェクト内の属性名はデータベース内の列名と同じにしておく必要があります。渡されたパラメータがオブジェクトの場合、MyBatis はそのオブジェクトに入り、その属性を表示するためです。次に、属性とデータベースの列名が比較され、同じ場合は Java オブジェクトの属性の値が SQL 文に代入され、同じでない場合は含まれません。
主キーを返す
Insert ステートメントは、デフォルトで影響を受ける行の数を返します。必要な場合は、メソッドの戻り値の型を int/Integer として宣言するだけで済みます。そうでない場合は、メソッドの戻り値の型を void として宣言するだけです。
ただし、場合によっては、insert ステートメントの影響を受ける行数だけでなく、自動インクリメントされた主キーの値など、他の情報も取得する必要がある場合があります。挿入後の主キー? 自動インクリメントされる主キー列と同じ名前の Java オブジェクト内の属性を直接取得した場合、取得できるでしょうか。
log.info(ret + "行被更新" + userInfo.getId());
論理的に言えば、この自動インクリメント主キーは 5 である必要がありますが、取得された値は確かに 0 であり、これがまだ初期値であることを示しています。このインサートの?
自動インクリメントされる主キーの値を取得したい場合は、Mapper インターフェースのメソッドにアノテーションを追加する必要があります@Options
。
@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("insert into userinfo (username, `password`, age, gender, phone)" +
"values (#{username}, #{password}, #{age}, #{gender}, #{phone})")
public Integer insert(UserInfo userInfo);
- useGeneratedKeys: これにより、MyBatis は JDB の getGeneratedKeys メソッドを使用して、データベースによって内部的に生成された主キー (MySQL や SQL Server などのリレーショナル データベース管理システムの自動インクリメント フィールドなど) を取得します。デフォルト値: false
- keyProperty: オブジェクトを一意に識別できるプロパティを指定します。MyBatis は、getGeneratedKeys の戻り値または挿入ステートメントの selectKey サブ要素を使用して、その値を設定します。デフォルト値: 未設定
useGeneratedKeys パラメータは、自動増加する主キーを使用する必要があるかどうかを示し、keyProperty パラメータは、自動増加する主キーの値を Java のどのプロパティに割り当てるかを示します。ここで渡すパラメータは Java オブジェクトであるため、したがって、insert によって挿入された行を取得すると、自動インクリメント主キーを id に割り当てた後、MyBatis はこのオブジェクトのプロパティに移動して id 属性があるかどうかを確認し、ある場合はそれに割り当てます。渡されたパラメータが複数の共通型パラメータである場合、MyBatis はこれらの渡されたパラメータの中から同じ名前のパラメータがあるかどうかを検索し、それに割り当てます。
ここでデモするときは、複数回挿入しているため、取得される自動インクリメント主キーの値は 8 です。これはほとんど影響しません。重要なのは、insert で挿入された行の自動インクリメント主キーが 8 であるかどうかを確認することです。 userInfo オブジェクトの id 属性に割り当てられます。
オブジェクトが渡され、パラメータを受け取るときにパラメータの名前が変更される場合、SQL の #{} パラメータでどの属性がどの参照を参照するかを指定する必要があります。
@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("insert into userinfo (username, `password`, age, gender, phone)" +
"values (#{user.username}, #{user.password}, #{user.age}, #{user.gender}, #{user.phone})")
public Integer insert(@Param("user") UserInfo userInfo);
MyBatis 削除操作
MyBatis を使用してデータを削除するには、アノテーションを使用する必要があります@Delete
。
@Delete("delete from userinfo where id=#{id}")
public void delete(Integer id);
@Test
void delete() {
userInfoMapper.delete(1);
}
MyBatis 変更操作
MyBatis は、変更操作を実装するためにアノテーションを使用する必要があります@Update
。
@Update("update userinfo set gender=#{gender} where id=#{id}")
public void update(Integer gender, Integer id);
@Test
void update() {
userInfoMapper.update(0, 8);
}
MyBatis検索操作
これは単なるクエリ操作ではありませんかselect
? 他に言うべきことはありますか?
前のクエリを通じて、Java userInfo オブジェクトの値がすべて初期値であることがわかりますdeleteFlag createTime updateTime
。つまり、これらの属性には値が割り当てられていません。これはなぜでしょうか。私の選択 SQL ステートメントは結果を生成しませんでしたか?
先ほど言ったことを覚えていますか? Java の属性名とデータベース テーブルの列名が一貫していることを確認する必要があります。選択クエリの結果後、MyBatis はメソッドの戻り値の型 (共通型の場合) に従って戻り値を返すからです。選択クエリによって取得された結果の型とメソッド。値の型が同じ場合、クエリ結果が直接返されます。ただし、メソッドの戻り値の型が Java オブジェクトの場合、MyBatis は、 Java オブジェクトの列名とプロパティ名が同じである場合は、このプロパティに値を割り当てます。同じプロパティ名がない場合は、Java オブジェクトのこのプロパティが初期値となります。
データベース テーブルの列名と Java オブジェクトの属性名が一貫していることを確認することが重要ですが、SQL と Java では、変数名の命名規則と習慣に違いがあります。たとえば、SQL では、deletflg はSQL では delete_flag Java では、名前付けはキャメル ケース規則、つまり deleteFlag に基づいています。この場合、名前の一貫性は保証されません。解決策は 3 つあります。
1. クエリ結果のエイリアス化
以前に SQL を学習していたときに、クエリ結果の名前を変更する方法を学んだはずですが、Java 属性名と異なる列名をもつ列の名前を変更できます。
@Select("select id, username, password, age, gender, delete_flag as deleteFlag," +
"create_time as createTime, update_time as updateTime from userinfo")
public List<UserInfo> selectAll1();
@Test
void selectAll1() {
List<UserInfo> list = userInfoMapper.selectAll1();
log.info(list.toString());
}
2. @Results アノテーション
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.METHOD})
public @interface Results {
String id() default "";
Result[] value() default {
};
}
@Results アノテーションには 2 つのパラメータがあります。1 つは String 型です。このパラメータの使用法については後で説明します。2 番目のパラメータは Result[] の配列です。配列内の各要素は Result 型であり、Result 内にあります。パラメータもたくさんありますが、ここでは主に次の 2 つを使用します。
@Results(value = {
@Result(column = "delete_flag", property = "deleteFlag"),
@Result(column = "create_time", property = "createTime"),
@Result(column = "update_time", property = "updateTime")
})
@Select("select id, username, password, age, gender, delete_flag," +
"create_time, update_time from userinfo")
public List<UserInfo> selectAll2();
@Test
void selectAll2() {
List<UserInfo> list = userInfoMapper.selectAll1();
log.info(list.toString());
}
与えられたIDに基づいてクエリを実行したい場合、テーブルの列名がJavaの属性名と異なるため、@Results
上記と同じアノテーションを記述する必要がありますか? いいえ、@Results アノテーションの最初のパラメータが必要です。@Results の最初のパラメータを指定することで、@Results アノテーションを再利用できます。
@Results(id = "BaseMap", value = {
@Result(column = "delete_flag", property = "deleteFlag"),
@Result(column = "create_time", property = "createTme"),
@Result(column = "update_time", property = "updateTime")
})
後続のメソッドでもこの @Results アノテーションと同じ構成を使用する場合は、@ResultMap
メソッドにアノテーションを追加するだけで済みます。
@ResultMap("BaseMap")
@Select("select id, username, password, age, gender, delete_flag," +
"create_time, update_time from userinfo where id=#{id}")
public UserInfo getById2(Integer id);
@Results の同じ構成を使用するには、この @ResultMap のパラメーターが @Results アノテーションの最初のパラメーター ID の値と一致している必要があります。
3. キャメルケースの名前付けをオンにする (推奨)
通常、データベース列はスネーク命名法 (各単語をアンダースコアで区切る) を使用して名前が付けられますが、Java プロパティは通常、キャメルケースの命名規則に従います。これら 2 つの命名メソッド間の自動マッピングを有効にするには、mapUnderscoreToCamelCase を true に設定する必要があります。
mybatis:
configuration:
map-underscore-to-camel-case: true #配置驼峰⾃动转换
この構成を構成ファイルに追加した後、結果をもう一度確認してみましょう。
@Select("select * from userinfo")
public List<UserInfo> selectAll3();
@Test
void selectAll3() {
List<UserInfo> list = userInfoMapper.selectAll3();
log.info(list.toString());
}
SQL と Java の異なる命名規則によって引き起こされる問題を、構成ファイルに構成を追加することで解決するのは非常に便利であることがわかりますので、このアプローチを使用することもお勧めします。
XML 設定ファイルの書き方 MyBatis
データベース関連の構成を構成する
MyBatis をどのような方法で記述する場合でも、最初にデータベース関連の情報を設定する必要がありますが、XML でデータベースの情報を設定する方法は、アノテーションを使用してデータベースを設定する方法と同じですので、ここでは紹介しません。詳細はこちら。
# 数据库连接配置
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mybatis_test?
characterEncoding=utf8&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
XMLのファイルパスを指定します
データベース関連の構成を完了したら、MyBatis XML のファイル パスも指定する必要があります。
mybatis:
mapper-locations: classpath:mapper/**Mapper.xml
このパスはプロジェクトでは次のように表示されます。
クラスパスはプロジェクトのリソース フォルダー、マッパーは MyBatis を操作するために自分で作成したフォルダーです。すべての xml ファイルはこのフォルダーに保存され、この構成内のファイルは**Mapper.xml
Mapper.xml で終わるすべてのファイルを表します。.xml
で終わるファイルを表すには、 を使用して**.xml
それを表します。通常、MyBatis の操作に使用する XML ファイルには、接尾辞として Mapper.xml が付いています。mapper
フォルダーとここは**Mapper.xml
、一致する限り、すべてプログラマーによってカスタマイズされます。
XML実装
まず、xml ファイルに固定フォーマットを追加する必要があります。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper <mapper namespace="com.example.mybatis20231226.Mapper.UserInfoXMLMapper">
</mapper>
ここでの名前空間の値は、実装するインターフェイスの完全修飾クラス名です。
ここのインターフェイスは通常どおりに記述されており、主な操作は XML ファイルにあります。
package com.example.mybatis20231226.Mapper;
import com.example.mybatis20231226.Model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserInfoXMLMapper {
public List<UserInfo> selectAll();
}
後続の実装はタグ内に記述されます<mapper>
。ここでまだクエリを実行していると仮定すると、次のように記述できます。
<mapper namespace="com.example.mybatis20231226.Mapper.UserInfoXMLMapper">
<select id="selectAll" resultType="com.example.mybatis20231226.Model.UserInfo">
select * from userinfo
</select>
</mapper>
id パラメータは実装するインターフェイスのメソッド名を指定し、resultType はメソッドによって返されるデータの型のパスを指定します。これは List ではなく、List 内の要素の型である UserInfo です。
@Slf4j
@SpringBootTest
class UserInfoXMLMapperTest {
@Autowired
private UserInfoXMLMapper userInfoXMLMapper;
@Test
void selectAll() {
List<UserInfo> list = userInfoXMLMapper.selectAll();
log.info(list.toString());
}
}
操作の追加
public Integer insert(UserInfo userInfo);
<insert id="insert">
insert into userinfo (username, password, age, gender, phone)
values(#{username}, #{password}, #{age}, #{gender}, #{phone})
</insert>
@Test
void insert() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("小帅");
userInfo.setPassword("小帅");
userInfo.setAge(28);
userInfo.setGender(1);
userInfo.setPhone("31737137128");
int ret = userInfoXMLMapper.insert(userInfo);
log.info(ret + "被更新");
}
挿入されたデータの自動インクリメント主キーを取得します
挿入されたデータの自動インクリメント主キーを取得するには、パラメータとタグ内のパラメータ<insert>
を設定する必要があります。userGenerateKeys
keyProperty
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
insert into userinfo (username, password, age, gender, phone)
values(#{
username}, #{
password}, #{
age}, #{
gender}, #{
phone})
</insert>
エイリアス
XML エイリアスの操作は、アノテーションを使用する操作と似ています。
public Integer insert(@Param("user") UserInfo userInfo);
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
insert into userinfo (username, password, age, gender, phone)
values(#{user.username}, #{user.password}, #{user.age}, #{user.gender}, #{user.phone})
</insert>
削除操作
public void delete(Integer id);
<delete id="delete">
delete from userinfo where id=#{id}
</delete>
@Test
void delete() {
userInfoXMLMapper.delete(2);
}
操作の変更
public void update(Integer gender, Integer id);
<update id="update">
update userinfo set gender=#{gender} where id=#{id}
</update>
@Test
void update() {
userInfoXMLMapper.update(0, 3);
}
検索操作
これも主に SQL と Java の命名規則の違いに起因する問題を解決するためのもので、解決方法はアノテーションによるものと同様です。
1.別名
public List<UserInfo> selectAll2();
<select id="selectAll2" resultType="com.example.mybatis20231226.Model.UserInfo">
select id, username, password, age, gender, delete_flag as deleteFlag,
create_time as createTime, update_time as updateTime from userinfo
</select>
@Test
void selectAll2() {
List<UserInfo> list = userInfoXMLMapper.selectAll1();
log.info(list.toString());
}
2. 結果の定義
public List<UserInfo> selectAll1();
<resultMap id="XmlBaseMap" type="com.example.mybatis20231226.Model.UserInfo">
<id column="id" property="id"></id>
<result column="delete_flag" property="deleteFlag"></result>
<result column="create_time" property="createTime"></result>
<result column="update_time" property="updateTime"></result>
</resultMap>
<select id="selectAll1" resultMap="XmlBaseMap">
select * from userinfo
</select>
id タグは主キー列と Java オブジェクトの対応関係を識別するために使用され、<result>
タグは非主キー列と Java オブジェクトの対応関係を識別するために使用されます。
@Test
void selectAll1() {
List<UserInfo> list = userInfoXMLMapper.selectAll1();
log.info(list.toString());
}
3. キャメルケースの名前付けを有効にする
これは前のアノテーションと同じで、設定ファイルでキャメルケース変換設定の値を true に設定するだけです。
mybatis:
configuration:
map-underscore-to-camel-case: true #配置驼峰⾃动转换