Java-MyBatis框架-3(动态sql语句,多表联查)

一、动态sql语句

什么是动态sql:根据参数的值,判断sql的条件。

MyBatis 的强大特性之一便是它的动态 SQL,即拼接SQL字符串。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。

通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中。

动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis 3 大大提升了它们,现在用不到原先一半的元素就可以了。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。

mybatis中的动态sql标签

1、if标签--单条件判断

可以通过条件判断,动态拼接sql

if标签一般用于非空验证,如上例,若id为空,if标签里的代码,将不会执行,反之,则会执行。

<!--因为如果id 或者 name 都为null 那么where后面的sql语句就会被隐藏,这样sql语句就会错所有加上1=1-->
    <select id="find_teacher" resultType="com.gsh.entity.Teacher">
        select * from teacher where 1=1
        /*test里是条件,如果条件成立那么if内的内容会显示否则不显示*/
        <if test="id!=null and id!=''">
            and id=#{id}
        </if>
        <if test="name!=null and name!=''">
            and name=#{name}
        </if>
    </select>

2、choose--多条件分支判断

<!--choose 多分支判断相当于switch when是里边的case -->
    <select id="find_teacher" resultType="com.gsh.entity.Teacher">
        select * from teacher where 1=1
        <choose>
            <when test="id!=null and id!=''">
                and id=#{id}
            </when>
            <when test="name!=null and name!=''">
                and name=#{name}
            </when>
            <otherwise>
            </otherwise>
        </choose>
    </select>

3、where标签

        我们观察到上面的sql都加了 where 1=1 ,如果不使用where 1=1 那么你的动态sql可能会出错。 我们能不能不加where 1=1呢! 可以 那么我们就可以使用where标签,作用:可以自动为你添加where关键字,并且可以帮你去除第一个and |or

where一般和if结合使用,根据参数值动态拼接sql

1.当需要拼接条件的时候,会自动拼接where关键字

2.自动去除第一个条件前面的and关键字

注:where标签会根据情况自动过滤掉前面的and

where 元素知道只有在一个以上的if条件有值的情况下才去插入“WHERE”子句。而且,若最后的内容是“AND”或“OR”开头的,where 元素也知道如何将他们去除。

如果 where 元素没有按正常套路出牌,我们还是可以通过自定义 trim 元素来定制我们想要的功能。比如,和 where 元素等价的自定义 trim 元素为:

trim 可以更新内容,也可以替换内容

<!--where-->
    <select id="find_teacher" resultType="com.gsh.entity.Teacher">
        select *from teacher
        <where>
            <if test="id!=null and id!=''">
                and id=#{id}
            </if>
            <if test="name!=null and name!=''">
                and name=#{name}
            </if>
        </where>
    </select>

4、foreach标签

  foreach标签可迭代任何对象(如数组、集合(list,set,map)等)和任何的字典或者数组对象传递给foreach作为集合参数,当使用可迭代对象或者数组时,index是当前迭代的次数,item的值是本次迭代获取的元素。当使用字典(或者Map.Entry对象的集合)时,index是键,item是值。collection标签可以填('list','array','map')

  foreach元素的属性主要有 item,index,collection,open,separator,close

collection:指定要循环的目标数据的类型,数组(array) list集合(list)

item:存储遍历的某个数据对象

open:拼接的字符串的前缀

close:拼接的字符串的后缀

separator:拼接内容的分隔符

使用foreach批量查询:

<mapper namespace="com.gsh.dao.UserDao">

    <select id="findAll" resultType="com.gsh.entity.User">
        select *from user where id in
                //目标数据类型       赋值给的元素 以什么开始以什么结束  用什么分割  
        <foreach collection="array" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </select>
</mapper>

使用foreach批量删除:

    <delete id="deleAll">
        delete from user where id in
        <foreach collection="array" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </delete>

使用foreach批量添加

    <insert id="addAll">
        insert  into user(username,password,name) values
        <foreach collection="list" item="u" separator=",">
            (#{u.username},#{u.password},#{u.name})
        </foreach>
    </insert>

5.sql片段

        在执行查询语句时不建议使用select *, 建议把查询的列写出。

我们可以把所有的列定义到sql标签中

 //定义的sql列 id可以理解为使用时的名字
<sql id="sql_stu">
        stu_id,stu_name,stu_age,c_id,c_name
    </sql>
    <select id="find_all" resultMap="stuMap">
                //在这里我们就可以通过 include标签使用我们定义的sql
        select <include refid="sql_stu"/>from tb_student s join tb_class c on s.class_id=c.c_id where stu_id=#{id};
    </select>

6.mybatis处理特殊字符

在xml文件中尽量避免写大于,小于,大于等于,小于等于  &

两种方式

第一种使用转义字符

 第二种使用<![CDATA[sql]]>

<![CDATA[

含有特殊符号的代码

]]>

 <select id="find_age" resultType="com.gsh.entity.Student">
           <![CDATA[select * from student where age >#{min} and age <#{max}]]>
    </select>

7、mybatis完成模糊查询

一共有两种方案可以完成模糊查询

第一种:${}

${}: 用字符串拼接的方式,拼接sql语句。当方法参数只有一个值的时候,

必须写${value}。不安全,会导致sql注入

<select id="select_like" resultType="com.gsh.entity.student">
        select * from student where name like '%${name}%'
    </select>

第二种:使用字符串函数 完成拼接 concat

<select id="select_like" resultType="com.gsh.entity.Student">
        select * from student where name like concat('%',#{name},'%')
    </select>

通过观察: 发现使用${}实际上是字符串拼接,它不能防止sql注入, 而#{}它是预编译,它可以防止sql注入问题,#{}实际使用的PreparedStatement.

8、多表联查

        多对一的关系,一个学生只属于一个班级,一个班级可以拥有多名学生,学生与班级的关系就属于多对一。

案例:通过学生的学号查询出学生的信息和学生所在班级的信息

第一步:在创建班级实体类,将班级信息作为属性封装在班级类中

第二步:在学生实体类属性中封装一个班级属性

public class Student {
    private int id;
    private String name;
    private int age;
    private int cid;
    //班级属性
    private Clazz clazz;
}

第三步:在学生dao中封装对应的方法

第四步:在学生的StudentMapper.xml文件中使用resultMap标签与association标签完成多表联查

使用association标签来解决一对一的关联查询,association标签可用的属性如下:

property:表示属性名

javaType:表示属性的类型(该属性名对应的数据类型)

    <resultMap id="stuMap" type="com.gsh.entity.Student">
        <id column="stu_id" property="id"/>
        <result column="stu_name" property="name"/>
        <result column="stu_age" property="age"/>
        <result column="class_id" property="cid"/>            
        //association表示一对一的关系,它是一的一方
        <association property="clazz" column="c_id" javaType="com.gsh.entity.Clazz">
            <id column="c_id" property="cid"/>
            <result column="c_name" property="cname"/>
        </association>
    </resultMap>

    <sql id="sql_stu">
        stu_id,stu_name,stu_age,c_id,c_name
    </sql>
    <select id="find_all" resultMap="stuMap">

        select <include refid="sql_stu"/>from tb_student s join tb_class c on s.class_id=c.c_id where stu_id=#{id};
    </select>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值