【Mybatisの入門から実戦までのチュートリアル】第4章 Mybatisの入力マッピング、出力マッピング、動的SQLの詳細解説

4. Mybatis Mapper 設定ファイル

データベースを操作するための Sql は mapper.xml マッピング ファイルで定義されます.各 Sql はステートメントであり、マッピング ファイルは MyBatis のコアです。

4.1 parameterType 入力マッピング

    parameterType は、入力パラメーターのタイプを構成します。

4.1.1 テーブル構造

CREATE TABLE `users`  (
  `id` int(11) PRIMARY KEY AUTO_INCREMENT,
  `username` varchar(20),
  `password` varchar(50),
  `realname` varchar(20)
);

INSERT INTO `users` VALUES (1, 'admin', '123456', '管理员');
INSERT INTO `users` VALUES (2, 'tom', '123', '汤姆');
INSERT INTO `users` VALUES (3, 'jerry', '456', '杰瑞');
INSERT INTO `users` VALUES (4, 'zhangsan', '111', '张三');
INSERT INTO `users` VALUES (5, 'lisi', '222', '李四');

4.1.2 エンティティクラス

package com.newcapec.entity;

public class Users {

    private Integer id;
    private String username;
    private String password;
    private String realname;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getRealname() {
        return realname;
    }

    public void setRealname(String realname) {
        this.realname = realname;
    }

    @Override
    public String toString() {
        return "Users{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", realname='" + realname + '\'' +
                '}';
    }
}

4.1.3 単純型

    Java の基本的なデータ型とパッケージング クラス、String 文字列型。

マッパー インターフェイス:

package com.newcapec.mapper;

import com.newcapec.entity.Users;

import java.util.List;

public interface UsersMapper {
    List<Users> selectByRealname(String realname);
}

マッパーファイル:

