Java小白的数据库爱情(七)mybatis 动态SQL

动态SQL

MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力。 如果你有使用 JDBC 或其他 相似框架的经验,你就明白条件地串联 SQL 字符串在一起是多么的痛苦,确保不能忘了空 格或在列表的最后省略逗号。动态 SQL 可以彻底处理这种痛苦。

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

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

if

if 判断条件 相当于java中的if语句
where 标签 代替的where 1=1恒等式
如果where标签对中有子句拼接,where就提供一个where关键字
去掉第一个多余的and
如果where标签对中没有子句拼接,提供where关键字

接口:

List<Emp> queryEmpByName(@Param("ename") String ename, @Param("deptno") Integer deptno);

xml:

<select id="queryEmpByName" resultType="Emp" >
    select * from emp where 1=1
        <if test="ename!=null and ename!=''">
            and ename = #{ename}
        </if>
        <if test="deptno!=null and deptno!=0">
            and deptno = #{deptno}
        </if>
</select>

java代码

List<Emp> list = mapper2.queryEmpByName("", 0);
   list.forEach(System.out::println);
   System.out.println("----------------");

   list = mapper2.queryEmpByName("SMITH",0);
   list.forEach(System.out::println);*/
where

用于管理 where 子句. 有如下功能:

  1. 如果没有条件, 不会生成 where 关键字
  2. 如果有条件, 会自动添加 where 关键字
  3. 如果第一个条件中有 and, 去除之
List<Emp> queryEmpWhere(@Param("ename") String ename, @Param("deptno") Integer deptno);
<select id="queryEmpWhere" resultType="Emp">
    select * from emp
    <where>
        <if test="ename!=null and ename!=''">
            and ename = #{ename}
        </if>
        <if test="deptno!=null and deptno!=0">
            and deptno = #{deptno}
        </if>
    </where>
</select>
List<Emp> list = mapper2.queryEmpWhere("",10);
list.forEach(System.out::println);
choose…when…otherwise

功能类似于 switch…case…

List<Emp> queryEmpChoose(@Param("ename") String ename, @Param("deptno") Integer deptno);
<select id="queryEmpChoose" resultType="Emp">
    select * from emp
    <where>
        <choose>
            <when test="deptno!=null and deptno!=0">
            and deptno = #{deptno}
            </when>
            <when test="ename!=null and ename!=''">
            and ename = #{ename}
            </when>
        </choose>
    </where>
</select>

List<Emp> list1 = mapper2.queryEmpChoose("KING",10);
list1.forEach(System.out::println);
set

用于维护 update 语句中的 set 子句. 功能如下:

  1. 满足条件时, 会自动添加 set 关键字
  2. 会去除 set 子句中多余的逗号
  3. 不满足条件时, 不会生成 set 关键字
<update id="queryEmpSet" >
    update emp
    <set>
        empno = #{empno},
        <if test="sal!=null and sal!=0">
          sal = #{sal},
        </if>
        <if test="ename!=null and ename!=''">
           ename = #{ename},
        </if>
    </set>
    where  empno = #{empno}
</update>
trim

使用trim代替where标签
用于在前后添加或删除一些内容

    1. prefix, 在前面添加内容
    2. prefixOverrides, 从前面去除内容
    3. suffix, 向后面添加内容
    4. suffixOverrides, 从后面去除内容
<select id="queryEmp" resultType="Emp">
        select <include refid="emp_all"/> from emp
        <trim prefix="where" prefixOverrides="and">
            <if test="ename!=null and ename!=''">
                and ename = #{ename}
            </if>
            <if test="deptno!=null and deptno!=0">
                and deptno = #{deptno}
            </if>
        </trim>
    </select>
bind

用于对数据进行再加工, 用于模糊查询

<select id="queryEmpBind" resultType="Emp" parameterType="string">
        select * from emp
            <where>
                <if test="ename!=null and ename!=''">
                    <bind name="ename" value="'%' + ename + '%'" />
                    and ename like #{ename}
                </if>
            </where>
    </select>
sql…include

sql用于提取 SQL 语句, include用于引用 SQL 语句

<sql id="emp_all">
        empno,ename,job,mgr,sal,comm,hiredate,deptno
    </sql>
select <include refid="emp_all"/> from emp
resultMap

resultMap用于自定义映射关系, 可以由程序员自主制定 列名和属性名的映射关系. 一旦使用 resultMap, 表示不再 采用自动映射机制.

resultMap的id与select的resultMap值保持一致

<resultMap id="hh" type="Dept">
     <id property="deptno" column="deptno"/>
     <result property="dname" column="dname"/>
     <result property="loc" column="loc"/>
 </resultMap>
