MyBatis の強力な機能の 1 つは動的 SQL です。 JDBC または他の同様のフレームワークの使用経験がある場合は、さまざまな条件に基づいて SQL ステートメントを結合する難しさを理解できるでしょう。たとえば、スプライスするときは、必要なスペースを忘れずに追加し、リストの最後の列名からカンマを削除するように注意してください。この問題を完全に取り除くには、動的 SQL 機能を利用してください。
これまで動的 SQL を使用するのは簡単ではありませんでしたが、MyBatis は、あらゆる SQL マッピング ステートメントで使用できる強力な動的 SQL 言語を提供することでこの状況を改善しました。
動的 SQL 要素は、JSTL または XML ベースのテキスト プロセッサに似ています。 MyBatis の以前のバージョンでは、理解するのに時間がかかる要素がたくさんありました。 MyBatis 3 では要素の種類が大幅に簡略化され、元の要素の半分を学習するだけで済みます。 MyBatis は強力な OGNL ベースの式を使用して、他のほとんどの要素を排除します。
最初にユーザー エンティティ クラスを作成します
public class User { private Integer id; private String username; private String userEmail; private String userCity; private Integer age;}
ユーザー テーブルを作成します
CREATE TABLE user ( id int(11) NOT NULL AUTO_INCREMENT, username varchar(255) DEFAULT NULL, user_email varchar(255) DEFAULT NULL, user_city varchar(255) DEFAULT NULL, age int(11) DEFAULT NULL, PRIMARY KEY (id))
インターフェースメソッドの定義
public List<User> findByUser(User user);
インターフェースに対応するMapper.xmlの定義は次のとおりです
<select id="findByUser" resultType="com.example.mybatis.entity.User"> select id, username, user_email userEmail, user_city userCity, age from user where <if test="username != null and username != ''"> username = #{username} </if> <if test="userEmail != null and userEmail != ''"> and user_email = #{userEmail} </if> <if test="userCity != null and userCity != ''"> and user_city = #{userCity} </if></select>
ifタグのテストがtrueの場合、SQL文はif タグ内は Splicing になります。
username、userEmail、および userCity が空でない場合、SQL は以下に示すように結合されます
select id, username, user_email userEmail, user_city userCity, age from user where username = ? and user_email = ? and user_city = ?
ユーザー名のみが空でない場合、SQL は結合されます以下に示すように
select id, username, user_email userEmail, user_city userCity, age from user where username = ?
ただし、この方法には欠点があり、このとき username は空であり、userEmail と userCity は空ではないとします。
動的 SQL コードを分析してみましょう。現在、ユーザー名には値が割り当てられていないため、つまり username==null であるため、「username=#{username}」コードは SQL ステートメントに追加されません。最終的に結合された動的 SQL は次のようになります:
select id, username, user_email userEmail, user_city userCity, age from user where and user_email = ? and user_city = ?
where のすぐ後に and が続きますが、これは明らかな構文エラーです。このとき、where# に続く
and は次のようになります。 ## は削除する必要があります。この問題を解決するには、
where タグを使用します。
<select id="findByUser" resultType="com.example.mybatis.entity.User"> select id, username, user_email userEmail, user_city userCity, age from user <where> <if test="username != null and username != ''"> username = #{username} </if> <if test="userEmail != null and userEmail != ''"> and user_email = #{userEmail} </if> <if test="userCity != null and userCity != ''"> and user_city = #{userCity} </if> </where> </select>
where##if に変更します。
タグが条件を満たしている場合、where
タグは where ステートメントに接続されます。if
タグで接続された SQL の先頭に and ステートメントがある場合、フロントにすると、 and が where ステートメントに結合されます。この方法を利用すると、SQL中の不要なキーワードが自動的に削除されるので、一般的にifタグとwhereタグを組み合わせて使用します。
タグの prefix
属性と suffix
属性は、次の目的で使用されます。実際の SQL ステートメントは、ラベル内のステートメントと結合されます。
または suffixOverrides
属性で指定された値がステートメントの前後に見つかった場合、MyBatis はそれらを自動的に削除します。複数の値を指定する場合は、後続の SQL に接続されないように、各値の後にスペースを入れることを忘れないでください。
: 結合された SQL ステートメントに接頭辞を追加します。
suffix: 結合された SQL ステートメントに接尾辞を追加します
prefixOverrides: 接続された SQL ステートメントの前に prefixOverrides が見つかった場合、MyBatis はそれらを自動的に削除します。
: Ifこれは、結合された SQL ステートメント suffixOverrides の後に発生します。MyBatis はそれらを自動的に削除します。以下の
タグを使用して、where の関数を実装します。
tag<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><select id="findByUser" resultType="com.example.mybatis.entity.User">
select
id, username, user_email userEmail, user_city userCity, age
from user <trim prefix="where" prefixOverrides="and">
<if test="username != null and username != &#39;&#39;">
username = #{username} </if>
<if test="userEmail != null and userEmail != &#39;&#39;">
and user_email = #{userEmail} </if>
<if test="userCity != null and userCity != &#39;&#39;">
and user_city = #{userCity} </if>
</trim>
</select></pre><div class="contentsignin">ログイン後にコピー</div></div>
ユーザー名が空で、userEmail と userCity が空でない場合、
ラベル結合の SQL ステートメントは次のとおりです。<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">and user_email = #{userEmail} and user_city = #{userCity}</pre><div class="contentsignin">ログイン後にコピー</div></div>
理由は、
ラベルは prefixOverrides="and" で設定されており、上記の SQL ステートメントの前に and ステートメントがあるため、上記の and ステートメントを削除する必要があります。タグが prefix="where" で設定されている場合は、結合された SQL ステートメントの前に where ステートメントを追加する必要があります。 Finally
trim
タグの SQL ステートメントが結合されます次のように
where user_email = #{userEmail} and user_city = #{userCity}
choose
<select id="findByUser" resultType="com.example.mybatis.entity.User"> select id, username, user_email userEmail, user_city userCity, age from user <where> <choose> <when test="username != null and username != ''"> username = #{username} </when> <when test="userEmail != null and userEmail != ''"> and user_email = #{userEmail} </when> <when test="userCity != null and userCity != ''"> and user_city = #{userCity} </when> </choose> </where> </select>
set
public int updateUser(User user);
インターフェイスに対応する Mapper.xml 定義は次のとおりです
<update id="updateUser" parameterType="com.example.mybatis.entity.User"> update user <set> <if test="username != null and username != ''"> username=#{username}, </if> <if test="userEmail != null and userEmail != ''"> user_email=#{userEmail}, </if> <if test="userCity != null and userCity != ''"> user_city=#{userCity}, </if> <if test="age != null"> age=#{age} </if> </set> where id=#{id} </update>
接口定义如下所示
public List<User> getUsersByIds(List<Integer> ids);
接口对应的 Mapper.xml 定义如下所示
<!-- collection: 指定要遍历的集合 默认情况下 如果为Collection类型的,key为collection; 如果为List类型的,key为list 如果是数组类型,key为array 可以通过@Param("ids")来指定key item: 将当前遍历的元素赋值给指定的变量 open: 给遍历的结果添加一个开始字符 close: 给遍历的结果添加一个结束字符 separator: 每个元素之间的分隔符 --><select id="getUsersByIds" resultType="com.example.mybatis.entity.User"> select * from user where id in <foreach collection="list" item="id" open="(" close=")" separator=","> #{id} </foreach></select>
用于批量插入
接口定义如下所示
public int addUserList(List<User> users);
接口对应的 Mapper.xml 定义如下所示
<insert id="addUserList" parameterType="com.example.mybatis.entity.User"> insert into user (username, user_email, user_city, age) values <foreach item="user" collection="list" separator=","> (#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age}) </foreach></insert><!--返回自增主键--><insert id="addUserList" parameterType="com.example.mybatis.entity.User" useGeneratedKeys="true" keyProperty="id"> insert into user (username, user_email, user_city, age) values <foreach item="user" collection="list" separator=","> (#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age}) </foreach></insert><!--还可以这样写--><!-- 这种方式需要数据库连接属性设置allowMultiQueries=true 这种分号分隔多个SQL还可以用于其他的批量操作,如修改、删除 --><insert id="addUserList" parameterType="com.example.mybatis.entity.User"> <foreach item="user" collection="list" separator=";"> insert into user (username, user_email, user_city, age) values (#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age}) </foreach></insert><!--如果是Oracle数据库,则需要这样写--><insert id="addUserList" parameterType="com.example.mybatis.entity.User"> <foreach item="user" open="begin" close="end;" collection="list"> insert into user (username, user_email, user_city, age) values (#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age}); </foreach></insert>
以上がMyBatis動的SQLを学ぶの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。