Mybatis 映射文件标签详解

来源:互联网 发布:百度网盘mac版怎么安装 编辑:程序博客网 时间:2024/05/29 14:03

1.1     Mybatis映射文件(核心

1.1.1 输入映射

1.1.1.1  ParameterType

指定输入参数的java类型,可以使用别名或者类的全限定名。它可以接收简单类型、POJOHashMap

1.1.1.1.1      传递简单类型

参考需求:根据用户ID查询用户信息。


1.1.1.1.2      传递POJO对象
1.1.1.1.2.1     需求

根据用户性别和用户名称来查询用户信息

1.1.1.1.2.2     编写mapper接口

    //根据用户性别和用户名称来查询用户信息

    public List<User> findUserByUser(User user);

1.1.1.1.2.3     编写mapper映射文件

 

<!-- 传递POJO对象作为入参来查询用户信息-->

<select id="findUserByUser"parameterType="user" resultType="user">

    SELECT * FROM USER WHERE sex=#{sex} AND username LIKE '%${username}%'

</select>

Mybatis获取入参的值是通过OGNL表达式从对象中获取的。

该案例中,sexusername都是user对象的属性,而且必须完全一致。而且在使用${}时传入的不是value,而是具体的属性名称

1.1.1.1.2.4     编写测试代码

 

@Test

publicvoid findUserByUserTest(){

    // 创建SqlSession

    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 通过SqlSession,获取mapper接口的动态代理对象

    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

 

    // 构造User对象

    User user = new User();

    user.setSex("1");

    user.setUsername("小明");

 

    // 调用mapper对象的方法

    List<User> list = userMapper.findUserByUser(user);

 

    System.out.println(list);

    // 关闭SqlSession

    sqlSession.close();

}

 

1.1.1.1.3      传递POJO包装对象
1.1.1.1.3.1     需求

完成用户信息的综合查询,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息)。

 

1.1.1.1.3.2     创建包装对象

 

针对需求,建议使用自定义的包装类型pojo。在包装类中将复杂的查询字段包装进去。

 

 

先定义下用户扩展类UserExt.java一般User.java类要和数据表表字段一致,最好不要在这里面添加其他字段


定义复杂查询的POJO包装类:


 

1.1.1.1.3.3     编写Mapper接口

//通过包装类来进行复杂的用户信息综合查询

public List<UserExt> findUserList(UserQueryVOuserQueryVO);

1.1.1.1.3.4     编写mapper映射文件

 

<!-- 通过包装类来进行复杂的用户信息综合查询 -->

<select id="findUserList"parameterType="userQueryVO" resultType="userExt">

       SELECT * FROM USER WHERE sex=#{userExt.sex} AND usernameLIKE '%${userExt.username}%'

</select>

 

注意:入参的类型变为UserQueryVO、出参的类型变为UserExt#{}里面的参数变为UserQueryVO对象中的userExt属性的sexusername子属性。

 

1.1.1.1.3.5     编写测试代码

 

@Test

publicvoid findUserListTest() {

    // 创建SqlSession

    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 通过SqlSession,获取mapper接口的动态代理对象

    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

 

    //构造userQueryVO对象

    UserQueryVO userQueryVO = new UserQueryVO();

      

    // 构造UserExt对象

    UserExt userExtnew UserExt();

    userExt.setSex("1");

    userExt.setUsername("小明");

      

    userQueryVO.setUserExt(userExt);

 

    // 调用mapper对象的方法

    List<UserExt> list = userMapper.findUserList(userQueryVO);

 

    System.out.println(list);

    // 关闭SqlSession

    sqlSession.close();

}

 

1.1.1.1.4      传递HashMap

同传递POJO对象一样,只是mapkey要和#{}里面的参数名称一致。

1.1.2 输出映射

1.1.2.1  resultType

1.1.2.1.1      要求

使用resultType进行结果映射时,查询的列名和映射的pojo属性名完全一致,该列才能映射成功。

如果查询的列名和映射的pojo属性名全部不一致,则不会创建pojo对象;