<?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 namespace="com.newcapec.mapper.UsersMapper">

    <select id="selectByRealname" parameterType="java.lang.String" resultType="com.newcapec.entity.Users">
        select id,username,password,realname from users where realname like concat('%',#{realname},'%')
    </select>
</mapper>

テスト:

package com.newcapec;

import com.newcapec.entity.Users;
import com.newcapec.mapper.UsersMapper;
import com.newcapec.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class ParameterTypeTest {

    @Test
    public void testSimpleParam() {
        SqlSession sqlSession = MybatisUtil.getSession();
        UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
        List<Users> list = usersMapper.selectByRealname("张");
        for (Users users : list) {
            System.out.println(users);
        }
        sqlSession.close();
    }
}

4.1.4 エンティティ クラスまたはカスタム型

    開発時、クエリ条件はエンティティクラスまたは pojo タイプを介して渡されます.クエリ条件は、エンティティクラス内のクエリ条件だけでなく、他のクエリ条件も含む包括的なクエリ条件です.このとき、ラッパーオブジェクトを使用できます.入力パラメータを渡します。

  • カスタムタイプ

ページネーション クラス:

package com.newcapec.entity;

/**
 * 分页类
 */
public class Page {

    //当前页码
    private Integer pageNum = 1;
    //每页条数
    private Integer pageSize = 3;
    //总页数: 总记录数/每页条数,除不尽+1
    private Integer pages;
    //总记录数
    private Integer total;

    /**
     * mysql
     * 起始偏移量:(当前页码-1)*每页条数
     */
    private Integer offset;

    /**
     * oracle
     * 起始条数:(当前页码-1)*每页条数+1
     * 结束条数: 当前页码*每页条数
     */
    private Integer start;
    private Integer end;

    public Integer getPageNum() {
        return pageNum;
    }

    public void setPageNum(Integer pageNum) {
        this.pageNum = pageNum;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public Integer getPages() {
        return getTotal() % getPageSize() == 0 ? getTotal() / getPageSize() : getTotal() / getPageSize() + 1;
    }

    public void setPages(Integer pages) {
        this.pages = pages;
    }

    public Integer getTotal() {
        return total;
    }

    public void setTotal(Integer total) {
        this.total = total;
    }

    public Integer getOffset() {
        return (getPageNum() - 1) * getPageSize();
    }

    public void setOffset(Integer offset) {
        this.offset = offset;
    }

    public Integer getStart() {
        return (getPageNum() - 1) * getPageSize() + 1;
    }

    public void setStart(Integer start) {
        this.start = start;
    }

    public Integer getEnd() {
        return getPageNum() * getPageSize();
    }

    public void setEnd(Integer end) {
        this.end = end;
    }
}

複合クラス: UsersQuery

package com.newcapec.entity;

/**
 * 多条件查询复合类
 */
public class UsersQuery {

    private Users users;
    private Page page;

    public Users getUsers() {
        return users;
    }

    public void setUsers(Users users) {
        this.users = users;
    }

    public Page getPage() {
        return page;
    }

    public void setPage(Page page) {
        this.page = page;
    }
}
  • マッパー インターフェイス
List<Users> selectByPage(Page page);

List<Users> selectByRealnameAndPage(UsersQuery usersQuery);
  • マッパーファイル
<select id="selectByPage" parameterType="com.newcapec.entity.Page" resultType="com.newcapec.entity.Users">
    select id,username,password,realname from users order by id limit #{offset}, #{pageSize}
</select>

<select id="selectByRealnameAndPage" parameterType="com.newcapec.entity.UsersQuery" resultType="com.newcapec.entity.Users">
    select id,username,password,realname from users
    where realname like concat('%',#{users.realname},'%')
    order by id limit #{page.offset}, #{page.pageSize}
</select>
  • テスト
@Test
public void testClassParam1() {
    SqlSession sqlSession = MybatisUtil.getSession();
    UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
    Page page = new Page();
    page.setPageNum(1);

    System.out.println("mysql起始偏移量:" + page.getOffset());
    System.out.println("起始条数:" + page.getStart());
    System.out.println("结束条数:" + page.getEnd());
    List<Users> list = usersMapper.selectByPage(page);
    for (Users users : list) {
        System.out.println(users);
    }
    sqlSession.close();
}

@Test
public void testPojoParam2() {
    SqlSession sqlSession = MybatisUtil.getSession();
    UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
    Page page = new Page();
    page.setPageNum(1);

    Users users = new Users();
    users.setRealname("张");
    UsersQuery usersQuery = new UsersQuery();
    usersQuery.setPage(page);
    usersQuery.setUsers(users);

    List<Users> list = usersMapper.selectByRealnameAndPage(usersQuery);
    for (Users u : list) {
        System.out.println(u);
    }
    sqlSession.close();
}

4.1.5 地図の種類

マッパー インターフェイス:

List<Users> selectUseMap(Map<String, Object> map);

マッパーファイル:

<select id="selectUseMap" parameterType="java.util.HashMap" resultType="com.newcapec.entity.Users">
    select id,username,password,realname from users
    where realname like concat('%',#{name},'%')
    order by id limit #{begin}, #{size}
</select>

テスト:

@Test
public void testMapParam() {
    SqlSession sqlSession = MybatisUtil.getSession();
    UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
    Map<String, Object> map = new HashMap<>();
    map.put("name", "李");
    map.put("size", 5);
    map.put("begin", 0);

    List<Users> list = usersMapper.selectUseMap(map);
    for (Users u : list) {
        System.out.println(u);
    }
    sqlSession.close();
}

4.1.6 複数の入力パラメータ

    MyBatis では複数の入力パラメーターが許可されており、@Param で注釈を付けることができます。

    このアプローチは、 @Param アノテーションの value 属性が Map のキーである Map タイプの入力パラメータに似ており、対応する値はマッピング ファイルの ognl を介して取得でき、parameterType は必要ありません。タイプを指定します。

マッパー インターフェイス:

Users login(@Param("uname") String username, @Param("pwd") String password);

マッパーファイル:

<select id="login" parameterType="java.util.HashMap" resultType="com.newcapec.entity.Users">
    select id,username,password,realname from users
    where username=#{uname} and password=#{pwd}
</select>

テスト:

@Test
public void testMultiParam() {
    SqlSession sqlSession = MybatisUtil.getSession();
    UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);

    Users users = usersMapper.login("jerry", "456");
    System.out.println(users);
    sqlSession.close();
}

4.2 resultType 出力マッピング

4.2.1 テーブル構造

CREATE TABLE `person`  (
  `id` int(11) PRIMARY KEY AUTO_INCREMENT,
  `person_name` varchar(20),
  `person_age` int(4),
  `person_address` varchar(50)
);

INSERT INTO `person` VALUES (1, '曹操', 40, '洛阳');
INSERT INTO `person` VALUES (2, '刘备', 38, '成都');
INSERT INTO `person` VALUES (3, '孙权', 29, '杭州');
INSERT INTO `person` VALUES (4, '关羽', 35, '荆州');
INSERT INTO `person` VALUES (5, '张飞', 32, '成都');
INSERT INTO `person` VALUES (6, '曹仁', 28, '许都');

4.2.2 エンティティクラス

package com.newcapec.entity;

public class Person {

    private Integer id;
    private String personName;
    private Integer personAge;
    private String personAddress;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getPersonName() {
        return personName;
    }

    public void setPersonName(String personName) {
        this.personName = personName;
    }

    public Integer getPersonAge() {
        return personAge;
    }

    public void setPersonAge(Integer personAge) {
        this.personAge = personAge;
    }

    public String getPersonAddress() {
        return personAddress;
    }

    public void setPersonAddress(String personAddress) {
        this.personAddress = personAddress;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", personName='" + personName + '\'' +
                ", personAge=" + personAge +
                ", personAddress='" + personAddress + '\'' +
                '}';
    }
}

4.2.3 単純型

    クエリの結果セットには 1 つの行と 1 つの列しかなく、出力マッピングには単純型を使用できます。

マッパー インターフェイス:

package com.newcapec.mapper;

public interface PersonMapper {
    // 查询Person的总数量
    Integer selectCount();
}

マッパーファイル:

<?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 namespace="com.newcapec.mapper.PersonMapper">

    <select id="selectCount" resultType="java.lang.Integer">
        select count(1) from person
    </select>
</mapper>

テスト:

public class ResultTypeTest {

    @Test
    public void testSimpleResult() {
        SqlSession sqlSession = MybatisUtil.getSession();
        PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);

        int total = personMapper.selectCount();
        System.out.println("总记录数:" + total);
        sqlSession.close();
    }
}

4.2.4 エンティティークラスのオブジェクトとリスト

    出力エンティティクラスが単一のオブジェクトかリスト(エンティティクラスのオブジェクトを含むリスト)かに関わらず、mapper.xmlのresultTypeで指定された型は同じであり、元のDaoメソッドでは、戻り値はselectOneによって区別されます。および selectList
メソッド 単一のオブジェクトまたはコレクションのリスト、およびマッパー プロキシでは、インターフェイスで定義されたメソッドの戻り値によって区別されます。

マッパー インターフェイス:

Person selectById(Integer id);

List<Person> selectAll();

マッパーファイル:

<select id="selectById" parameterType="java.lang.Integer" resultType="com.newcapec.entity.Person">
    select id,person_name personName,person_age personAge,person_address personAddress from person where id=#{id}
</select>

<select id="selectAll" resultType="com.newcapec.entity.Person">
    select id,person_name personName,person_age personAge,person_address personAddress from person
</select>

テスト:

@Test
public void testResultType1() {
    SqlSession sqlSession = MybatisUtil.getSession();
    PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);

    Person person = personMapper.selectById(1);
    System.out.println(person);
    sqlSession.close();
}

@Test
public void testResultType2() {
    SqlSession sqlSession = MybatisUtil.getSession();
    PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);

    List<Person> list = personMapper.selectAll();
    for (Person person : list) {
        System.out.println(person);
    }
    sqlSession.close();
}

