• Mybatis学习(4)输入映射、输出映射、动态sql


    一、输入映射:

    通过parameterType指定输入参数的类型,类型可以是简单类型、hashmap、pojo的包装类型

    1) 传递pojo的包装对象

     需求是:完成用户信息的综合查询,传入的查询条件复杂;(包括用户信息、其他信息等);

    定义包装类型:

      用户扩展类:

    package com.cy.po;
    
    /**
     *用户的扩展类
     * @author chengyu
     *
     */
    public class UserCustom extends User{
    
    }

      视图层面的用户包装类型:

     1 package com.cy.po;
     2 
     3 /**
     4  * 用户的包装类型
     5  * @author chengyu
     6  *
     7  */
     8 public class UserQueryVo {
     9     //在这里包装所需要的查询条件
    10     
    11     //用户查询条件
    12     private UserCustom userCustom;
    13     
    14     //可以包装其它的查询条件,订单、商品
    15     //....
    16         
    17     public UserCustom getUserCustom() {
    18         return userCustom;
    19     }
    20 
    21     public void setUserCustom(UserCustom userCustom) {
    22         this.userCustom = userCustom;
    23     }
    24 }
    View Code

    mapper.xml:

    <!-- 用户信息综合查询
        #{userCustom.sex}:取出pojo包装对象中性别值
        ${userCustom.username}:取出pojo包装对象中用户名称
         -->
        <select id="findUserList" parameterType="com.cy.po.UserQueryVo" resultType="com.cy.po.UserCustom">
            SELECT * FROM USER where sex = #{userCustom.sex} and username like '%${userCustom.username}%'
        </select>

    mapper.接口:

    public interface UserMapper {
        //用户信息综合查询
        public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;

    测试代码:

     1 @Test
     2     public void testFindUserList() throws Exception {
     3         SqlSession sqlSession = sqlSessionFactory.openSession();
     4         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
     5         
     6         //创建包装对象,设置查询条件
     7         UserQueryVo userQueryVo = new UserQueryVo();
     8         UserCustom userCustom = new UserCustom();
     9         userCustom.setSex("1");
    10         userCustom.setUsername("张三丰");
    11         userQueryVo.setUserCustom(userCustom);
    12         //调用userMapper的方法
    13         
    14         List<UserCustom> list = userMapper.findUserList(userQueryVo);
    15         
    16         System.out.println(list);
    17     }
    View Code

    二、输出映射、

     1、resultType:

    使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。

    如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。

    只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。

    1)  输出简单类型: ----》》查询出来的结果集只有一行且一列,可以使用简单类型进行输出映射。

    需求是,用户信息的综合查询列表总数,通过查询总数和上边用户综合查询列表才可以实现分页。

    mapper.xml:

    1 <!-- 用户信息综合查询总数
    2     parameterType:指定输入类型和findUserList一样
    3     resultType:输出结果类型
    4      -->
    5     <select id="findUserCount" parameterType="com.cy.po.UserQueryVo" resultType="int">
    6        SELECT count(*) FROM USER  where sex = #{userCustom.sex} and username like '%${userCustom.username}%'
    7     </select>

    mapper.java接口:

    //用户信息综合查询总数
        public int findUserCount(UserQueryVo userQueryVo) throws Exception;

    juit测试代码:

     1 //测试查询用户数
     2     @Test
     3     public void testFindUserCount() throws Exception {
     4         SqlSession sqlSession = sqlSessionFactory.openSession();
     5         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
     6         
     7         //创建包装对象,设置查询条件
     8         UserQueryVo userQueryVo = new UserQueryVo();
     9         UserCustom userCustom = new UserCustom();
    10         userCustom.setSex("1");
    11         userCustom.setUsername("张三丰");
    12         userQueryVo.setUserCustom(userCustom);
    13         int count = userMapper.findUserCount(userQueryVo);
    14         System.out.println(count);
    15     }
    View Code

    2)输出pojo对象,和pojo对象列表:

    不管是输出的pojo单个对象还是一个列表,在mapper.xml中resultType指定的类型是一样的。在mapper.java指定的方法返回值类型不一样;

    输出单个pojo,返回值是这个pojo对象类型

    输出pojo列表,返回值是List<pojo>

    2.resultMap

    mybatis中使用resultMap完成高级输出结果映射。如果查询出来的列名和pojo的属性名不一致,可以通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。

    使用方法啊:

    1)定义resultMap

    2)使用resultMap作为statement的输出映射类型

    mapper.xml:

     1 <!--使用mapper代理方法开发,namespace有特殊重要的作用,namespace等于mapper接口地址-->
     2 <mapper namespace="com.cy.mapper.UserMapper">
     3     
     4     <!-- 定义resultMap 将SELECT id id_,username username_ FROM USER 和User类中的属性作一个映射关系
     5     type:resultMap最终映射的java对象类型,可以使用别名
     6     id:对resultMap的唯一标识
     7      -->
     8      <resultMap type="com.cy.po.User" id="userResultMap">
     9          <!-- id表示查询结果集中唯一标识  column:查询出来的列名 property:type指定的pojo类型中的属性名-->
    10          <id column="id_" property="id"/>
    11          
    12          <!-- result:对普通名映射定义 column:查询出来的列名 property:type指定的pojo类型中的属性名 -->
    13          <result column="username_" property="username"/>
    14      </resultMap>
    15      
    16      <!-- 使用resultMap进行输出映射
    17     resultMap:指定定义的resultMap的id,如果这个resultMap在其它的mapper文件,前边需要加namespace
    18     -->
    19     <select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
    20         SELECT id id_,username username_ FROM USER WHERE id=#{value}
    21     </select>
    22 </mapper>

    mapper接口:

    //根据id查询用户信息,使用resultMap输出
    public User findUserByIdResultMap(int id) throws Exception;

    juittest代码:

    @Test
        public void testFindUserByIdResultMap() throws Exception {
            SqlSession sqlSession = sqlSessionFactory.openSession();
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            
            User user = userMapper.findUserByIdResultMap(1);
            System.out.println(user);
        }

     3.自己做的实验,输入类型和传出类型都为java.util.Map:

    <!-- 查看resultMap的使用 java.util.Map 
            传入参数为hashmap id和username都为map的key
        -->
        <select id="findUserByIdDefaultMap" parameterType="java.util.Map" resultType="java.util.Map">
            SELECT * FROM USER where id=#{id} and username like '%${username}%'
        </select>

    并且java.util.Map在mybatis中的别名是hashmap,写成这样,效果一样的:

    <select id="findUserByIdDefaultMap" parameterType="hashmap" resultType="hashmap">
            SELECT * FROM USER where id=#{id} and username like '%${username}%'
        </select>

    mapper接口:

    //find user parameterMap and resultMap both are java.uti.Map
    public Map<String, String> findUserByIdDefaultMap(Map<String, String> parmas) throws Exception;

    测试代码:

    @Test 
        public void testfindUserByIdDefaultMap() throws Exception{
            SqlSession sqlSession = sqlSessionFactory.openSession();
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            
            Map<String ,String> params = new HashMap<String, String>();
            params.put("id", "25");
            params.put("username", "小明");
            Map<String, String> user = userMapper.findUserByIdDefaultMap(params);
            System.out.println(user);
        }

    打印结果:

    DEBUG [main] - ==>  Preparing: SELECT * FROM USER where id=? and username like '%小明%' 
    DEBUG [main] - ==> Parameters: 25(String)
    DEBUG [main] - <==      Total: 1
    {id=25, sex=1, username=陈小明, address=河南郑州}
    

      

    三、动态sql

    mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装。

    例子1:

      需求: 对上面程序中的  用户信息综合查询列表这个statement使用动态sql,对查询条件进行判断,如果输入参数不为空才进行查询条件拼接。

    mapper.xml:

    <!-- 用户信息综合查询
        #{userCustom.sex}:取出pojo包装对象中性别值
        ${userCustom.username}:取出pojo包装对象中用户名称
         -->
        <select id="findUserList" parameterType="com.cy.po.UserQueryVo" resultType="com.cy.po.UserCustom">
            SELECT * FROM USER
            
            <!-- where可以自动去掉条件中的第一个and -->
            <where>
                <if test="userCustom!=null">
                    <if test="userCustom.sex!=null and userCustom.sex!=''">
                        and sex = #{userCustom.sex}
                    </if>
                    <if test="userCustom.username!=null and userCustom.username!=''">
                        and username like '%${userCustom.username}%'
                    </if>
                </if>
            </where>
        </select>

    测试代码:

     1 @Test
     2     public void testFindUserList() throws Exception {
     3         SqlSession sqlSession = sqlSessionFactory.openSession();
     4         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
     5         
     6         //创建包装对象,设置查询条件
     7         UserQueryVo userQueryVo = new UserQueryVo();
     8         UserCustom userCustom = new UserCustom();
     9         
    10         //动态sql的存在,不设置某个值,条件不会拼接在sql中
    11         //userCustom.setSex("1");
    12         userCustom.setUsername("小明");
    13         userQueryVo.setUserCustom(userCustom);
    14         
    15         List<UserCustom> list = userMapper.findUserList(userQueryVo);
    16         System.out.println(list);
    17     }
    View Code

    打印:

    DEBUG [main] - ==> Preparing: SELECT * FROM USER WHERE username like '%小明%'
    DEBUG [main] - ==> Parameters:
    DEBUG [main] - <== Total: 3
    [------->> User [id=16, username=张小明, sex=1, birthday=null, address=河南郑州], ------->> User [id=22, username=陈小明, sex=1, birthday=null, address=河南郑州], ------->> User [id=25, username=陈小明, sex=1, birthday=null, address=河南郑州]]

    2)sql片段:

    将上边实现的动态sql判断代码块抽取出来,组成一个sql片段。其它的statement中就可以引用sql片段。

    mapper.xml:----定义sql片段、引用sql片段:

    <mapper namespace="com.cy.mapper.UserMapper">
        
        <!-- 定义sql片段id:sql片段的唯 一标识
             经验:是基于单表来定义sql片段,这样话这个sql片段可重用性才高;在sql片段中不要包括 where
        -->
        <sql id="query_user_where">
            <if test="userCustom!=null">
                <if test="userCustom.sex!=null and userCustom.sex!=''">
                    and sex = #{userCustom.sex}
                </if>
                <if test="userCustom.username!=null and userCustom.username!=''">
                    and username like '%${userCustom.username}%'
                </if>
            </if>
        </sql>
    
        <!-- 用户信息综合查询
        #{userCustom.sex}:取出pojo包装对象中性别值
        ${userCustom.username}:取出pojo包装对象中用户名称
         -->
        <select id="findUserList" parameterType="com.cy.po.UserQueryVo" resultType="com.cy.po.UserCustom">
            SELECT * FROM USER
            <where>
                <!-- 引用sql片段 的id,如果refid指定的id不在本mapper文件中,需要前边加namespace -->
                <include refid="query_user_where"></include>
            </where>
        </select>
    </mapper>

     3)使用foreach标签:

    向sql传递数组或List,mybatis使用foreach解析;

    需求:在用户查询列表的statement中增加多个id输入查询。

    输入参数类型UserQueryVo中添加ids List,根据这个list查:

     1 package com.cy.po;
     2 
     3 import java.util.List;
     4 
     5 /**
     6  * 用户的包装类型
     7  * @author chengyu
     8  *
     9  */
    10 public class UserQueryVo {
    11     //在这里包装所需要的查询条件
    12     
    13     private List<Integer> ids;
    14     
    15     //用户查询条件
    16     private UserCustom userCustom;
    17     
    18     //可以包装其它的查询条件,订单、商品
    19     //....
    20     
    21     public List<Integer> getIds() {
    22         return ids;
    23     }
    24     public void setIds(List<Integer> ids) {
    25         this.ids = ids;
    26     }
    27     public UserCustom getUserCustom() {
    28         return userCustom;
    29     }
    30     public void setUserCustom(UserCustom userCustom) {
    31         this.userCustom = userCustom;
    32     }
    33 }
    View Code

    mapper.xml:

        <sql id="query_user_where">
            <if test="userCustom!=null">
                <if test="userCustom.sex!=null and userCustom.sex!=''">
                    and sex = #{userCustom.sex}
                </if>
                <if test="userCustom.username!=null and userCustom.username!=''">
                    and username like '%${userCustom.username}%'
                </if>
                <if test="ids!=null">
                    <!-- 使用 foreach遍历传入ids
                    collection:指定输入 对象中集合属性
                    item:每个遍历生成对象中
                    open:开始遍历时拼接的串
                    close:结束遍历时拼接的串
                    separator:遍历的两个对象中需要拼接的串
                     -->
                     
                    <!-- AND (id=1 OR id=10 OR id=16)-->
                    <foreach collection="ids" item="user_id" open="and (" close=")" separator="or">
                        id=#{user_id}
                    </foreach>
                    
                    <!-- and id IN(1,10,16) -->
                    <!-- <foreach collection="ids" item="user_id" open="and id in(" close=")" separator=",">
                        #{user_id}
                    </foreach> -->
                </if>
            </if>
        </sql>
    
        <!-- 用户信息综合查询
        #{userCustom.sex}:取出pojo包装对象中性别值
        ${userCustom.username}:取出pojo包装对象中用户名称
         -->
        <select id="findUserList" parameterType="com.cy.po.UserQueryVo" resultType="com.cy.po.UserCustom">
            SELECT * FROM USER
            <where>
                <!-- 引用sql片段 的id,如果refid指定的id不在本mapper文件中,需要前边加namespace -->
                <include refid="query_user_where"></include>
            </where>
        </select>

    测试代码:

     1 @Test
     2     public void testFindUserList() throws Exception {
     3         SqlSession sqlSession = sqlSessionFactory.openSession();
     4         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
     5         
     6         //创建包装对象,设置查询条件
     7         UserQueryVo userQueryVo = new UserQueryVo();
     8         UserCustom userCustom = new UserCustom();
     9         
    10         //动态sql的存在,不设置某个值,条件不会拼接在sql中
    11         //userCustom.setSex("1");
    12         userCustom.setUsername("小明");
    13         
    14         //传入多个id
    15         List<Integer> ids = new ArrayList<Integer>();
    16         ids.add(1);
    17         ids.add(10);
    18         ids.add(16);
    19         userQueryVo.setIds(ids);
    20         userQueryVo.setUserCustom(userCustom);
    21         
    22         List<UserCustom> list = userMapper.findUserList(userQueryVo);
    23         System.out.println(list);
    24     }
    View Code

    可以看打印结果拼接的sql:

    DEBUG [main] - ==> Preparing: SELECT * FROM USER WHERE username like '%小明%' and ( id=? or id=? or id=? )
    DEBUG [main] - ==> Parameters: 1(Integer), 10(Integer), 16(Integer)
    DEBUG [main] - <== Total: 1
    [------->> User [id=16, username=张小明, sex=1, birthday=null, address=河南郑州]]

  • 相关阅读:
    20145223《信息安全系统设计基础》第7周学习总结
    20145223《信息安全系统设计基础》第6周学习总结
    20145223《信息安全系统设计基础》第5周学习总结
    20145223《信息安全系统设计基础》第3周学习总结
    20145223《信息安全系统设计基础》第2周学习总结
    20145223《信息安全系统设计基础》第1周学习总结
    node小爬虫
    node知识
    css之单行缩略..以及多行缩略
    html两大布局
  • 原文地址:https://www.cnblogs.com/tenWood/p/6280519.html
Copyright © 2020-2023  润新知