mybatis学习(4)mybatis的三个核心

14、输入映射

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

       1、传递pojo的包装对象

完成用户信息的综合查询,需要传入查询条件(可能包括用户信息,其它信息)

建议使用自定义的包装类型的pojo

       2、定义包装类型pojo

在包装类型的pojo中将复杂的查询条件包装进去

//在这里包装所需要的查询条件

   

    //用户查询条件

    private UserCustom userCustom;

 

    public UserCustom getUserCustom() {

        return userCustom;

    }

 

    public void setUserCustom(UserCustom userCustom) {

        this.userCustom = userCustom;

    }

       3、定义映射文件mapper.xml

在userMapper.xml中定义用户信息综合查询(查询条件复杂,通过高级查询进行复杂关联查询。

<!-- 用户信息综合查询

    #{userCustom.sex}:取出pojo包装对象中的性别值

     -->

    <select id="finduserList" parameterType="UserQueryVo"

        resultType="com.fzy.mybatis.po.UserCustom">

        select * from users where users.sex = #{userCustom.sex} and users.userName like '%${userCustom.userName}%'

    </select>

       4、mapper.java

    public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;

       5、单元测试:

//用户信息的综合查询

    @Test

    public void testFindUserList() throws Exception {

        SqlSession sqlSession = sqlSessionFactory.openSession();

        //创建UserMapper对象,mybatis自动生成mapper代理对象

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

       

        //创建包装对象,设置查询条件

        UserQueryVo userQueryVo = new UserQueryVo();

        UserCustom userCustom = new UserCustom();

        userCustom.setSex("女");

        userCustom.setUserName("岩");

        userQueryVo.setUserCustom(userCustom);

       

       

        //调用userMapper的方法

        List<UserCustom> list = userMapper.findUserList(userQueryVo);

        sqlSession.close();

        System.out.println(list);

    }

 

传递hashmap

<select id=’findUserByHashmap” parameterType=”hashmap” resultType=”user”>

       select * from users where userId = #{userId} and username like ‘%${userName}%’

</select>

 

15、输出映射

输出hashmap:

       输出pojo对象可以使用hashmap输出类型,将输出的字段名称作为map的key,value为字段名。

      

       1、resultType

       输出pojo对象和pojo列表

不管是输出的pojo单个对象还是一个列表(list中包括pojo),在mapper.xml中resultType指定的类型是一样的

在mapper.java指定的方法返回值类型不一样        (接口返回值类型不一样)

1、输出单个pojo对象,方法返回值是单个对象类型

2、输出pojo对象list,方法返回值是List<Pojo>

//用户信息综合查询

    public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;

   

    //用户信息综合查询总数

    public int findUserCount(UserQueryVo userQueryVo) throws Exception;

生成的动态代理对象中是根据mapper方法的返回值类型确定是调用selectOne(返回单个对象调用),还是选择selectList(返回集合对象调用)

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

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

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

       输出简单类型

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

mapper.xml

<!-- 用户信息综合查询总数

   parameterType:指定输入类型和findUserList一致

   resultType:输出结果类型

    -->

  

    <select id="findUserList" parameterType="UserQueryVo"

        resultType="int">

        select count(*) from users where users.sex = #{userCustom.sex} and users.userName like '%${userCustom.userName}%'

    </select>

mapper.java

//用户信息综合查询总数

    public int findUserCustom(UserQueryVo userQueryVo) throws Exception;

单元测试:

//用户信息综合查询总数

    @Test

    public void testFindUserCount() throws Exception {

        SqlSession sqlSession = sqlSessionFactory.openSession();

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

        //创建包装对象,设置查询条件

        UserQueryVo userQueryVo = new UserQueryVo();

        UserCustom userCustom = new UserCustom();

        userCustom.setSex("女");

        userCustom.setUserName("岩");

        userQueryVo.setUserCustom(userCustom);

        int count = userMapper.findUserCount(userQueryVo);

        System.out.println(count);

    }

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

              2、resultMap

mybatis中可以使用resultType完成高级输出结果映射

       resultMap使用方法

如果查询出来的列名和pojo的对象名不一致,通过定义一个resultMap对列名和pojo属性名之间做一个映射关系

需求:将下面的sql使用UserCustom完成映射

select userName userName_ from users where userId = #{value}

userCustom类中属性名和上边查询列名不一致

       1、定义resultMap

<!-- 定义resultMap映射

     select userName userName_ from users where userId = #{value}

     和user类中的属性做一个映射关系

     type:resultMap最终映射的java对像类型

     id:对resultMap的唯一标识

     -->

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

        <!-- id表示查询结果集中唯一标识

        column:查询出来的列名

        properties:type指定的pojo类型中的属性名

        最终resultMap对column和properties做一个映射关系(即对应关系)

         -->

         <id column="userId_" property="userId"/>

         <!-- 对普通名映射定义

         result:对普通名映射定义

         column:查询出来的列名

        properties:type指定的pojo类型中的属性名

        最终resultMap对column和properties做一个映射关系(即对应关系)

          -->

          <result column="userName_" property="userName"/>

</resultMap>

      

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

 <!-- 使用resultMap进行输出映射

    resultMap:指定定义的resultMap的id,如果这个resultMap在

    其他的mapper文件,前面需要加namespace

     -->

     <select id="findUserByIdResultMap" parameterType="int"

         resultMap="userResultMap">

         select userId userId_,userName userName_ from users where userId = #{value}

     </select>

       3、mapper.java

//根据id查询用户信息,使用resultMap输出

    public User findUserByIdResultMap(int userId) throws Exception;

单元测试:

@Test

    public void testFindUserByIdResultMap() throws Exception {

        SqlSession sqlSession = sqlSessionFactory.openSession();

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

       

        //调用userMapper方法

        User user = userMapper.findUserByIdResultMap(4);

       

        System.out.println(user);

    }

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

         resultMap进行输出映射,

如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。

16、动态sql(动态代理)

       1、什么是动态 sql

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

       2、需求

用户信息综合查询列表和用户信息查询列表总数这两个statement的定义使用动态sql

对查询条件进行判断,如果输入参数不为空才进行查询条件的拼接

mapper.xml

<!-- 用户信息综合查询

    #{userCustom.sex}:取出pojo包装对象中的性别值

     -->

    

    <select id="findUserList" parameterType="UserQueryVo"

        resultType="UserCustom">

        select * from users

       

        <!-- where可以自动去掉条件中的第一个and -->

        <where>

            <if test="userCustom!=null">

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

                and users.sex = #{userCustom.sex}

            </if>

            <if test="userCustom.userName!=null and userCustom.userName!=''">

                and users.userName like '%${userCustom.userName}%'

            </if>

        </if>

        </where> 

       

       

    </select>

   

   <!-- 用户信息综合查询总数

   parameterType:指定输入类型和findUserList一致

   resultType:输出结果类型

    -->

  

    <select id="findUserCount" parameterType="UserQueryVo"

        resultType="int">

        select count(*) from users

        <where>

            <if test="userCustom!=null">

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

                and users.sex = #{userCustom.sex}

            </if>

            <if test="userCustom.userName!=null and userCustom.userName!=''">

                and users.userName like '%${userCustom.userName}%'

            </if>

        </if>

        </where>

</select>

单元测试:

//由于使用动态sql,如果不设置某个值,条件不会拼接在sql

        userCustom.setSex("女");

        userCustom.setUserName("岩");

    userQueryVo.setUserCustom(userCustom);

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

<!-- 定义sql片段

    id:sql片段的唯一标识

   

    经验:sql判断基于单表来定义sql片段,这样的sql片段重用性才高

    在sql片段中不要包括where

     -->

     <sql id="query_user_where">

       

           <if test="userCustom!=null">

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

            and users.sex = #{userCustom.sex}

        </if>

        <if test="userCustom.userName!=null and userCustom.userName!=''">

            and users.userName like '%${userCustom.userName}%'

        </if>

       </if>

     </sql>

引用:

<select id="findUserList" parameterType="UserQueryVo"

        resultType="UserCustom">

        select * from users

       

        <!-- where可以自动去掉条件中的第一个and -->

        <where>

            <!-- 引用sql片段的id,如果refid指定的id不在本mapper文件中,需要前面加namespace -->

            <include refid="query_user_where"></include>

            <!-- 在这里还可能引用其他的sql片段:所以在sql片段中不要包含where -->

        </where>       

    </select>

4、foreach

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

需求:

在用户查询列表和查询总数的statement中增加多个输入查询

select * from users where userId=1 or userId=2 or userId=4

select * from users where userId in(1,2,4)

在输入参数类型中添加List<Integer>ids传入多个id

//传入多个id

    private List<Integer> ids;

   

    public List<Integer> getIds() {

        return ids;

    }

 

    public void setIds(List<Integer> ids) {

        this.ids = ids;

    }

修改mapper.xml中的sql片段

<!-- foreach标签 -->

        <if test="ids!=null">

            <!-- 使用foreach遍历传入ids

            collection:指定输入对象中的集合属性

            item:每次遍历的对象名生成的对象名

            open:开始遍历时拼接串

                :开始是

                AND (id=1 or id=2)

            close:结束遍历时拼接的串

            separator:遍历的两个对象中需要拼接的串

            -->

            <foreach collection="ids" item="user_id"

                open="AND (" close=")" separator="or">

            <!-- 每次遍历需要拼接的串 -->

            userId=#{user_id}

            </foreach>

        </if>

测试:

<!-- 实现“and id IN(1,2,4)”拼接 -->

            <!-- <foreach collection="ids" item="user_id"

                open="and id IN(" close=")" separator=",">

                #{user_id}

            </foreach> -->

猜你喜欢

转载自www.cnblogs.com/fzywhy/p/9583810.html