zoukankan      html  css  js  c++  java
  • Mybatis中输入输出映射和动态Sql

    一、输入映射

      我们通过配置parameterType的值来指定输入参数的类型,这些类型可以是简单数据类型、POJO、HashMap等数据类型

      1、简单类型

      2、POJO包装类型

      ①这是单表查询的时候传入的POJO包装类型,即可以直接传入实体类,但是当多表查询的时候,就需要自定义POJO类型

      ②我们使用自定义POJO类型来具体的了解一下

      先设计 包装类型如下,其中UserPOJO是除了User本身之外的添加的其他跟User相关的属性的包装类,UserVo是用于视图层面的包装类型,同样也是作为Mapper配置文件的输入类型

      其中User文件同上一篇Mybatis简单入门中的User,包括数据表部分也一样。这里给出UserPoJO和UserVo文件

     1 package cn.mybatis.po;
     2 
     3 public class UserPoJo extends User{
     4     private User user;
     5 
     6     public void setUser(User user) {
     7         this.user = user;
     8     }
     9 
    10     public User getUser() {
    11         return user;
    12     }
    13 }
    UserPOJO
     1 package cn.mybatis.po;
     2 
     3 public class UserVo {
     4     private UserPoJo userPoJo;
     5 
     6     public UserPoJo getUserPoJo() {
     7         return userPoJo;
     8     }
     9 
    10     public void setUserPoJo(UserPoJo userPoJo) {
    11         this.userPoJo = userPoJo;
    12     }
    13 }
    UserVo

      然后我们配置UserMapper.xml文件

      然后在UserMapper接口文件中添加

        //测试包装类型的查询
        public List<UserPoJo> findUserList(UserVo userVo) throws Exception;

      使用Junit测试刚刚做的配置

     1     @Test
     2     public void testFindUserList() throws Exception {
     3         SqlSession sqlSession = sqlSessionFactory.openSession();
     4         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
     5 
     6         UserPoJo userPoJo = new UserPoJo();
     7         UserVo userVo = new UserVo();
     8         userPoJo.setSex("男");
     9         userPoJo.setUsername("u");
    10         userVo.setUserPoJo(userPoJo);
    11 
    12         List<UserPoJo> userPoJoList = userMapper.findUserList(userVo);
    13 
    14         System.out.println(userPoJoList);
    15     }

      最后结果如下

    二、输出映射

    1、resultType

    ①在使用resultType进行映射的时候,只有查询出来的列名和包装类型中的属性名一致的时候,才会映射成功

    ②当使用简单类型作为输出映射的时候,我们需要保证Sql查询的结果只有一行一列,这样就可以使用简单类型

    如下所示示例

    SELECT COUNT(*) FROM t_user
    
    SELECT username FROM t_user WHERE id = 2

    2、resultMap  

      查询出来的列名和包装类型的属性名不一致的时候,可以使用resultMap来进行相应的映射(具体在使用中来说就是:定义resultMap中和属性的映射关系,然后将输出结果设置为resultMap的类型)  

      下面我们使用一个例子来进行具体的测试

      ①首先编写mapper配置文件,其中需要加上resultMap的配置

     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <!DOCTYPE mapper
     3         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     4         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     5 <mapper namespace="cn.mybatis.mapper.UserMapper">
     6 
     7     <!--定义resultMap
     8         type:resultMap最终映射的Java对象类型
     9         id:对resultMap的标识
    10     -->
    11     <resultMap id="userResultMap" type="user">
    12         <!--id:标识查询结果集中的唯一标识-->
    13         <id column="_id" property="id"></id>
    14         <!--result:标识查询结果集中其他列的标识-->
    15         <result column="_username" property="username"></result>
    16         <result column="_password" property="password"></result>
    17         <result column="_sex" property="sex"></result>
    18         <result column="_address" property="address"></result>
    19     </resultMap>
    20 
    21     <select id="findUserById_resultMap" parameterType="int" resultMap="userResultMap">
    22         SELECT id _id, username _username, PASSWORD _password, address _address, sex _sex FROM t_user WHERE id = #{id}
    23     </select>
    24 </mapper>

      ②然后在Mapper接口中添加方法

        //测试resultMap
        public User findUserById_resultMap(int id) throws Exception;

      ③ 测试方法

    1     @Test
    2     public void testFindUserById_resultMap() throws Exception {
    3         SqlSession sqlSession = sqlSessionFactory.openSession();
    4         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    5 
    6         User user = userMapper.findUserById_resultMap(2);
    7 
    8         System.out.println(user);
    9     }

      ④可以发现,使用resultMap的方式跟直接查询的结果是一致的

     

    三、动态Sql

     1、if判断

    我们在上面使用包装类查询的用例的时候,考虑到可能出现userPoJo会是null的情况,以及其相应的属性也可能是null的情况,这样的话,如果我们直接在Sql中进行拼接而不做判断的话,可能会出现一些错误,所以我们使用if来进行动态的拼接。

        <select id="findUserList" parameterType="cn.mybatis.po.UserVo" resultType="cn.mybatis.po.UserPoJo">
            SELECT * FROM t_user
            <where>
                <if test="userPoJo != null">
                    <if test="userPoJo.sex != null and userPoJo.sex != ''">
                        AND sex = #{userPoJo.sex}
                    </if>
                    <if test="userPoJo.username != null and userPoJo.username != ''">
                        AND username LIKE '%${userPoJo.username}%'
                    </if>
                </if>
            </where>
        </select>

     

    2.Sql片段

    上面的例子中,我们可以将if判断抽取出来作为一个Sql片段,这样做的好处是,可能再进行别的单表查询User信息的时候可以重复使用这些Sql。

     1     <!--定义Sql片段-->
     2     <sql id="query_user_info">
     3         <if test="userPoJo != null">
     4             <if test="userPoJo.sex != null and userPoJo.sex != ''">
     5                 AND sex = #{userPoJo.sex}
     6             </if>
     7             <if test="userPoJo.username != null and userPoJo.username != ''">
     8                 AND username LIKE '%${userPoJo.username}%'
     9             </if>
    10         </if>
    11     </sql>

    然后在别的Sql中将上面的Sql片段引入拼接即可

    1     <select id="findUserList" parameterType="cn.mybatis.po.UserVo" resultType="cn.mybatis.po.UserPoJo">
    2         SELECT * FROM t_user
    3         <where>
    4             <include refid="query_user_info"></include>
    5         </where>
    6     </select>

    3.foreach

    当我们需要一种同样的查询方式只是参数不同的时候:SELECT * FROM t_user WHERE 1=1 AND (id = 1 OR id =2 OR id = 3),可以使用foreach来记性sql拼接

        <sql id="query_ids">
            <if test="ids != null">
                <!--
                    SELECT * FROM t_user WHERE 1=1 AND (id = 1 OR id =2 OR id = 3)
                    cilleation: 指定的是输入参数集合的属性名
                    item:每次遍历的名称
                    open:开始遍历时拼接串
                    close:结束遍历时候拼接的串
                    separator:遍历的两个对象中间需要拼接的串
                -->
                <foreach collection="ids" item="item_id" open="AND (" close=")" separator=" OR ">
                    id=#{item_id}
                </foreach>
            </if>
        </sql>

     然后将上面的Sql片段加入响应的statment中

        <select id="findUserByIds" parameterType="userVo" resultType="userPoJo">
            SELECT * FROM t_user
            <where>
                <include refid="query_ids"></include>
            </where>
        </select>

     测试结果如下

  • 相关阅读:
    硬盘的结构和介绍,硬盘MBR详细介绍(超详细彩图)
    websocket协议学习
    Qt4可以使用trUtf8函数,其内容可以是中文,也可以是F硬编码
    QString转换为LPTSTR(使用了reinterpret_cast,真是叹为观止,但是也开阔了思路),三篇文章合起来的各种转换方法
    系统高可用
    Visual Studio
    管道是如何建立起来的?
    CLR和.Net对象
    任务调度
    路由与控制器
  • 原文地址:https://www.cnblogs.com/fsmly/p/10335456.html
Copyright © 2011-2022 走看看