この記事の一部は機械翻訳を使ってるよ
MyBatis シリーズ
インストールと開始方法: https://blog.yexca.net/ja/archives/215
使い方: この記事
削除
パラメータ名を中に入れたプレースホルダとして #{}
を使用します
@Mapper
public interface EmpMapper {
// 削除
@Delete("delete from mybatis.emp where id = #{id}")
public void delete(Integer id);
}
テスト
@SpringBootTest
class Mybatis02ApplicationTests {
@Autowired
private EmpMapper empMapper;
@Test
void contextLoads() {
empMapper.delete(17);
}
}
通常、戻り値は必要ありません。戻り値は、この操作によって影響を受ける行の数です。
@Mapper
public interface EmpMapper {
// 削除
@Delete("delete from mybatis.emp where id = #{id}")
public int delete(Integer id);
}
プレースホルダー
パラメータプレースホルダは #{}
と ${}
です
プレースホルダー | #{} |
${} |
---|---|---|
形状 | プリコンパイル | スプライシング |
いつ使うか | パラメータの受け渡し、ログインなど | テーブル名とリストを動的に設定する |
長所と短所 | 安全性と高性能 | SQLインジェクションの問題がある |
挿入(新規)
プレースホルダも使用されますが、渡されるパラメータが多すぎる場合は、オブジェクトのカプセル化を使用することができ、正式なパラメータ名はオブジェクトのパラメータ名になります。
@Mapper
public interface EmpMapper {
// 増加
@Insert("insert into mybatis.emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) "+
"values (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime});")
public void insert(Emp emp);
}
テスト
@SpringBootTest
class Mybatis02ApplicationTests {
@Autowired
private EmpMapper empMapper;
@Test
public void testInsert(){
Emp emp = new Emp();
emp.setUsername("Tom");
emp.setName("トム");
emp.setGender((short) 1);
emp.setImage("tom.jpg");
emp.setJob((short) 1);
emp.setEntrydate(LocalDate.of(2000,1,1));
emp.setDeptId(1);
emp.setCreateTime(LocalDateTime.now());
emp.setUpdateTime(LocalDateTime.now());
empMapper.insert(emp);
}
}
主キーの値を取得する
場合によっては、データが正常に追加された後、データベースに挿入されたデータの主キーを取得する必要があります。
@Mapper
public interface EmpMapper {
// 主キーを取得します。最初の属性は、emp オブジェクトの id 属性に割り当てられた主キー値を定義します。2 番目の属性は、返される主キー値を表します。
@Options(keyProperty = "id", useGeneratedKeys = true)
// 増加
@Insert("insert into mybatis.emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) "+
"values (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime});")
public void insert(Emp emp);
}
更新(変更)
増加と同様に、オブジェクトにカプセル化することができます
@Mapper
public interface EmpMapper {
// 変更
@Update("update mybatis.emp set username = #{username}, name = #{name}, gender = #{gender}, image = #{image}, job = #{job}, "+
"entrydate = #{entrydate}, dept_id = #{deptId}, update_time = #{updateTime} where id = #{id};")
public void update(Emp emp);
}
テスト
@SpringBootTest
class Mybatis02ApplicationTests {
@Autowired
private EmpMapper empMapper;
@Test
public void testUpdate(){
Emp emp = new Emp();
emp.setUsername("Tom2");
emp.setName("トム2");
emp.setGender((short) 1);
emp.setImage("tom.jpg");
emp.setJob((short) 1);
emp.setEntrydate(LocalDate.of(2000,1,1));
emp.setDeptId(1);
emp.setUpdateTime(LocalDateTime.now());
emp.setId(19);
empMapper.update(emp);
}
}
クエリ
クエリには、IDに基づいてすべての属性をクエリするクエリと条件に基づいてクエリするクエリの2種類があります。
IDによるクエリ
インタフェース
@Mapper
public interface EmpMapper {
// IDによるクエリ
@Select("select * from mybatis.emp where id = #{id}")
public Emp idSelect(Integer id);
}
テスト
@SpringBootTest
class Mybatis02ApplicationTests {
@Autowired
private EmpMapper empMapper;
@Test
public void testIdSelect(){
Emp emp = empMapper.idSelect(19);
System.out.println(emp);
}
}
結果
Emp(id=19, username=Tom2, password=123456, name=汤姆2, gender=1, image=tom.jpg, job=1, entrydate=2000-01-01, deptId=null, createTime=null, updateTime=null)
クラス Emp のフィールド名がデータベースと異なるため、クエリ結果は null になります。
解決方法は3つあります
エイリアスの使用
@Mapper
public interface EmpMapper {
// 方法 1: エイリアス
@Select("select id, username, password, name, gender, image, job, entrydate, dept_id deptId, create_time createTime, update_time updateTime" +
" from mybatis.emp where id = #{id}")
public Emp idSelect(Integer id);
}
@Results アノテーションの使用
@Mapper
public interface EmpMapper {
// 方法 2: @Results @Result アノテーション
@Results({
@Result(column = "dept_id", property = "deptId"),
@Result(column = "create_time", property = "createTime"),
@Result(column = "update_time", property = "updateTime")
})
@Select("select * from mybatis.emp where id = #{id}")
public Emp idSelect(Integer id);
}
自動包装の使用
フィールド名と属性名がキャメルケース命名規則に準拠している場合は、自動キャメルケース命名カプセル化を有効にすることができ、Mybatisはキャメルケース命名規則に従って自動的にマッピングします。具体的には、データベースはアンダースコア「a_column」をJava属性「aColumn」にマッピングします。
キャメルケース命名を有効にするには、application.properties
に追加します。
mybatis.configuration.map-underscore-to-camel-case=true
然后直接使用最初的代码
@Mapper
public interface EmpMapper {
// IDによるクエリ
@Select("select * from mybatis.emp where id = #{id}")
public Emp idSelect(Integer id);
}
使いやすさのために、IDEA に MyBatisX プラグインをインストールすることができます。
条件による検索
要件: 従業員名 (あいまい一致)、性別 (完全一致)、雇用日 (範囲) に基づいて条件を満たす従業員情報を検索します。
@Mapper
public interface EmpMapper {
// 条件による検索
// '%${name}%' のように名前に使用される ${} は、'' 内でも使用できることに注意してください。
@Select("select * from mybatis.emp where name like '%${name}%' and gender = #{gender} and " +
"entrydate between #{begin} and #{end} order by update_time desc")
public List<Emp> conditionSelect(String name, short gender, LocalDate begin, LocalDate end);
}
文字列の連結には補間が使用されるため、この方法は安全ではありません。
@Mapper
public interface EmpMapper {
// より安全な条件付きクエリ
@Select("select * from mybatis.emp where name like concat('%',#{name},'%') and gender = #{gender} and " +
"entrydate between #{begin} and #{end} order by update_time desc")
public List<Emp> conditionSelect(String name, short gender, LocalDate begin, LocalDate end);
}
concat 関数は文字列を連結するために使用されます。テスト
@SpringBootTest
class Mybatis02ApplicationTests {
@Autowired
private EmpMapper empMapper;
@Test
public void testConditionSelect(){
List<Emp> empList = empMapper.conditionSelect("张", (short) 1, LocalDate.of(2010, 1, 1), LocalDate.of(2020, 1, 1));
System.out.println(empList);
}
}
パラメータ名の説明
SQLで使用される#{}
内の変数名はSpringBoot 2.x以降では自動的に認識されますが、バージョン1.xまたはMyBatisのみを使用する場合は、メソッド内で定義された変数名をアノテーションを使用して指定する必要があります。
@Mapper
public interface EmpMapper {
// より安全な条件付きクエリ
@Select("select * from mybatis.emp where name like concat('%',#{name},'%') and gender = #{gender} and " +
"entrydate between #{begin} and #{end} order by update_time desc")
public List<Emp> conditionSelect(String name, short gender, LocalDate begin, LocalDate end);
}
// 上記のコードは1.xでは動作しません。またMyBatisのみを使用する場合も動作しません。関数に注釈を付ける必要がある。
public List<Emp> conditionSelect(@Param("name") String name, @Param("gender") short gender, @Param("begin") LocalDate begin, @Param("end") LocalDate end);
XML マッピングファイルの使用
SQL コードが比較的短い場合は、アノテーションを使用すると便利ですが、SQL が長かったり複雑だったりする場合は、少し乱雑に見えます。この目的のために、XML マッピング ファイルを使用できます。仕様は以下の通りです
- XML マッピングファイルの名前は Mapperイ ンターフェースの名前と一致しており、XML マッピングファイルと Mapper インターフェースは同じパッケージ(同じパッケージ、同じ名前)に配置されています。
- XML の名前空間属性は Mapper インターフェースの完全修飾名と一致している
- XML 内の SQL 文の id 属性は Mapper インターフェースのメソッド名と一致しており、戻り値の型も一致している
XML
Maven プロジェクトでは、Java 以外のファイルは src/main/resources
の下に配置されます。このディレクトリの下に Mapper インターフェースと一致するディレクトリを作成します。
インターフェースが net.yexca.mapper.EmpMapper.java
の場合、XML ファイルは net.yexca.mapper.EmpMapper.xml
にあります。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 上記のヘッダーファイルを見つけるには、公式ウェブサイトにアクセスしてください。 -->
<!-- namespace 属性はインターフェースである -->
<mapper namespace="net.yexca.mapper.EmpMapper">
<!-- id属性はメソッド名です -->
<!-- resultTypeは単一のレコードでカプセル化された型です -->
<select id="conditionSelect" resultType="net.yexca.pojo.Emp">
select * from mybatis.emp where name like concat('%',#{name},'%') and gender = #{gender} and
entrydate between #{begin} and #{end} order by update_time desc
</select>
</mapper>
インターフェースクラス
@Mapper
public interface EmpMapper {
public List<Emp> conditionSelect(String name, short gender, LocalDate begin, LocalDate end);
}
動的 SQL
動的 SQL は、ユーザー入力または外部条件に応じて変化する SQL ステートメントです。
たとえば、上記の最後の条件クエリでは、クエリを実行するために 3 つの条件すべてを入力する必要があります。実際の使用では、1 つまたは 2 つの条件のみを指定するか、指定しない (すべてをクエリする) ことができます。上記の手順に従って実行すると、空の結果が返されます。
where if
条件が真であるかどうかを判断するために使用されます。条件判定を実行するには、テスト属性を使用します。条件が真の場合、SQLを連結します。
たとえば、名前が空でない場合、連結条件は名前によって照会されます。
<if test="name!=null">
name like contact('%',#{name},'%')
</if>
where タグは、where キーワードを生成するかどうか、および and キーワードと or キーワードを自動的に削除するかどうかを管理します。
<select id="conditionSelect" resultType="net.yexca.pojo.Emp">
select * from mybatis.emp
<where>
<if test="name!=null">
name like concat('%',#{name},'%')
</if>
<if test="gender!=null">
and gender = #{gender}
</if>
<if test="begin!=null and end!=null">
and entrydate between #{begin} and #{end}
</if>
</where>
order by update_time desc
</select>
set
SQL の set キーワードを置き換え、UPDATE ステートメントで使用する余分なカンマを自動的に削除します。
たとえば、次のSQL文は動的SQLに変更されます。
update mybatis.emp
set username = #{username},
name = #{name},
gender = #{gender},
image = #{image},
job = #{job},
entrydate = #{entrydate},
dept_id = #{deptId},
update_time = #{updateTime}
where id = #{id};
XML
<update id="update2">
update mybatis.emp
<set>
<if test="username != null">username = #{username},</if>
<if test="name != null">name = #{name},</if>
<if test="gender != null">gender = #{gender},</if>
<if test="image != null">image = #{image},</if>
<if test="job != null">job = #{job},</if>
<if test="entrydate != null">entrydate = #{entrydate},</if>
<if test="deptId != null">dept_id = #{deptId},</if>
<if test="updateTime != null">update_time = #{updateTime}</if>
</set>
where id = #{id};
</update>
foreach
foreach タグはトラバーサルに使用されます
<!--走査するコレクション 横断された要素 デリミタ 開始前と開始後に連結されたSQLフラグメント-->
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
ids が [13, 14, 15] の場合、上記は (13,14,15)
を生成します。
要件: ID 1、2、3 の項目を走査して削除します。 SQL文は
delete from emp where id in(1,2,3)
インターフェースメソッド
public void deleteByIds(List<Integer> ids);
XML
<delete id="deleteByIds">
delete from mybatis.emp where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
テスト
@Test
public void testDeleteByIds(){
List<Integer> ids = Arrays.asList(13,14,15);
empMapper.deleteByIds(ids);
}
sql と include
開発プロセスでは、多数の SQL ステートメントが繰り返される場合があります。sql タグを使用して再利用可能な SQL フラグメントを定義し、include タグを使用して再利用できます。
<!-- id属性を通じてステートメントを一意に識別する -->
<sql id = "commonCode">
<!-- SQL语句 -->
</sql>
<!-- refid 属性は参照ステートメントを指定します。 -->
<include refid = "commonCode" />