4.2.5 結果マップ

  • resultType は、クエリの結果がエンティティ クラスにマップされることを指定できますが、エンティティ クラスの属性名は、正常にマップされる SQL クエリの列名と一致している必要があります。もちろん、アンダースコアをキャメル ケースまたは Sql に有効にすると、列エイリアスを設定します。自動的にマップすることもできます。

  • SQL クエリ フィールド名がエンティティ クラスの属性名と一致しない場合、resultMap を使用してフィールド名と属性名の間に対応する関係を作成できます。resultMap は基本的にクエリ結果をエンティティ クラス オブジェクトにマップします。 .

  • resultMap は、クエリ結果マッピング オブジェクトにエンティティ クラスとリストを含めて、1 対 1 クエリと 1 対多クエリを実現するなど、クエリ結果の複合エンティティ クラスへのマッピングを実現できます。

マッパー インターフェイス:

List<Person> select();

マッパーファイル:

    ステートメントの出力マッピング タイプとして resultMap を使用します。

<resultMap id="selectResultMap" type="com.newcapec.entity.Person">
    <id property="id" column="id"/>
    <result property="personName" column="person_name"/>
    <result property="personAge" column="person_age"/>
    <result property="personAddress" column="person_address"/>
</resultMap>
<select id="select" resultMap="selectResultMap">
    select id,person_name,person_age,person_address from person