如果查询的列名和映射的pojo属性名有一个一致,就会创建pojo对象。

 

1.1.2.1.2      输出简单类型

当输出结果只有一列时,可以使用简单类型作为输出结果类型。

 

1.1.2.1.2.1     Mapper映射文件

<!-- 学习:resultType输出简单类型 -->

<select id="findIdFromUser"resultType="int">

    SELECT id FROM USER

</select>

1.1.2.1.2.2     Mapper接口

//学习:resultType输出简单类型

public List<Integer> findIdFromUser();

1.1.2.1.2.3     测试代码

@Test

publicvoid findIdFromUserTest() {

    // 创建SqlSession

    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 通过SqlSession,获取mapper接口的动态代理对象

    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

 

    // 调用mapper对象的方法

    List<Integer> list = userMapper.findIdFromUser();

 

    System.out.println(list);

    // 关闭SqlSession

    sqlSession.close();

}

 

 

1.1.2.1.3      输出POJO单个对象和列表

注意:输出单个pojo对象和pojo列表(盛放pojo对象)时,mapper映射文件中的resultType的类型是一样的,mapper接口的方法返回值不同。

 

1.1.2.1.3.1     Mapper映射文件

Mapper映射文件是同一个。

<select id="findUsersByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">

       SELECT * FROM USER WHERE username LIKE '%${value}%'

</select>

1.1.2.1.3.2     Mapper接口

下面看下mapper接口的不同之处

1、  输出单个pojo对象

//根据用户名称来模糊查询用户信息

public UserfindUsersByName(String username);

2、  输出pojo列表

 

//根据用户名称来模糊查询用户信息列表

    public List<User> findUsersByName(String username);

 

总结:同样的mapper映射文件,返回单个对象和对象列表时,mapper接口在生成动态代理的时候,会根据返回值的类型,决定调用selectOne方法还是selectList方法。

 

1.1.2.2  resultMap

resultMap可以进行高级结果映射(一对一、一对多映射,第二天讲解)。

 

1.1.2.2.1      要求

使用resultMap进行输出映射时,查询的列名和对应的pojo属性不需要一致,只需要在mapper映射文件中定义一个resultMap,把列名和属性名做一个映射关系即可,但是这列名和属性名都要是正确的

 

1.1.2.2.2      Mapper映射文件

注意:使用resultMap的时候,mapper映射文件中要编辑两块内容:定义resultMap和定义statement

 

定义statement

