MyBatis 04 实战

增删改查实现

在实际使用中,MyBatis 的使用遵从一定的规范。

常用的增删改查的 MyBatis 实现如下:

Mapper.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 namespace="cn.sail.mapper.UserMapper">

    <resultMap id="resultMap" type="user">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="pwd" property="pwd"/>
    </resultMap>

    <sql id="selectAll">
        select id,
               name,
               pwd
          from user
    </sql>

    <select id="selectList" parameterType="user" resultMap="resultMap">
        <include refid="selectAll"/>
        <where>
            <if test="name != null and name != ''">
                and name like concat('%', #{name}, '%')
            </if>
            <if test="pwd != null and pwd != ''">
                and pwd like concat('%', #{pwd}, '%')
            </if>
        </where>
        limit #{startIndex}, #{pageSize}
    </select>

    <select id="pageByRowBounds" parameterType="user" resultMap="resultMap">
        <include refid="selectAll"/>
        <where>
            <if test="name != null and name != ''">
                and name like concat('%', #{name}, '%')
            </if>
            <if test="pwd != null and pwd != ''">
                and pwd like concat('%', #{pwd}, '%')
            </if>
        </where>
    </select>

    <select id="selectOne" parameterType="int" resultMap="resultMap">
        <include refid="selectAll"/>
         where id = #{id}
    </select>

    <insert id="insert" parameterType="user">
        insert into user
        <trim prefix="(" suffixOverrides="," suffix=")">
            <if test="name != null">name,</if>
            <if test="pwd != null">pwd,</if>
        </trim>
        <trim prefix="values (" suffixOverrides="," suffix=")">
            <if test="name != null">#{name},</if>
            <if test="pwd != null">#{pwd},</if>
        </trim>
    </insert>

    <insert id="insertBatch" parameterType="list">
        insert into user
            (name, pwd)
        values
        <foreach item="user" collection="list" separator=",">
            (#{user.name}, #{user.pwd})
        </foreach>
    </insert>

    <update id="update" parameterType="user">
        update user
        <trim prefix="set" suffixOverrides=",">
            <if test="name != null">name = #{name},</if>
            <if test="pwd != null">pwd = #{pwd},</if>
        </trim>
        where id = #{id}
    </update>

    <update id="updateBatch1" parameterType="list">
        insert into user
            (id, name, pwd)
        values
        <foreach item="user" collection="list" separator=",">
            (#{user.id}, #{user.name}, #{user.pwd})
        </foreach>
        on duplicate key update
        name = values(name), pwd = values(pwd)
    </update>

    <update id="updateBatch2" parameterType="list">
        replace into user
            (id, name, pwd)
        values
        <foreach item="user" collection="list" separator=",">
            (#{user.id}, #{user.name}, #{user.pwd})
        </foreach>
    </update>

    <delete id="delete" parameterType="int">
        delete from user
        where id = #{id}
    </delete>

    <delete id="deleteBatch" parameterType="string">
        delete from user
        where id in
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>

</mapper>

Mapper.java

public interface UserMapper {

    /**
     * 列表
     * @return 用户列表
     * @param user 用户
     */
    List<User> selectList(User user);

    /**
     * 通过RowBounds分页
     * @return 用户列表
     * @param user 用户
     */
    List<User> pageByRowBounds(User user);

    /**
     * 单项
     * @param id 主键
     * @return 用户
     */
    User selectOne(int id);

    /**
     * 插入
     * @param user 用户
     * @return 插入数量
     */
    int insert(User user);

    /**
     * 批量插入
     * @param userList 用户列表
     * @return 插入数量
     */
    int insertBatch(List<User> userList);

    /**
     * 更新
     * @param user 用户
     * @return 更新数量
     */
    int update(User user);

    /**
     * 批量更新1
     * @param userList 用户列表
     * @return 更新数量
     */
    int updateBatch1(List<User> userList);

    /**
     * 批量更新2
     * @param userList 用户列表
     * @return 更新数量
     */
    int updateBatch2(List<User> userList);

    /**
     * 删除
     * @param id 主键
     * @return 删除数量
     */
    int delete(int id);

    /**
     * 批量删除
     * @param ids 主键数组
     * @return 删除数量
     */
    int deleteBatch(int[] ids);

}

Test.java

public class MyBatis {

    /**
     * 查询列表
     */
    @Test
    public void selectList() {
        SqlSession sqlSession = MybatisUtils.getSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        int pageNum = 1;
        int pageSize = 2;
        user.setStartIndex((pageNum - 1) * pageSize);
        user.setPageSize(pageSize);
        List<User> userList = userMapper.selectList(user);
        System.out.println(userList);
        sqlSession.close();
    }

    /**
     * RowBounds分页
     */
    @Test
    public void pageByRowBounds() {
        SqlSession sqlSession = MybatisUtils.getSession();
        User user = new User();
        int pageNum = 1;
        int pageSize = 2;
        RowBounds rowBounds = new RowBounds((pageNum - 1) * pageSize, pageSize);
        List<User> userList = sqlSession.selectList("cn.sail.mapper.UserMapper.pageByRowBounds", null, rowBounds);
        System.out.println(userList);
        sqlSession.close();
    }

    /**
     * 查询单项
     */
    @Test
    public void selectOne() {
        SqlSession sqlSession = MybatisUtils.getSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.selectOne(1);
        System.out.println(user);
        sqlSession.close();
    }

    /**
     * 插入
     */
    @Test
    public void insert() {
        SqlSession sqlSession = MybatisUtils.getSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setName("sail");
        user.setPwd("123456");
        int insert = userMapper.insert(user);
        System.out.println(insert);
        sqlSession.commit();
        sqlSession.close();
    }

    /**
     * 批量插入
     */
    @Test
    public void insertBatch() {
        SqlSession sqlSession = MybatisUtils.getSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = new ArrayList<>();
        User user = new User();
        user.setName("sail1");
        user.setPwd("123456");
        userList.add(user);
        user = new User();
        user.setName("sail2");
        user.setPwd("123456");
        userList.add(user);
        int insertBatch = userMapper.insertBatch(userList);
        System.out.println(insertBatch);
        sqlSession.commit();
        sqlSession.close();
    }

    /**
     * 更新
     */
    @Test
    public void update() {
        SqlSession sqlSession = MybatisUtils.getSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setId(6);
        user.setName("sail");
        user.setPwd("12345678");
        int update = userMapper.update(user);
        System.out.println(update);
        sqlSession.commit();
        sqlSession.close();
    }

    /**
     * 批量更新1
     */
    @Test
    public void updateBatch1() {
        SqlSession sqlSession = MybatisUtils.getSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = new ArrayList<>();
        User user = new User();
        user.setId(11);
        user.setName("sail1");
        user.setPwd("1234567");
        userList.add(user);
        user = new User();
        user.setId(12);
        user.setName("sail2");
        user.setPwd("1234567");
        userList.add(user);
        int updateBatch1 = userMapper.updateBatch1(userList);
        System.out.println(updateBatch1);
        sqlSession.commit();
        sqlSession.close();
    }

    /**
     * 批量更新2
     */
    @Test
    public void updateBatch2() {
        SqlSession sqlSession = MybatisUtils.getSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = new ArrayList<>();
        User user = new User();
        user.setId(11);
        user.setName("sail1");
        user.setPwd("12345678");
        userList.add(user);
        user = new User();
        user.setId(12);
        user.setName("sail2");
        user.setPwd("12345678");
        userList.add(user);
        int updateBatch2 = userMapper.updateBatch2(userList);
        System.out.println(updateBatch2);
        sqlSession.commit();
        sqlSession.close();
    }

    /**
     * 删除
     */
    @Test
    public void delete() {
        SqlSession sqlSession = MybatisUtils.getSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        int delete = userMapper.delete(6);
        System.out.println(delete);
        sqlSession.commit();
        sqlSession.close();
    }

    /**
     * 批量删除
     */
    @Test
    public void deleteBatch() {
        SqlSession sqlSession = MybatisUtils.getSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        int[] ids = {9, 10};
        int deleteBatch = userMapper.deleteBatch(ids);
        System.out.println(deleteBatch);
        sqlSession.commit();
        sqlSession.close();
    }

}

resultMap标签

<resultMap id="resultMap" type="user">
    <result column="id" property="id"/>
    <result column="name" property="name"/>
    <result column="pwd" property="pwd"/>
</resultMap>

resultMap 中,column 是数据库表的列名 , property 是对应实体类的属性名。

resultMap 元素是 MyBatis 中最重要最强大的元素。它可以省略大量的赋值代码,并可以灵活的给字段取别名,且可以复用。

resultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。

sql片段

<sql id="selectAll">
    select id,
    name,
    pwd
    from user
</sql>

sql 片段一般编写通用性的 SQL 语句,比如全字段查询,过滤条件封装等。

最好基于单表来定义 sql 片段,提高片段的可重用性。

在 sql 片段中不要包括 where。

sql 片段是需要用 include 标签引用的,如以上的 sql 片段可以用如下的 include 标签引用:

<include refid="selectAll"/>

引用 sql 片段时,如果 refid 指定的不在本文件中,那么需要在前面加上 namespace。

列表分页查询

<select id="selectList" parameterType="user" resultMap="resultMap">
    <include refid="selectAll"/>
    <where>
        <if test="name != null and name != ''">
            and name like concat('%', #{name}, '%')
        </if>
        <if test="pwd != null and pwd != ''">
            and pwd like concat('%', #{pwd}, '%')
        </if>
    </where>
    limit #{startIndex}, #{pageSize}
</select>
/**
 * 列表
 * @return 用户列表
 * @param user 用户
 */
List<User> selectList(User user);
/**
 * 查询列表
 */
@Test
public void selectList() {
    SqlSession sqlSession = MybatisUtils.getSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User user = new User();
    int pageNum = 1;
    int pageSize = 2;
    user.setStartIndex((pageNum - 1) * pageSize);
    user.setPageSize(pageSize);
    List<User> userList = userMapper.selectList(user);
    System.out.println(userList);
    sqlSession.close();
}

列表查询往往是一个页面需要编写的第一个 SQL,也往往是数据量最大、语句最复杂的 SQL。

parameterType 这里使用的是配置文件中取的别名,对应实体类。

resultMap 这里使用的是前面定义的 resultMap。

如果用 resultType ,则需要指定具体的类或者 MyBatis 默认的基本数据类型。

MyBatis 默认的基本数据类型有:int、string、long、map。

where 标签会知道如果它包含的标签中有返回值的话,它就插入一个 where 。此外,如果标签返回的内容是以 and 或 or 开头的,则它会剔除掉。

if 标签用于判断参数是否有值,有值则拼接标签中的 SQL 语句,没有值则不拼接,可以提高 SQL 查询效率和避免传值为 null 的语法错误。

#{} 用于传递参数,会默认在首尾拼接 ‘ 。

${} 用于传递直接量,即不会在首尾拼接 ’ ,常用于拼接 SQL 语句。

limit 处没有进行参数有值判断,所以 startIndex 和 pageSize 必须有值,不然语句会报错。

以上是常用的分页查询处理方式,也可以用 Java 代码实现分页,如RowBounds分页:

<select id="pageByRowBounds" parameterType="user" resultMap="resultMap">
    <include refid="selectAll"/>
    <where>
        <if test="name != null and name != ''">
            and name like concat('%', #{name}, '%')
        </if>
        <if test="pwd != null and pwd != ''">
            and pwd like concat('%', #{pwd}, '%')
        </if>
    </where>
</select>
/**
 * 通过RowBounds分页
 * @return 用户列表
 * @param user 用户
 */
List<User> pageByRowBounds(User user);
@Test
public void pageByRowBounds() {
    SqlSession sqlSession = MybatisUtils.getSession();
    User user = new User();
    int pageNum = 1;
    int pageSize = 2;
    RowBounds rowBounds = new RowBounds((pageNum - 1) * pageSize, pageSize);
    List<User> userList = sqlSession.selectList("cn.sail.mapper.UserMapper.pageByRowBounds", null, rowBounds);
    System.out.println(userList);
    sqlSession.close();
}

此种分页方式的代码较为繁琐,且由于进行了封装,效率也不如上面的方式,不推荐使用。

查询单项

<select id="selectOne" parameterType="int" resultMap="resultMap">
    <include refid="selectAll"/>
    where id = #{id}
</select>
/**
 * 单项
 * @param id 主键
 * @return 用户
 */
User selectOne(int id);
/**
 * 查询单项
 */
@Test
public void selectOne() {
    SqlSession sqlSession = MybatisUtils.getSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User user = userMapper.selectOne(1);
    System.out.println(user);
    sqlSession.close();
}

查询单项常用于详情查看和修改时赋值。

由于主键项是没有做是否有值判断的,因此必须有值,是否会造成语法错误。

由于单项查询的返回值往往是一个类,因此要注意非空判断,避免空指针异常。

插入

<insert id="insert" parameterType="user">
    insert into user
    <trim prefix="(" suffixOverrides="," suffix=")">
        <if test="name != null">name,</if>
        <if test="pwd != null">pwd,</if>
    </trim>
    <trim prefix="values (" suffixOverrides="," suffix=")">
        <if test="name != null">#{name},</if>
        <if test="pwd != null">#{pwd},</if>
    </trim>
</insert>
/**
 * 插入
 * @param user 用户
 * @return 插入数量
 */
int insert(User user);
@Test
public void insert() {
    SqlSession sqlSession = MybatisUtils.getSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User user = new User();
    user.setName("sail");
    user.setPwd("123456");
    int insert = userMapper.insert(user);
    System.out.println(insert);
    sqlSession.commit();
    sqlSession.close();
}

插入涉及到数据变更,在实际使用中建议加上 @Transactional(rollbackFor = Exception.class)注解,在出错时会进行回滚,避免造成数据错误。

主键值往往是自增的,插入时一般不需要设置主键值。

trim 标签可以用 suffixOverrides 属性过滤掉 SQL 语句尾部多余的符号,也可以用 prefix 拼接标签中开头的语句,用 suffix 标签拼接标签中结尾的语句。

批量插入

<insert id="insertBatch" parameterType="list">
    insert into user
        (name, pwd)
    values
    <foreach item="user" collection="list" separator=",">
        (#{user.name}, #{user.pwd})
    </foreach>
</insert>
/**
 * 批量插入
 * @param userList 用户列表
 * @return 插入数量
 */
int insertBatch(List<User> userList);
@Test
public void insertBatch() {
    SqlSession sqlSession = MybatisUtils.getSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    List<User> userList = new ArrayList<>();
    User user = new User();
    user.setName("sail1");
    user.setPwd("123456");
    userList.add(user);
    user = new User();
    user.setName("sail2");
    user.setPwd("123456");
    userList.add(user);
    int insertBatch = userMapper.insertBatch(userList);
    System.out.println(insertBatch);
    sqlSession.commit();
    sqlSession.close();
}

foreach标签

  • collection:指定输入对象中的集合属性。
  • item:每次遍历生成的对象。
  • open:开始遍历时的拼接字符串。
  • close:结束时拼接的字符串。
  • separator:遍历对象之间需要拼接的字符串。

修改

<update id="update" parameterType="user">
    update user
    <trim prefix="set" suffixOverrides=",">
        <if test="name != null">name = #{name},</if>
        <if test="pwd != null">pwd = #{pwd},</if>
    </trim>
    where id = #{id}
</update>
/**
 * 更新
 * @param user 用户
 * @return 更新数量
 */
int update(User user);
@Test
public void update() {
    SqlSession sqlSession = MybatisUtils.getSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User user = new User();
    user.setId(6);
    user.setName("sail");
    user.setPwd("12345678");
    int update = userMapper.update(user);
    System.out.println(update);
    sqlSession.commit();
    sqlSession.close();
}

参数中主键的值是必须的。

更新涉及到数据变更,在实际使用中建议加上 @Transactional(rollbackFor = Exception.class)注解,在出错时会进行回滚,避免造成数据错误。

由于一般会进行修改字段的非空判断,所以当一个字段有值改为无值时,由于无值的参数被非空判断拦截,是修改不成功的,如果有此需求则需要单独定义没有字段非空判断的 SQL 语句。

批量更新1

<update id="updateBatch1" parameterType="list">
    insert into user
        (id, name, pwd)
    values
    <foreach item="user" collection="list" separator=",">
        (#{user.id}, #{user.name}, #{user.pwd})
    </foreach>
    on duplicate key update
    name = values(name), pwd = values(pwd)
</update>
/**
 * 批量更新1
 * @param userList 用户列表
 * @return 更新数量
 */
int updateBatch1(List<User> userList);
@Test
public void updateBatch1() {
    SqlSession sqlSession = MybatisUtils.getSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    List<User> userList = new ArrayList<>();
    User user = new User();
    user.setId(11);
    user.setName("sail1");
    user.setPwd("1234567");
    userList.add(user);
    user = new User();
    user.setId(12);
    user.setName("sail2");
    user.setPwd("1234567");
    userList.add(user);
    int updateBatch1 = userMapper.updateBatch1(userList);
    System.out.println(updateBatch1);
    sqlSession.commit();
    sqlSession.close();
}

on duplicate key update,是基于主键(PRIMARY KEY)或唯一索引(UNIQUE INDEX)使用的。

如果已存在该唯一标示或主键就更新,如果不存在该唯一标示或主键则作为新行插入。

批量更新2

<update id="updateBatch2" parameterType="list">
    replace into user
        (id, name, pwd)
    values
    <foreach item="user" collection="list" separator=",">
        (#{user.id}, #{user.name}, #{user.pwd})
    </foreach>
</update>
/**
 * 批量更新2
 * @param userList 用户列表
 * @return 更新数量
 */
int updateBatch2(List<User> userList);
@Test
public void updateBatch2() {
    SqlSession sqlSession = MybatisUtils.getSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    List<User> userList = new ArrayList<>();
    User user = new User();
    user.setId(11);
    user.setName("sail1");
    user.setPwd("12345678");
    userList.add(user);
    user = new User();
    user.setId(12);
    user.setName("sail2");
    user.setPwd("12345678");
    userList.add(user);
    int updateBatch2 = userMapper.updateBatch2(userList);
    System.out.println(updateBatch2);
    sqlSession.commit();
    sqlSession.close();
}

replace into 跟 insert into 的用法完全一样,但是它带有更新功能。

如果发现表中已经有此行数据(根据主键或者唯一索引判断)则先删除此行数据,然后插入新的数据。否则,直接插入新数据。

它是先删除数据,然后再插入,如果当前的数据库用户没有删除权限,是不能使用replace into的。

删除

<delete id="delete" parameterType="int">
    delete from user
    where id = #{id}
</delete>
/**
 * 删除
 * @param id 主键
 * @return 删除数量
 */
int delete(int id);
@Test
public void delete() {
    SqlSession sqlSession = MybatisUtils.getSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    int delete = userMapper.delete(6);
    System.out.println(delete);
    sqlSession.commit();
    sqlSession.close();
}

参数中主键是必须的。

删除涉及到数据变更,在实际使用中建议加上 @Transactional(rollbackFor = Exception.class)注解,在出错时会进行回滚,避免造成数据错误。

批量删除

<delete id="deleteBatch" parameterType="string">
    delete from user
    where id in
    <foreach item="id" collection="array" open="(" separator="," close=")">
        #{id}
    </foreach>
</delete>
/**
 * 批量删除
 * @param ids 主键数组
 * @return 删除数量
 */
int deleteBatch(int[] ids);
@Test
public void deleteBatch() {
    SqlSession sqlSession = MybatisUtils.getSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    int[] ids = {9, 10};
    int deleteBatch = userMapper.deleteBatch(ids);
    System.out.println(deleteBatch);
    sqlSession.commit();
    sqlSession.close();
}

以上就是常用的增删改查语句,在实际使用中,为效率考虑,建议尽量使用单表进行增删改查,那些复杂的关联在代码中处理。

补充

@Param

@Param 注解用于给方法参数起一个名字。以下是总结的使用原则:

  • 在方法只接受一个参数的情况下,可以不使用 @Param。
  • 在方法接受多个参数的情况下,建议一定要使用 @Param 注解给参数命名。
  • 如果参数是 JavaBean, 则不能使用 @Param。
  • 不使用 @Param 注解时,参数只能有一个,并且是 Javabean。

注解写SQL

mybatis 最初配置信息是基于 XML,映射语句(SQL)也是定义在 XML 中的。而到 MyBatis 3 提供了新的基于注解的配置。

注解主要分成 :

  • @select ()
  • @update ()
  • @Insert ()
  • @delete ()

可以在注解中编写 SQL 语句实现与 XML 同样的效果。

利用注解开发就不需要mapper.xml映射文件了。

Java 注解的的表达力和灵活性十分有限,稍微复杂一点的 SQL 语句用注解进行编写会非常困难,因此不建议使用。

多对一和一对多处理

多对一

多对一的理解:

  • 多个学生对应一个老师。
  • 如果对于学生这边,就是一个多对一的现象,即从学生这边关联一个老师。

按查询嵌套处理

<select id="getStudents" resultMap="StudentTeacher">
    select * 
      from student
</select>

<resultMap id="StudentTeacher" type="Student">
    <!-- association关联属性: 
			property属性名 
			column在多的一方的表中的列名
				column="{key=value,key=value}"
				其实就是键值对的形式,key是传给下个sql的取值名称,value是上个sql查询的字段名。
			javaType属性类型 
			select引用查询结果 -->
    <association property="teacher"  column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>

<select id="getTeacher" resultType="teacher">
    select * 
      from teacher 
     where id = #{id}
</select>

按结果嵌套处理

<select id="getStudents2" resultMap="StudentTeacher2" >
  select s.id sid, 
    	 s.name sname, 
    	 t.name tname
    from student s, teacher t
   where s.tid = t.id
</select>

<resultMap id="StudentTeacher2" type="Student">
   <id property="id" column="sid"/>
   <result property="name" column="sname"/>
   <!--关联对象property 关联对象在Student实体类中的属性-->
   <association property="teacher" javaType="Teacher">
       <result property="name" column="tname"/>
   </association>
</resultMap>

按照查询进行嵌套处理就像SQL中的子查询

按照结果进行嵌套处理就像SQL中的联表查询

多对一的情况用 XML 处理较为复杂,建议在代码中进行处理,逻辑会清晰很多,由于不会关联表,查询效率也会大大提高。

一对多

一对多的理解:

  • 一个老师拥有多个学生。
  • 如果对于老师这边,就是一个一对多的现象,即从一个老师下面拥有一群学生(集合)。

按查询嵌套处理

<select id="getTeacher2" resultMap="TeacherStudent2">
	select * 
      from teacher 
     where id = #{id}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
   <!--column是一对多的外键 , 写的是一的主键的列名-->
   <collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStudentByTeacherId"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
    select * 
      from student 
     where tid = #{id}
</select>

按结果嵌套处理

<select id="getTeacher" resultMap="TeacherStudent">
    select s.id sid, 
    	   s.name sname, 
    	   t.name tname, 
    	   t.id tid
      from student s,teacher t
     where s.tid = t.id 
       and t.id = #{id}
</select>

<resultMap id="TeacherStudent" type="Teacher">
    <result property="name" column="tname"/>
    <collection property="students" ofType="Student">
        <result property="id" column="sid" />
        <result property="name" column="sname" />
        <result property="tid" column="tid" />
    </collection>
</resultMap>

总结

association:关联

collection:集合

association 是用于一对一和多对一,而collection是用于一对多的关系

JavaType和ofType都是用来指定对象类型的

JavaType 是用来指定pojo中属性的类型

ofType 指定的是映射到list集合属性中pojo的类型。

choose语句

有时候,我们不想用到所有的查询条件,只想选择其中的一个,查询条件有一个满足即可,使用 choose 标签可以解决此类问题,它类似于 if-else 语句。

<select id="queryBlogChoose" parameterType="map" resultType="blog">
  select * 
    from blog
   <where>
       <choose>
           <when test="title != null">
                title = #{title}
           </when>
           <when test="author != null">
              and author = #{author}
           </when>
           <otherwise>
              and views = #{views}
           </otherwise>
       </choose>
   </where>
</select>
posted @ 2021-09-30 11:41  天航星  阅读(53)  评论(0编辑  收藏  举报