</select>
  • resultType: 自動マッピング

  • resultMap: 手動マッピング

    • id: 一意の識別子、名前。

    • type: 手動でマップされた Java タイプ

    • サブラベル データベーステーブルの主キーとエンティティクラスの属性の対応<id/>を設定

    • サブタグ データベース テーブルの共通フィールドとエンティティ クラスの属性間の対応<result/>を設定します

      • プロパティ: エンティティ クラスのメンバー変数の名前

      • column: 結果セット内のフィールドの名前

      • javaType: mybaits によって自動的に認識されるエンティティ クラス メンバー変数の型であり、構成する必要はありません。

      • jdbcType: mybaits によって自動的に認識され、設定できないテーブル フィールドのタイプ

      • typeHandler: カスタム型ハンドラー、比較的あまり使用されていません

テスト:

@Test
public void testResultMap() {
    SqlSession sqlSession = MybatisUtil.getSession();
    PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);

    List<Person> list = personMapper.select();
    for (Person person : list) {
        System.out.println(person);
    }
    sqlSession.close();
}

4.3 動的 SQL

4.3.1 動的 SQL とは

    Dynamic Sql とは、MyBatis コアによる Sql ステートメントの柔軟な操作、式による判断、および Sql の柔軟なスプライシングとアセンブリを指します。
    
    たとえば、
        名前に M が含まれていて 1000 より大きい従業員情報をクエリしたい場合、
        条件なしでクエリを実行する必要がある場合もあれば、
        ファジー クエリが必要な場合もあれば、
        複数の条件に基づいてクエリを実行する必要がある場合もあります。
        動的 SQL が役立ちます。これらの質問を解決します。

    SQL の動的スプライシングは、mybatis が提供するさまざまなラベル メソッドによって実現されます。

4.3.2 ifタグ

    判定ラベルは、パラメータが判定条件を満たした場合、SQL文をつなぎ合わせます。

エンティティ クラス:

package com.newcapec.entity;

import java.util.Date;

public class Emp {

    private Integer empno;
    private String ename;
    private String job;
    private Integer mgr;
    private Date hiredate;
    private Double sal;
    private Double comm;
    private Integer deptno;
    private String gender;

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public Integer getMgr() {
        return mgr;
    }

    public void setMgr(Integer mgr) {
        this.mgr = mgr;
    }

