2019.5.26学习周报-----mybatis输入输出映射,动态sql

1、输入映射

通过parameterType指定输入参数的类型,类型可以是简单类型、hashMap和破解哦的包装类型。
传递pojo的包装对象:

  1. 定义包装类型pojo
package pojo;

import java.util.List;
/**
 * Student类的pojo包装对象
 */
public class StudentQueryVo {
    // 在这里包装所有的查询条件

    // 学生
    // 使用扩展类继承Student类
    private  StudentCustom studentCustom;

    public StudentCustom getStudentCustom() {
        return studentCustom;
    }

    public void setStudentCustom(StudentCustom studentCustom) {
        this.studentCustom = studentCustom;
    }

    // 其他查询条件。。。。。
    private List<Integer> snos;

    public List<Integer> getSnos() {
        return snos;
    }

    public void setSnos(List<Integer> snos) {
        this.snos = snos;
    }
}	
  1. 扩展类
package pojo;

/**
 * Student类的扩展类
 */
public class StudentCustom extends Student {
}

  1. Mapper.xml
    通过studentQueryVo包装类包装查询时所用到的所有信息(类),作为参数传入,在sql中调用其中的属性即可
    sutdentCustom指的是StudentQueryVo的成员变量名。
	<!-- 用户信息综合查询 -->
    <!--
     通过studentQueryVo包装类包装查询时所用到的所有信息(类),作为参数传入
     在sql中调用其中的属性即可
     -->
    <select id="findStudentList" parameterType="StudentQueryVo" resultType="StudentCustom">
        select *
        from test_mybatis.student
        where sage = #{studentCustom.sage}
          and saddress = #{studentCustom.saddress};
    </select>
  1. Mapper.java
	/**
     * 用户信息的综合查询
     * 通过studentQueryVo包装类包装查询时所用到的所有信息(类),作为参数传入
     * 在sql中调用其中的属性即可
     * @param studentQueryVo 查询时会用到的所有信息所包装成的包装类
     * @return 因为不确定查询的字段值,所以使用扩展类(或其容器)来接收查询结果
     * @throws Exception
     */
    public List<StudentCustom> findStudentList(StudentQueryVo studentQueryVo) throws Exception;
  1. 测试代码
    @Test
    public void TestfindStudentList() throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();

        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

        //构造包装类
        StudentQueryVo studentQueryVo = new StudentQueryVo();
        //包装类的成员变量Student扩展类
        StudentCustom studentCustom = new StudentCustom();
        studentCustom.setSage(18);
        studentCustom.setSaddress("xa");
        studentQueryVo.setStudentCustom(studentCustom);

        //查询
        List<StudentCustom> studentCustomList = studentMapper.findStudentList(studentQueryVo);

        for(StudentCustom studentCustom1 : studentCustomList){
            System.out.println(studentCustom1);
        }
        sqlSession.close();
    }

2、输出映射

输出映射有两种方式:

  1. resultType:
    • 使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
    • 如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。
    • 只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。
      输出简单类型时:查询出来的结果集只有一行且一列,可以使用简单类型进行输出映射。
      输出pojo对象还是pojo列表取决于接口中设定方法的返回值
  2. resultMap
    mybatis中使用resultMap完成高级输出结果映射。(一对多,多对多)
    resultMap使用方法:
    1. 定义resultMap

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

    <!-- 使用id为toStudent的resultMap将sno_映射为Student.sno,sage_映射为Student.sage -->
    <resultMap id="toStudent" type="Student">
        <id column="sno_" property="sno"/>
        <result column="sage_" property="sage"/>
    </resultMap>
    
    <!-- resultMap输出映射 -->
    <select id="findStudentListResultMap" parameterType="StudentQueryVo" resultMap="toStudent">
        select sno sno_, sage sage_
        from test_mybatis.student
        where sage > #{studentCustom.sage}
          and saddress = #{studentCustom.saddress};
    </select>
    
    1. 接口
    /**
     * 通过resultMap进行输出映射,将不可识别的字段名映射为Student对象
     * @param studentQueryVo 查询时会用到的所有信息所包装成的包装类
     * @return
     * @throws Exception
     */
    public List<Student> findStudentListResultMap(StudentQueryVo studentQueryVo) throws Exception;
    
    1. 测试代码 略
    2. 测试结果
      在这里插入图片描述

小结
• 使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
• 如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。