<select id="queryDept" resultMap="hh">
    select * from dept
</select>

resultMap 的关联方式实现多表查询 (一对一|多对一)

  1. 在 StudentMapper.xml 中定义多表连接查询 SQL 语 句, 一次性查到需要的所有数据, 包括对应班级的信息.
  2. 通过resultMap标签定义映射关系, 并通过association 标签指定对象属性的映射关系. 可以把association标签 看成一个resultMap标签使用. javaType 属性表示当前 对象, 可以写全限定路径或别名.
    emp类中添加一个dept类型的属性 :
<!--做表字段与类型属性的映射-->
    <resultMap id="haha" type="Emp">
        <id property="empno" column="empno"></id>
        <result property="ename" column="ename"/>
        <result property="deptno" column="deptno"/>
        <!--自定义引用数据类型的关联-->
        <association property="dept" javaType="Dept">
            <id property="deptno" column="deptno"/>
            <result property="dname" column="dname"/>
            <result property="loc" column="loc"/>
        </association>
    </resultMap>
<select id="queryEmp" resultMap="haha">
    select empno,ename,e.deptno,dname,loc from emp e join dept d on e.deptno = d.deptno
</select>

resultMap 的关联方式实现多表查询 (一对 多)

在“一”的地方创建一个可以接受“多”的容器,把这个容器当作一个对象

在javabeen的dept类中添加一个List容器存储emp类型 的数据 :

 /*存储部门所有的员工信息*/
List<Emp> list = null;
    public List<Emp> getList() {
        return list;
    }
    public void setList(List<Emp> list) {
        this.list = list;
    }
    <!--做表字段与类型属性的映射-->
    <resultMap id="haha" type="Dept">
        <id property="deptno" column="deptno"></id>
        <result property="dname" column="dname"/>
        <result property="loc" column="loc"/>
        <!--设置当属性为集合类型时-->
        <collection property="list" javaType="list" ofType="Emp">
            <id property="empno" column="empno"/>
            <result property="ename" column="ename"/>
            <result property="deptno" column="deptno"/>
        </collection>
    </resultMap>

    <select id="queryDept" resultMap="haha">
        select d.deptno,dname,loc,empno,ename from dept d left join emp e on e.deptno = d.deptno
    </select>

public interface DeptMapper {
    List<Dept> queryDept();
}

注意

  • 接口的抽象方法与select的id要求保持一致

  • resultMap标签的id与 seselect中resultMap的value保持一致,

  • resultMap标签的type与 接口中List泛型保持一致,

  • collection标签中的ofType的值与javabeen中List泛型保持一致,

  • collection标签中的property=“list” javaType="list"与javabeen中返回值保持一致,

在这里插入图片描述

注解开发
CRUD 注解
  • @Select: 类似于select标签
  • @Insert: 类似于insert标签
  • @Update: 类似于update标签
  • @Delete: 类似于delete标签

用注解开发可以省略SQL映射文件,直接写在一个接口文件中,适用于简单的CRUD

 	@Select("select * from dept")
    List<Dept> queryDept();

    @Select("select * from dept where deptno = #{deptno}")
    Dept queryDeptByDeptno(int deptno);

    @Update("update dept set dname = #{dname} where deptno = #{deptno}")
    int updateDept(Dept dept);
其他注解
  • @Results: 类似于resultMap标签
  • @Result: 类似<resultMap的子标签
  • @One: 类似于association标签
  • @Many: 类似于collection标签
    @Select("select * from emp")
    @Results(value={
         @Result(property ="empno",column = "empno",id = true),  /*id = true主键字段*/
         @Result(property ="ename",column = "ename"),
         @Result(property ="deptno",column = "deptno"),
         @Result(property ="dept",one=@One(select="com.xxxx.mappers.DeptMapper.queryDeptByDeptno"),column = "deptno")
    })

@Select("select * from dept where deptno = #{deptno}")
Dept queryDeptByDeptno(int deptno);

点进去查看one注解为

public @interface One {
    String select() default "";

    FetchType fetchType() default FetchType.DEFAULT;
}

select 后面要为一个String类型,填写一个权限定类名加方法名查找到某条sql语句

tByDeptno"),column = “deptno”)
})


@Select(“select * from dept where deptno = #{deptno}”)
Dept queryDeptByDeptno(int deptno);


点进去查看one注解为

public @interface One {
String select() default “”;

FetchType fetchType() default FetchType.DEFAULT;

}


select 后面要为一个String类型,填写一个权限定类名加方法名查找到某条sql语句

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值