    public Date getHiredate() {
        return hiredate;
    }

    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    }

    public Double getSal() {
        return sal;
    }

    public void setSal(Double sal) {
        this.sal = sal;
    }

    public Double getComm() {
        return comm;
    }

    public void setComm(Double comm) {
        this.comm = comm;
    }

    public Integer getDeptno() {
        return deptno;
    }

    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "empno=" + empno +
                ", ename='" + ename + '\'' +
                ", job='" + job + '\'' +
                ", mgr=" + mgr +
                ", hiredate=" + hiredate +
                ", sal=" + sal +
                ", comm=" + comm +
                ", deptno=" + deptno +
                ", gender='" + gender + '\'' +
                '}';
    }
}

マッパー インターフェイス:

public interface EmpMapper {
    
    List<Emp> selectUseIf(Emp emp);
}

マッパーファイル:

<select id="selectUseIf" parameterType="com.newcapec.entity.Emp" resultType="com.newcapec.entity.Emp">
    select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
    where
    <!--
		注意:判断条件中使用的变量为实体类或输入参数的属性
			 空字符串的判断仅能使用在字符串类型的属性中
	-->
    <if test="ename != null and ename != ''">
        ename like concat('%',#{ename},'%')
    </if>
    <if test="sal != null">
        and sal=#{sal}
    </if>
    <if test="deptno != null">
        and deptno=#{deptno}
    </if>
</select>

テスト:

/*
 * 动态sql测试
 */
public class DynamicSqlTest {

    @Test
    public void testIf() {
        SqlSession sqlSession = MybatisUtil.getSession();
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);

        Emp emp = new Emp();
        emp.setEname("S");
        emp.setSal(1300.0);
        emp.setDeptno(20);

        List<Emp> list = empMapper.selectUseIf(emp);
        for (Emp e : list) {
            System.out.println(e);
        }
        sqlSession.close();
    }
}

4.3.3 where タグ

    where タグは where キーワードを置き換えます。
        1. where タグ内のすべての条件が満たされない場合、where キーワードは結合されません. 1 つの条件が真である限り、where キーワードは SQL ステートメントで結合されます.
        2. where タグは、条件ヘッドの and または or キーワードを自動的に削除します。

マッパー インターフェイス:

List<Emp> selectUseWhere(Emp emp);

マッパーファイル:

<select id="selectUseWhere" parameterType="com.newcapec.entity.Emp" resultType="com.newcapec.entity.Emp">
    select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
    <where>
        <if test="ename != null and ename != ''">
            ename like concat('%',#{ename},'%')
        </if>
        <if test="sal != null">
            and sal=#{sal}
        </if>
        <if test="deptno != null">
            and deptno=#{deptno}
        </if>
    </where>
</select>

テスト:

@Test
public void testWhere() {
    SqlSession sqlSession = MybatisUtil.getSession();
    EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);

    Emp emp = new Emp();
    emp.setEname("S");
    emp.setSal(1300.0);
    emp.setDeptno(20);

    List<Emp> list = empMapper.selectUseWhere(emp);
    for (Emp e : list) {
        System.out.println(e);
    }
    sqlSession.close();
}

4.3.4 ラベルの設定

    set キーワードの代わりに set タグを使用します。
        1. set タグ内のすべての条件が満たされない場合、set キーワードは結合されません. 1 つの条件が真である限り、set キーワードは SQL ステートメントで結合されます.
        2. 注: セットに含まれる内容が空の場合、SQL ステートメントでエラーが発生します。
        3. set タグは、条件の末尾にある無関係なカンマを自動的に削除します。

マッパー インターフェイス:

void updateUseSet(Emp emp);

マッパーファイル:

<update id="updateUseSet" parameterType="com.newcapec.entity.Emp">
    update emp
    <set>
        <if test="ename != null">
            ename=#{ename},
        </if>
        <if test="job != null">
            job=#{job},
        </if>
        <if test="mgr != null">
            mgr=#{mgr},
        </if>
        <if test="hiredate != null">
            hiredate=#{hiredate},
        </if>
        <if test="sal != null">
            sal=#{sal},
        </if>
        <if test="comm != null">
            comm=#{comm},
        </if>
        <if test="deptno != null">
            deptno=#{deptno},
        </if>
    </set>
    where empno=#{empno}