3、动态sql

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

  1. if判断

    1. Mapper.xml中使用where标签和if标签对查询条件进行判断
      每一个if内test属性是拼接的条件,标签内设置拼接的字符串,用and开头
      where可以自动去掉第一个and
    <!-- 动态sql -->
    <select id="findStudentListDynamicSQL" parameterType="StudentQueryVo" resultType="StudentCustom">
        select * from test_mybatis.student
        <where>
            <include refid="selectStudentWhere"/>
            <!-- 这里可能再调用其他的sql片段 -->
        </where>
    </select>
    
    1. 接口
    /**
     * 使用动态sql
     * @param studentQueryVo 查询时会用到的所有信息所包装成的包装类
     * @return 因为不确定查询的字段值,所以使用扩展类(或其容器)来接收查询结果
     * @throws Exception
     */
    public List<StudentCustom> findStudentListDynamicSQL(StudentQueryVo studentQueryVo) throws Exception;
    
    1. 测试
        @Test
    public void findStudentListDynamicSQL() throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
    
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
    
        //构造包装类
        StudentQueryVo studentQueryVo = new StudentQueryVo();
        //包装类的成员变量Student扩展类
        StudentCustom studentCustom = new StudentCustom();
        //studentCustom.setSname("en");
        //studentCustom.setSage(19);
        //studentCustom.setSaddress("xa");
        List<Integer> snos = new ArrayList<>();
        snos.add(1);
        snos.add(4);
        snos.add(7);
        studentQueryVo.setStudentCustom(studentCustom);
        studentQueryVo.setSnos(snos);
    
        //查询
        List<StudentCustom> studentCustomList = studentMapper.findStudentListDynamicSQL(studentQueryVo);
    
        for(StudentCustom studentCustom1 : studentCustomList){
            System.out.println(studentCustom1);
        }
        sqlSession.close();
    }
    

    在这里插入图片描述
    在这里插入图片描述

  2. sql片段
    将又将编写好的动态sql判断代码抽取出来,则称一个sql片段。在其他的statement中就可以引用该sql片段。

    1. 定义、使用(在sql片段中不要写进where标签,后面使用sql片段时可能会同时使用多个sql片段,where会重复,造成语法错误)
        <!-- sql片段 -->
    <sql id="selectStudentWhere">
        <if test="studentCustom != null">
            <if test="studentCustom.sname != null and studentCustom.sname != ''">
                and sname like '%${studentCustom.sname}%'
            </if>
            <if test="studentCustom.sage != null and studentCustom.sage != ''">
                and sage = #{studentCustom.sage}
            </if>
            <if test="studentCustom.saddress != null and studentCustom.saddress != ''">
                and saddress = #{studentCustom.saddress}
            </if>
        </if>
    </sql>
    <!-- 动态sql -->
    <select id="findStudentListDynamicSQL" parameterType="StudentQueryVo" resultType="StudentCustom">
        select * from test_mybatis.student
        <where>
            <include refid="selectStudentWhere"/>
            <!-- 这里可能再调用其他的sql片段 -->
        </where>
    </select>
    
  3. foreach标签
    向sql传递数组或List,mybatis使用foreach解析,foreach可以将数组或list中的元素取出来进行拼接。拼接出的串作为查询条件。如“id in(1,2,3)”或“and(id = 1 or id = 2 or id = 3)”。(高亮部分为拼接内容)

    1. 使用方法
        <if test="snos != null">
        <!-- 使用foreach拼接查询条件
        如“id in(1, 2, 3)”或“and(id = 1 or id = 2 or id = 3)”
        collection:指定输入 对象中集合属性
        item:每个遍历生成对象中
        open:开始遍历时拼接的串
        close:结束遍历时拼接的串
        separator:遍历的两个对象中需要拼接的串
        -->
        <foreach collection="snos" item="sno" open="and (" close=")" separator="or">
            <!-- 需要进行拼接的串 -->
            sno = #{sno}
        </foreach>
        <!-- 实现id in(1, 2, 3) -->
        <foreach collection="snos" item="sno" open="and sno in (" close=")" separator=",">
            #{sno}
        </foreach>
    </if>
    
     需要在包装类StudentQueryVo中设置成员变量List<Integer> snos
    
    private List<Integer> snos;
    
    public List<Integer> getSnos() {
        return snos;
    }
    
    public void setSnos(List<Integer> snos) {
        this.snos = snos;
    }
    
    
    1. 测试
        @Test
    public void findStudentListDynamicSQL() throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
    
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
    
        //构造包装类
        StudentQueryVo studentQueryVo = new StudentQueryVo();
        //包装类的成员变量Student扩展类
        StudentCustom studentCustom = new StudentCustom();
        //studentCustom.setSname("en");
        //studentCustom.setSage(19);
        //studentCustom.setSaddress("xa");
        List<Integer> snos = new ArrayList<>();
        snos.add(1);
        snos.add(4);
        snos.add(7);
        studentQueryVo.setStudentCustom(studentCustom);
        studentQueryVo.setSnos(snos);
    
        //查询
        List<StudentCustom> studentCustomList = studentMapper.findStudentListDynamicSQL(studentQueryVo);
    
        for(StudentCustom studentCustom1 : studentCustomList){
            System.out.println(studentCustom1);
        }
        sqlSession.close();
    }
    

    在这里插入图片描述
    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值