【MyBatis】动态SQL

本文已收录于专栏
⭐️ 《MyBatis》⭐️

学习指南:

  • MyBatis
    • 映射文件概述
    • 常用配置
      • environments标签
      • mapper标签
      • Properties标签
      • typeAliases标签
    • 代理开发
      • 开发步骤
  • 动态SQL
    • if
    • where
    • set
    • foreach
  • 完结散花
  • 参考文献

MyBatis

MyBatis 是一款优秀的持久层框架

MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的过程

MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 实体类 【Plain Old Java Objects,普通的 Java对象】映射成数据库中的记录。

映射文件概述

【MyBatis】动态SQL_第1张图片

常用配置

environments标签

数据源环境配置标签

数据库环境的配置,支持多环境配置

事务管理器(transactionManager)类型有两种:

    • JDBC:这个配置就是直接使用了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。

    • MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如JEE 应用服务器的上下文)。 默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置 为 false 来阻止它默认的关闭行为。

数据源(dataSource)类型有三种:

    • UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接。

    • POOLED:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来。

    • JNDI:这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置 一个 JNDI 上下文的引用

【MyBatis】动态SQL_第2张图片

mapper标签

加载映射配置

该标签的作用是加载映射的,加载方式有如下几种:

• 使用相对于类路径的资源引用,例如:


• 使用完全限定资源定位符(URL),例如:


• 使用映射器接口实现类的完全限定类名,例如:


• 将包内的映射器接口实现全部注册为映射器,例如:

Properties标签

该标签可以加载外部的properties文件

​ 实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件(像web阶段抽取一样)

【MyBatis】动态SQL_第3张图片

typeAliases标签

设置类型别名

【MyBatis】动态SQL_第4张图片

代理开发

采用 Mybatis 的代理开发方式实现 DAO 层的开发,这种方式是我们后面进入企业的主流。 Mapper 接口开发方法只需要程序员编写Mapper 接口(相当于Dao 接口),由Mybatis 框架根据接口定义创建接 口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper 接口开发需要遵循以下规范:

    1、 Mapper.xml文件中的namespace与mapper接口的全限定名相同

    2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同

    3、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同

    4、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

对应关系图解

【MyBatis】动态SQL_第5张图片

开发步骤

①编写BrandMapper接口

②进行mapper文件的相应配置(要遵守规范)

③测试用例

①编写BrandMapper接口

public interface BrandMapper {
   //实现操作:查询所有
   List<Brand> selectAll();
}

②进行mapper文件的相应配置(要遵守规范)


DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace = "com.spellbind.mapper.BrandMapper">
    
    <resultMap id="brandResultMap" type="brand">
        <result column="brand_name" property="brandName">result>
        <result column="company_name" property="companyName">result>
    resultMap>

    
    <select id="selectAll" resultMap="brandResultMap">
        select * from tb_brand;
    select>

mapper>

③测试代理方式:

@Test//查看所有
public void testSelectAll() throws Exception {
    //1.加载mybatis的核心配置文件,获取 SqlSessionFactory
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //2.获取Sqlsession对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //3.获取Mapper 接口的代理对象
    BrandMapper brandmapper = sqlSession.getMapper(BrandMapper.class);
    //4.执行方法
    List<Brand> brands = brandmapper.selectAll();

    System.out.println(brands);
    //5.关闭资源
    sqlSession.close();
}
* 参数占位符: 
1.#{}:会将其替换为 ?,为了防止SQL注入
2.${}:直接拼接 sql,存在SQL注入问题
3.使用时机:
    * 参数传递时:#{}
    * 表名或者列名不固定的情况下:${}会存在SQL注入问题

动态SQL

在传统的JDBC的操作中书写SQL语句是非常容易出错的,而Mybatis的动态SQL的出现则很巧妙的解决了这一问题。

其通过 if, choose, when, otherwise, trim, where, set, foreach 标签,可组合成非常灵活的SQL语句,从而大大提高开发效率。

if

Mybatis提供了 if 标签,可以实现针对多个参数进行可选搜索。

test:填入的是能否进行下面SQL语句的判断表达式

<select id="findUserById" resultType="users">
    select * from users 
    where 
        <if test="id != null">
               id > #{id}
        if>
    	<if test="name != null">
        AND name like #{title}
select>

执行的SQL语句是:

select * from users where id > 'xx' and name like 'xxx'

但这样会出现一系列语法问题。

当 id 为空时,and 会直接与 where相连

select * from users where and name like 'xxx'

当 id 和 age 都为空时,where 后面就没有了语句。

select * from users where

很显然,这样会造成运行错误

那么,如何解决上面所说的问题呢?mybatis给出了****元素。

where

<select id="findUserById" resultType="users">
    select * from users 
    <where>
        <if test="id != null">
               id > #{id}
        if>
    	<if test="name != null">
        AND name like #{name}
    where>
select>

where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。

而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

set

<update id="updateUser" parameterType="com.dy.entity.User">
    update user set 
        <if test="name != null">
            name = #{name},
        if> 
        <if test="password != null">
            password = #{password},
        if> 
        <if test="age != null">
            age = #{age}
        if> 
        <where>
            <if test="id != null">
                id = #{id}
            if>
            and deleteFlag = 0;
        where>
update>

从上面这里我们可以发现,如果只有 name 不为空时,SQL语句则变为:

update set name = #{name}, where deleteFlag = 0;

此时 name 后面的逗号 则会导致语法错误。

我们需要用mybatis为我们提供的set 标签来解决这个问题。

<update id="updateUser" parameterType="com.dy.entity.User">
    update user
        <set>
            <if test="name != null">name = #{name},if> 
            <if test="password != null">password = #{password},if> 
            <if test="age != null">age = #{age},if> 
        set>
        <where>
            <if test="id != null">
                id = #{id}
            if>
            and deleteFlag = 0;
        where>
update>

foreach

当接收多个参数时,一个一个写显然过于麻烦,mybatis中的foreach标签可以帮助我们直接遍历数组.

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。

属性 描述
collection 表示集合的名称,默认名为 array,可以使用@Param注解指定, 该参数为必选
item 表示本次迭代获取的元素,若collection为List、Set或者数组,则表示其中的元素;若collection为map,则代表key-value的value,该参数为必选
open 表示该语句以什么开始,最常用的是左括弧’(’,注意:mybatis会将该字符拼接到整体的sql语句之前,并且只拼接一次,该参数为可选项
close 表示该语句以什么结束,最常用的是右括弧’)’,注意:mybatis会将该字符拼接到整体的sql语句之后,该参数为可选项
separator mybatis会在每次迭代后给sql语句append上separator属性指定的字符,该参数为可选项
index 在list、Set和数组中,index表示当前迭代的位置,在map中,index代指是元素的key,该参数是可选项。
<select id="getBlogListByIds" parameterType="map" resultType="com.company.org.pojo.Blog">
    select * from blog
    <where>
        id in
        <foreach collection="ids" item="id" open="(" separator="," close=")">
           #{id}
        foreach>
    where>
select>

上面这个例子的作用是,查询id在ids(列表)中的博客。

相当于sql语句:

select * from blog where id IN (116012859,117374430,118058442)

完结散花

ok以上就是对 动态SQL 的全部讲解啦,很感谢你能看到这儿。如果有遗漏、错误或者有更加通俗易懂的讲解,欢迎小伙伴私信我,我后期再补充完善。

参考文献

https://blog.csdn.net/qq_33369905

你可能感兴趣的:(MyBatis,sql,mybatis,java)