</update>

テスト:

@Test
public void testSet() {
    SqlSession sqlSession = MybatisUtil.getSession();
    EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);

    Emp emp = new Emp();
    emp.setEmpno(7938);
    emp.setEname("JACK");
    emp.setJob("MANAGER");
    emp.setMgr(7844);
    emp.setSal(5600.0);
    emp.setComm(1200.0);
    emp.setHiredate(new Date());
    emp.setDeptno(30);
    empMapper.updateUseSet(emp);
    sqlSession.commit();
    sqlSession.close();
}

4.3.5 トリムラベル

トリムタグ属性分析:

  • prefix: コンテンツの前にいくつかの文字を含むプレフィックス。

  • suffix: コンテンツの後のいくつかの文字を含むサフィックス。

  • prefixOverrides: 含まれるコンテンツの前にあるいくつかの文字を削除します。

  • suffixOverrides: 含まれるコンテンツの後のいくつかの文字を削除します。

マッパー インターフェイス:

void insertUseTrim(Emp emp);

マッパーファイル:

<insert id="insertUseTrim" parameterType="com.newcapec.entity.Emp">
    insert into emp
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="ename != null">
            ename,
        </if>
        <if test="job != null">
            job,
        </if>
        <if test="mgr != null">
            mgr,
        </if>
        <if test="hiredate != null">
            hiredate,
        </if>
        <if test="sal != null">
            sal,
        </if>
        <if test="comm != null">
            comm,
        </if>
        <if test="deptno != null">
            deptno,
        </if>
    </trim>
    <trim prefix=" values(" suffix=")" suffixOverrides=",">
        <if test="ename != null">
            #{ename},
        </if>
        <if test="job != null">
            #{job},
        </if>
        <if test="mgr != null">
            #{mgr},
        </if>
        <if test="hiredate != null">
            #{hiredate},
        </if>
        <if test="sal != null">
            #{sal},
        </if>
        <if test="comm != null">
            #{comm},
        </if>
        <if test="deptno != null">
            #{deptno},
        </if>
    </trim>
</insert>

テスト:

@Test
public void testTrim() {
    SqlSession sqlSession = MybatisUtil.getSession();
    EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);

    Emp emp = new Emp();
    emp.setEname("CHRIS");
    emp.setJob("CLERK");
    emp.setMgr(1);
    emp.setSal(3400.0);
    emp.setComm(800.0);
    emp.setHiredate(new Date());
    emp.setDeptno(10);

    empMapper.insertUseTrim(emp);
    sqlSession.commit();
    sqlSession.close();
}

where タグの代わりに:

