13、動的SQL
動的SQLとは
動的SQLとは:動的SQLとは、さまざまなクエリ条件に従ってさまざまなSqlステートメントを生成することを指します。
官网描述:
MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形。
动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。
-------------------------------
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
-------------------------------
以前に作成したSQLステートメントは比較的単純です。より複雑なビジネスがある場合は、複雑なSQLステートメントを作成する必要があります。これは、多くの場合、スプライスが必要です。スプライシングSQL、少し不注意、引用符やスペースの欠落などがあります。エラーを引き起こします。
では、この問題をどのように解決するのでしょうか?これには、mybatis動的SQLを使用する必要があります。if、choose、when、else、trim、where、set、foreachなどのタグを使用して、非常に柔軟なSQLステートメントに組み合わせることができるため、SQLの精度が向上します。また、大幅に改善しながらステートメント開発者の効率を向上させます。
いわゆる動的SQLは本質的にSQLステートメントですが、SQLレベルでロジックコードを実行できます。
環境をセットアップする
前の従業員エンティティクラスを直接使用するだけです。
-
lombokの依存関係をインポートする
-
新しいPojoエンティティクラスの従業員
-
EmployeeMapperインターフェイスを作成し、いくつかの抽象メソッドを記述します
-
リソースパッケージにEmployeeMapper.xmlを作成して記述します
-
コア構成ファイルmybatis-config.xmlファイルのEmployeeMapper.xmlリソースをバインドします
-
テストクラスを書く
もし
<select id="getEmployeeDynamicSQL" parameterType="map" resultType="Employee">
select * from employee where 1 = 1
<if test="age != null">
and age = #{age}
</if>
<if test="dept_id != null">
and dept_id = #{dept_id}
</if>
</select>
@Test
public void getEmployeeDynamicSQL(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("age",20);
// map.put("dept_id",1);
List<Employee> employees = mapper.getEmployeeDynamicSQL(map);
for (Employee employee : employees) {
System.out.println(employee);
}
}
このメソッドは比較的厳密です。SQLステートメントのwhereを取得してアクティブ化する必要があります。条件が満たされない場合は、テーブル全体のクエリが実行され、両方が満たされる場合は、条件付きユニオンクエリが実行されます。
選択します(それ以外の場合)
<select id="getEmployeeDynamicSQL3" parameterType="map" resultType="Employee">
select * from employee
<where>
<choose>
<when test="age != null">
age = #{age}
</when>
<when test="dept_id != null">
dept_id = #{dept_id}
</when>
<otherwise>
id = #{id}
</otherwise>
</choose>
</where>
</select>
@Test
public void getEmployeeDynamicSQL3(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
HashMap<String, Object> map = new HashMap<String, Object>();
// map.put("age",20);
// map.put("dept_id",1);
map.put("id",7);
List<Employee> employees = mapper.getEmployeeDynamicSQL3(map);
for (Employee employee : employees) {
System.out.println(employee);
}
}
条件に応じて実行の1つをこのように選択するには、前のifとの比較とメモリが必要です。
トリム(どこで、設定)
ifで使用される場所
<select id="getEmployeeDynamicSQL2" parameterType="map" resultType="Employee">
select * from employee
<where>
<if test="age != null">
and age = #{age}
</if>
<if test="dept_id != null">
and dept_id = #{dept_id}
</if>
</where>
</select>
@Test
public void getEmployeeDynamicSQL2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("age",20);
map.put("dept_id",1);
List<Employee> employees = mapper.getEmployeeDynamicSQL2(map);
for (Employee employee : employees) {
System.out.println(employee);
}
}
変更の設定変更の実行SQL
<update id="updateEmployeeDynamicSQL" parameterType="map">
update employee
<set>
<if test="name != null">name = #{name},</if>
<if test="age != null">age = #{age},</if>
<if test="dept_id != null">dept_id = #{depid}</if>
</set>
where id = #{id}
</update>
@Test
public void updateEmployeeDynamicSQL(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
HashMap<String, Object> map = new HashMap<String, Object>();
// map.put("age",20);
// map.put("dept_id",1);
map.put("id",7);
map.put("name","王炸炸");
map.put("age",18);
mapper.updateEmployeeDynamicSQL(map);
}
SQLフラグメント
時々、再利用を容易にするためにいくつかの機能部品を抽出することがあります!
-
SQLタグを使用して一般的な部分を抽出します
<sql id="age-dept_id"> <if test="age != null"> and age = #{age} </if> <if test="dept_id != null"> and dept_id = #{dept_id} </if> </sql>
-
使用する必要がある場合は、インクルードタグリファレンスを使用してください
<select id="getEmployeeDynamicSQL2" parameterType="map" resultType="Employee"> select * from employee <where> <include refid="age-dept_id"/> </where> </select>