(三)MyBatis学习笔记——动态SQL语句

一、案例测试:不使用动态SQL语句

如果需要使用带有复杂参数的SQL语句,比如条件查询语句,需要怎样实现呢?例如,现在需要根据sid、name、age三个字段进行查询记录。

  1. 首先在映射配置文件中建立查询语句:
<!--多条件查询-->
<select id="selectCondition" resultType="student" parameterType="student">
    SELECT * FROM student WHERE sid=#{sid} AND name=#{name} AND age=#{age}
</select>
  1. 然后在StudentService.class定义条件查询接口,在StudentServiceImpl.class中编写条件查询的代码:
//动态SQL的实现--条件查询
    @Override
    public List<Student> selectCondition(Student student) {
        List<Student> list = null;
        SqlSession sqlSession = null;
        InputStream is = null;
        try {
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");
            //2.获取到SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            //3.通过工厂对象获取到SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);
            //4.获取StudentMapper接口的实现类对象
            StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);//等同于:StudentMapper studentMapper = new StudentMapperImpl();

            //5.通过实现类对象调用方法,接收结果
            list = studentMapper.selectCondition(student);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //6.释放资源
            if(sqlSession != null) {
                sqlSession.close();
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //7.返回结果
        return list;
    }
  1. 控制层测试功能:
//条件查询功能
    @Test
    public void selectCondition(){
        //创建Student对象,设置查询条件
        Student stuTmp = new Student();
        stuTmp.setSid(2);
        stuTmp.setName("小乙");
        stuTmp.setAge(24);
        List<Student> students = service.selectCondition(stuTmp);
        for (Student stu : students) System.out.println(stu);
    }
  1. 结果:此时可以查询到该条记录。但将setSid、setName、setAge中任意一条去掉,即sid、name、age三个参数缺少任意一个,则不能查询到此记录。如果想这三个参数不管传入几个,都能执行查询语句呢?例如,只传入sid,就根据sid查询;传入了sid和age就根据这两个字段查。

二、动态SQL语句

动态SQL根据实体类的不同取值,可以使用不同的SQL语句进行查询。主要用到的标签有如下:

  • <where> 用于替换WHERE条件之后的语句
  • <if>
    <if test="条件判断">
    	查询条件拼接
    </if>
    
  • <foreach>
    <foreach collection="参数容器类型(list、array)" open="开始SQL语句" close="结束SQL语句" item="参数变量名" separator="分隔符">
    	获取参数
    </foreach>
    

1.< if>标签使用案例

将第一步中的映射文件中的条件查询语句更改为如下:

<!--多条件查询-->
    <select id="selectCondition" resultType="student" parameterType="student">
        SELECT * FROM student
        <where>
            <if test="sid != null">
                sid=#{sid}
            </if>
            <if test="name != null">
                AND name=#{name}
            </if>
            <if test="age != null">
                AND age=#{age}
            </if>
        </where>
    </select>

此时不管通过sid、name、age中的一个或多个字段都能查询到该记录。

2.< foreach>标签使用案例

  1. 首先在映射配置文件中建立查询语句:
    <select id="selectByIds" resultType="student" parameterType="list">
        SELECT * FROM student
        <where>
            <foreach collection="list" open="sid IN(" close=")" item="sid" separator=",">
                #{sid}
            </foreach>
        </where>
    </select>
  1. 然后在StudentService.class定义条件查询接口,在StudentServiceImpl.class中编写条件查询的代码:
//根据多个查询有无其中一个
    @Override
    public List<Student> selectByIds(List<Integer> idList) {
        List<Student> list = null;
        SqlSession sqlSession = null;
        InputStream is = null;
        try {
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");
            //2.获取到SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            //3.通过工厂对象获取到SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);
            //4.获取StudentMapper接口的实现类对象
            StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);//等同于:StudentMapper studentMapper = new StudentMapperImpl();

            //5.通过实现类对象调用方法,接收结果
            list = studentMapper.selectByIds(idList);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //6.释放资源
            if(sqlSession != null) {
                sqlSession.close();
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //7.返回结果
        return list;
    }
  1. 最后在控制层中测试:
//根据多个查询有无其中一个
    @Test
    public void selectByIds(){
        //创建idList,设置查询条件
        List<Integer> idList = new ArrayList<>();
        idList.add(1);
        idList.add(2);
        List<Student> students = service.selectByIds(idList);
        for (Student stu : students) System.out.println(stu);
    }

此时可查询到在list中存在的sid的记录。

三、常用SQL语句抽取

SELECT * FROM这种SQL语句使用较为频繁,所以可以将其进行抽取,以便于后续复用。这里使用<sql>标签:

<sql id="SQL语句唯一标识"> 抽取的SQL语句 </sql>

通过<include>标签引入定义的SQL语句:

<include refid="SQL语句唯一标识" />

例如,在上一步的<foreach>标签使用时可以使用:

	<sql id="select0"> SELECT * FROM student </sql>

    <select id="selectByIds" resultType="student" parameterType="list">
        <include refid="select0"/>
        <where>
            <foreach collection="list" open="sid IN(" close=")" item="sid" separator=",">
                #{sid}
            </foreach>
        </where>
    </select>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值