<select id="selectUseTrim" parameterType="com.newcapec.entity.Emp" resultType="com.newcapec.entity.Emp">
    select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
    <trim prefix="where" prefixOverrides="and|or">
        <if test="ename != null and ename != ''">
            ename like concat('%',#{ename},'%')
        </if>
        <if test="sal != null">
            and sal=#{sal}
        </if>
        <if test="deptno != null">
            and deptno=#{deptno}
        </if>
    </trim>
</select>

タグを設定する代わりに:

<update id="updateUseTrim" parameterType="com.newcapec.entity.Emp">
    update emp
    <trim prefix="set" suffixOverrides=",">
        <if test="ename != null">
            ename=#{ename},
        </if>
        <if test="job != null">
            job=#{job},
        </if>
        <if test="mgr != null">
            mgr=#{mgr},
        </if>
        <if test="hiredate != null">
            hiredate=#{hiredate},
        </if>
        <if test="sal != null">
            sal=#{sal},
        </if>
        <if test="comm != null">
            comm=#{comm},
        </if>
        <if test="deptno != null">
            deptno=#{deptno},
        </if>
    </trim>
    where empno=#{empno}
</update>

4.3.6 foreach タグ

    配列またはリストを SQL に渡すと、MyBatis は foreach を使用して解析します。

属性の解決:

  • collection: トラバースする配列またはコレクション オブジェクトの名前。

    • SQLは配列パラメータしか受け付けませんが、このとき、SQL解析パラメータMyBatisの名前は配列固定です。

    • SQL は List パラメーターのみを受け入れます.このとき、SQL 解析パラメーター MyBatis の名前は list に固定されています。

    • エンティティ クラスまたはカスタム型の属性が SQL 配列または List コレクションに渡される場合、パラメーターの名前は、エンティティ クラスまたはカスタム型の属性の名前です。

  • index: 配列の添字。

  • item: 各トラバーサル生成オブジェクト内。

  • open: トラバーサルの開始時の連結文字列。

  • close: 走査の最後に連結された文字列。

  • セパレーター: トラバースされる 2 つのオブジェクトで連結する必要がある文字列。

マッパー インターフェイス:

void deleteUseForeach(Integer[] ids);

void insertUseForeach(List<Emp> empList);

マッパーファイル:

<delete id="deleteUseForeach" parameterType="java.lang.Integer">
    <!--delete from emp where empno in (1,2,3,4)-->
    delete from emp where empno in
    <foreach collection="array" open="(" close=")" separator="," item="id">
        #{id}
    </foreach>
</delete>

<insert id="insertUseForeach" parameterType="com.newcapec.entity.Emp">
    insert into emp(ename,job,mgr,hiredate,sal,comm,deptno) values
    <foreach collection="list" separator="," item="emp">
        (#{emp.ename},#{emp.job},#{emp.mgr},#{emp.hiredate},#{emp.sal},#{emp.comm},#{emp.deptno})
    </foreach>
</insert>

テスト:

@Test
public void testForeach() {
    SqlSession sqlSession = MybatisUtil.getSession();
    EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);

    empMapper.deleteUseForeach(new Integer[]{1, 2, 3, 4});
    sqlSession.commit();
    sqlSession.close();
}

@Test
public void testForeach2() {
    SqlSession sqlSession = MybatisUtil.getSession();
    EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);

    List<Emp> empList = new ArrayList<>();
    for (int i = 1; i <= 3; i++) {
        Emp emp = new Emp();
        emp.setEname("TOM" + i);
        emp.setJob("CLERK" + i);
        emp.setMgr(1);
        emp.setSal(4567.0);
        emp.setComm(123.0);
        emp.setHiredate(new Date());
        emp.setDeptno(10);
        empList.add(emp);
    }
    empMapper.insertUseForeach(empList);
    //sqlSession.commit();
    sqlSession.close();
}

4.3.7 ラベルの選択

    choose タグ、when タグ、otherwise タグの組み合わせは、if-else-if 判定に似ています。

<select id="">
    select...
    <choose>
        <when test="">

        </when>
        <when test="">

        </when>
        <otherwise>

        </otherwise>
    </choose>
</select>

4.3.8 SQLフラグメント

    実装された動的 SQL 判定コード ブロックを抽出して SQL フラグメントを形成します。これは、他のステートメントで参照でき、プログラマーが開発するのに便利です。

    注: SQL フラグメントに where タグを含めないでください。

<sql id="feildSql">
    empno,ename,job,mgr,hiredate,sal,comm,deptno
</sql>

<sql id="whereSql">
    <if test="ename != null and ename != ''">
        ename like concat('%',#{ename},'%')
    </if>
    <if test="sal != null">
        and sal=#{sal}
    </if>
    <if test="deptno != null">
        and deptno=#{deptno}
    </if>
</sql>

<select id="selectUseSql" parameterType="com.newcapec.entity.Emp" resultType="com.newcapec.entity.Emp">
    select
    <include refid="feildSql"></include>
    from emp
    <where>
        <include refid="whereSql"></include>
    </where>
</select>

おすすめ

転載: blog.csdn.net/ligonglanyuan/article/details/124319848