<!-- 根据ID查询用户信息(学习resultMap -->

<select id="findUserByIdResultMap"parameterType="int" resultMap="userResultMap">

SELECT id id_,usernameusername_,sex sex_ FROM USER WHERE id = #{id}

</select>

 

定义resultMap

<!-- 定义resultMap -->

<!--

    [id]:定义resultMap的唯一标识

    [type]:定义该resultMap最终映射的pojo对象

    [id标签]:映射结果集的唯一标识列,如果是多个字段联合唯一,则定义多个id标签

    [result标签]:映射结果集的普通列

    [column]SQL查询的列名,如果列有别名,则该处填写别名

    [property]pojo对象的属性名

-->

<resultMap type="user"id="userResultMap">

    <id column="id_" property="id"/>

    <result column="username_" property="username"/>

    <result column="sex_" property="sex"/>

</resultMap>

 

1.1.2.2.3      Mapper接口定义

    //根据ID查询用户信息(学习resultMap

    public User findUserByIdResultMap(int id);

 

定义Statement使用resultMap映射结果集时,Mapper接口定义方法的返回值类型为mapper映射文件中resultMaptype类型。

1.1.2.2.4      测试代码

@Test

publicvoid findUserByIdResultMapTest() {

    // 创建SqlSession

    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 通过SqlSession,获取mapper接口的动态代理对象

    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

 

    // 调用mapper对象的方法

    User user = userMapper.findUserByIdResultMap(1);

 

    System.out.println(user);

    // 关闭SqlSession

    sqlSession.close();

}

1.1.3 SQL片段

Mybatis提供了SQL片段的功能,可以提高SQL的可重用性。

1.1.3.1  定义SQL片段

使用sql标签来定义一个SQL片段:

<!-- 定义SQL片段 -->

<!--

    [sql标签]:定义一个SQL片段

    [id]SQL片段的唯一标识

    建议:

       1SQL片段中的内容最好是以单表来定义

       2、如果是查询字段,则不要写上SELECT

       3、如果是条件语句,则不要写上WHERE

 -->

<sql id="selectUserSql">

    id,username,sex,birthday,address

</sql>

 

1.1.3.2  引用SQL片段

使用<include refid=’’ /> 来引用SQL片段:

<!-- 根据用户id来查询用户信息(使用SQL片段) -->

<!--

    [include标签]:引用已经定义好的SQL片段

    [refid]:引用的SQL片段id

-->

<select id="findUserByIdSql"parameterType="int" resultType="user">

    SELECT <include refid="selectUserSql"/> FROM USER WHEREid=#{id}

</select>

 

1.1.4 动态SQL(重点)

通过Mybatis提供的各种标签方法实现动态拼接sql,使得mapper映射文件在编写SQL时更加灵活,方便。动态标签有:ifwhereforeachset

 

1.1.4.1  需求

根据性别或者再加上用户名称来查询用户信息。

1.1.4.2  If

If标签作为判断入参来使用的,如果符合条件,则把if标签体内的SQL拼接上。

注意:用if进行判断是否为空时,不仅要判断null,也要判断空字符串‘’;

1.1.4.2.1      映射文件

<!-- 根据性别或者再加上用户名称来查询用户信息(学习动态SQLIF标签) -->

<!--

    [if标签]:进行动态判断,如果成功则把if标签内的内容拼接到原有SQL

    [test]:填写判断表达式

-->

<select id="findUser4If"parameterType="user" resultType="user">

    SELECT * FROM USER WHERE sex=#{sex}

    <if test="username != null and username != ''">

       AND username LIKE '%${username}%'

    </if>

</select>

1.1.4.2.2      Mapper接口

//根据性别或者再加上用户名称来查询用户信息(学习动态SQLIF标签)

public List<User> findUser4If(User user);

1.1.4.2.3      测试代码
  • 不传用户名:


 

输出的SQL如下(也不包含用户名):


 

  • 传用户名:


 

输出SQL如下(查询条件包含用户名):


 

通过测试可以得知,打印出的SQL语句确实会随着条件的满足情况而不一样。

1.1.4.3  Where

Where标签可以自动处理它后面的第一个and

1.1.4.3.1      需求

根据查询条件来查询用户信息,查询条件可能会有性别或者用户名称,有可能什么没有。

 

1.1.4.3.2      映射文件

根据需求,我们为了保证SQL的正确性,可以在where后面使用无意义的1=1

<!-- 根据查询条件来查询用户信息,查询条件可能会有性别或者用户名称,有可能什么没有。(学习where标签) -->

<!--

    通过动态SQL可以看出,为了保证SQL语句的正确性,需要在where 后面添加没有任何意义的1=1

 -->

<select id="findUser4If"parameterType="user" resultType="user">

    SELECT * FROM USER WHERE 1=1

    <if test="sex != null and sex != ''">

        AND sex=#{sex}

    </if>

    <if test="username != null and username != ''">

       AND username LIKE '%${username}%'

    </if>

</select>

 

如果不加1=1,则where后面的条件是错误的。当然还有一种更好的方式来处理这种问题,那就是where标签,修改如下:

 

<!-- 根据查询条件来查询用户信息,查询条件可能会有性别或者用户名称,有可能什么没有。(学习where标签) -->

<!--

    通过动态SQL可以看出,为了保证SQL语句的正确性,需要在where 后面添加没有任何意义的1=1

    [where标签]:使用它可以去掉它后面的第一个and,这样就可以保证SQL的正确性了

-->

<select id="findUser4Where"parameterType="user" resultType="user">

    SELECT * FROM USER

    <where>

       <if test="sex != nulland sex != ''">

            AND sex=#{sex}

       </if>

       <if test="username !=null and username != ''">

           AND username LIKE '%${username}%'

       </if>

    </where>     

</select>

 

1.1.4.4  Foreach

sql传递数组或List时,mybatis使用foreach解析数组里的参数并拼接到SQL中。

 

1.1.4.4.1      需求

根据用户id的集合查询用户列表。

1.1.4.4.2      直接传递List集合
1.1.4.4.2.1     映射文件

 

<!-- 根据用户ID的集合查询用户列表(学习foreach标签之直接传ID集合) -->

<!--

    [foreach标签]:表示一个foreach循环

    [collection]:集合参数的名称,如果是直接传入集合参数,则该处只能填写[list]

    [item]:定义遍历集合之后的参数名称

    [open]:开始遍历之前需要拼接的SQL

    [close]:结束遍历之后需要拼接的SQL

    [separator]:遍历出的每个对象之间需要拼接的字符

 -->

<select id="findUsersByIdListForEach"parameterType="list" resultType="user">

    SELECT * FROM USER

    <where>

       <if test="list != nulland list.size > 0">

           <foreach collection="list"item="id" open="AND id IN(" close=")"separator=",">

              #{id}

           </foreach>

       </if>

    </where>

</select>

 

1.1.4.4.2.2     Mapper接口

//根据用户ID的集合查询用户列表(学习foreach标签之直接传ID集合)

public List<User>findUsersByIdListForEach(List<Integer> idList);

1.1.4.4.2.3     测试代码

@Test

publicvoid findUsersByIdListForEachTest(){

    // 创建SqlSession

    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 通过SqlSession,获取mapper接口的动态代理对象

    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

 

    // 构造List<Integer>集合

    List<Integer> idList = new ArrayList<Integer>();

    idList.add(1);

    idList.add(10);

 

    // 调用mapper对象的方法

    List<User> list =userMapper.findUsersByIdListForEach(idList);

 

    System.out.println(list);

    // 关闭SqlSession

    sqlSession.close();

}

 

1.1.4.4.3      传递pojo对象中的List集合
1.1.4.4.3.1     定义pojo中的List属性


1.1.4.4.3.2     映射文件

<!-- 根据用户ID的集合查询用户列表(学习foreach标签之通过POJO对象传ID集合) -->

<!--

    通过POJO对象传集合,collection中的值为POJO对象中集合属性的属性名

    parameterType的值为POJO对象的类型

-->

<select id="findUsersByIdListForEach"parameterType="UserQueryVO" resultType="user">

    SELECT * FROM USER

    <where>

       <if test="idList != nulland idList.size > 0">

           <foreach collection="idList"item="id" open="AND id IN(" close=")"separator=",">

              #{id}

           </foreach>

       </if>

    </where>

</select>

1.1.4.4.3.3     Mapper接口

//根据用户ID的集合查询用户列表(学习foreach标签之通过POJO对象传ID集合)

public List<User>findUsersByIdListForEachPojo(UserQueryVO userQueryVO);

1.1.4.4.3.4     测试代码

@Test

publicvoid findUsersByIdListForEachPojoTest(){

    // 创建SqlSession

    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 通过SqlSession,获取mapper接口的动态代理对象

    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

 

    // 构造UserQueryVO对象

    UserQueryVO userQueryVO = new UserQueryVO();

      

    // 构造List<Integer>集合

    List<Integer> idList = new ArrayList<Integer>();

    idList.add(1);

    idList.add(10);

      

    userQueryVO.setIdList(idList);

 

    // 调用mapper对象的方法

    List<User> list =userMapper.findUsersByIdListForEachPojo(userQueryVO);

 

    System.out.println(list);

    // 关闭SqlSession

    sqlSession.close();

}

1.1.4.5  Set

where标签用法类似,set标签会去掉它后面第一个半角逗号,


原创粉丝点击