Mybatis 快速入门(四)🚩

826 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情

写在前面👀

承接上文,Mybatis 快速入门(二)☁ Mybatis 快速入门(三)🚀

今天主要讲讲动态SQL的选择条件动态查询主键返回

一、动态SQL

手动拼接SQL语句是一件非常痛苦的事,动态 SQL 可以减少编写代码的工作量,体现了 MyBatis 的灵活性、高度可配置性和可维护性

  • 动态SQL标签概述表👇
元素作用备注
if判断语句单条件分支判断
choose、when、otherwise相当于 Java 中的 switch case 语句多条件分支判断
trim、where辅助元素用于处理一些SQL拼装问题
foreach循环语句在in语句等列举条件常用
bind辅助元素拼接参数,模糊查询
  • if和where标签比较容易,所以我就简单讲一下。

1️⃣if标签

  • MyBatis if 类似于 Java 中的 if 语句,是 MyBatis 中最常用的判断语句。

a.语法

  • 当判断条件为 true 时,才会执行所包含的 SQL 语句
<if test="判断条件">
    SQL语句
</if>

b.示例

<!--    根据姓名模糊查询-->
<select id="searchAllByName" resultMap="OpResultMap">
    select *
    from tb_op
    <if test="name != null and name != ''">
        where name like CONCAT('%', #{name}, '%')
    </if>
</select>

2️⃣where标签

  • where 标签主要用来简化 SQL 语句中的条件判断,可以自动处理 AND/OR 条件,避免了多条件查询时 WHERE 1=1 的尴尬

a.语法

  • where 标签经常和if标签放在一起用,if 语句中判断条件为 true 时,where 关键字才会加入到组装的 SQL 里面,否则就不加入。where 会检索语句,它会将 where 后的第一个 SQL 条件语句的 AND 或者 OR 关键词去掉。
<where>
    <if test="判断条件">
        AND/OR ...
    </if>
</where>

b.示例

<!--    根据id和赏金查询记录-->
<select id="searchByIdAndReward" resultMap="OpResultMap">
    select *
    from tb_op
    <where>
        <if test="id != null and id != 0">
            and id <![CDATA[>]]> #{id}
        </if>
        <if test="reward != null">
            and reward <![CDATA[>]]> #{reward};
        </if>
    </where>
</select>

二、选择条件动态查询

0️⃣需求

在查询时只能选择性别果实能力身份这三个条件中的一个,或者一个条件都不选,查询默认的数据

  • 这种需求可以用choose(when,otherwise)标签

1️⃣choose-when-otherwise 语法

  • 类似于Java中的switch-case-default

  • choose 标签按顺序判断其内部 when 标签中的判断条件是否成立,如果有一个成立,则执行相应的 SQL 语句,choose 执行结束;如果都不成立,则执行 otherwise 中的 SQL 语句。

<choose>
    <when test="判断条件1">
        SQL语句1
    </when >
    <when test="判断条件2">
        SQL语句2
    </when >
    <when test="判断条件3">
        SQL语句3
    </when >
    <otherwise>
        SQL语句4
    </otherwise>
</choose>

2️⃣编写接口方法

/**
  * 5.在性别、果实、身份三个条件中,选择条件查询
  * @param op
  * @return List<Op>
  */
List<Op> searchByChoose(Op op);

3️⃣编写映射文件

<!--在性别、果实、身份三个条件中,选择条件查询-->
<select id="searchByChoose" resultMap="OpResultMap">
    select *
    from tb_op
    where 1=1
    <choose>
        <when test="gender != null and gender != ''">
            and gender = #{gender};
        </when>
        <when test="devilFruit !=null and devilFruit != ''">
            and devil_fruit like concat('%',#{devilFruit},'%') ;
        </when>
        <when test="identity != null and identity != ''">
            and identity like concat('%',#{identity},'%') ;
        </when>
        <otherwise>
            and id=1;
        </otherwise>
    </choose>
</select>

4️⃣编写测试方法

@Test
/**
  * 5.在性别、果实、身份三个条件中,选择条件查询
  */
public void testSearchByChoose() {
    //三个条件都未选择,默认查询id为1的记录
    String gender = null;
    String devilFruit = null;
    String identity = null;
    //5.1创建Op对象
    Op op = new Op();
    //5.2调用方法封装对象
    op.setGender(gender);
    op.setDevilFruit(devilFruit);
    op.setIdentity(identity);
    System.out.println(op);
    //5.3执行方法
    List<Op> opList = opMapper.searchByChoose(op);
    for (Op opValue : opList
        ) {
        System.out.println(opValue);
    }
    //5.4释放资源
    sqlSession.close();
}
  • 演示结果如下👇

image-20220420221310906

三、Insert, Update, Delete 元素属性

属性描述
id在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
flushCache将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:(对 insert、update 和 delete 语句)true。
timeout这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。
statementType可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
useGeneratedKeys(仅适用于 insert 和 update)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段),默认值:false。
keyProperty(仅适用于 insert 和 update)指定能够唯一识别对象的属性,MyBatis 会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值,默认值:未设置(unset)。如果生成列不止一个,可以用逗号分隔多个属性名称。
keyColumn(仅适用于 insert 和 update)设置生成键值在表中的列名,在某些数据库(像 PostgreSQL)中,当主键列不是表中的第一列的时候,是必须设置的。如果生成列不止一个,可以用逗号分隔多个属性名称。
databaseId如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有不带 databaseId 或匹配当前 databaseId 的语句;如果带和不带的语句都有,则不带的会被忽略。

四、添加数据-主键返回

0️⃣需求

添加数据,并且在数据添加成功后,要获取插入数据库数据的主键

  • 要满足需求,可以在insert 标签上添加如下属性🏴‍☠️
    • useGeneratedKeys:能够获取自动增长的主键值。默认是false,true表示获取
    • keyProperty :指定将获取到的主键值封装到哪儿个属性里

1️⃣编写接口方法

/**
  * 6.添加数据并返回主键
  * @param op
  * @return void
  */
void addAllOps(Op op);

2️⃣编写映射文件

<!--    添加数据并返回主键-->
<insert id="addAllOps" useGeneratedKeys="true" keyProperty="id">
    insert into tb_op (name, gender, devil_fruit, reward, identity)
    values (#{name}, #{gender}, #{devilFruit}, #{reward}, #{identity});
</insert>

3️⃣编写测试方法

@Test
/**
  * 6.添加数据并返回主键
  */
public void testAddAllOps() {
    //添加数据
    String name = "马尔科";
    String gender = "男";
    String devilFruit = "鸟鸟果实-幻兽种-不死鸟形态";
    Long reward = 1374000000L;
    String identity = "海贼";
    //6.1创建Op对象
    Op op = new Op();
    //6.2调用方法封装对象
    op.setName(name);
    op.setGender(gender);
    op.setDevilFruit(devilFruit);
    op.setReward(reward);
    op.setIdentity(identity);
    //6.3执行方法
    opMapper.addAllOps(op);
    //6.4调用getter方法获取主键
    Integer id = op.getId();
    //6.6根据返回的主键值查询相关信息
    System.out.println(opMapper.searchById(id));
    //6.7释放资源
    sqlSession.close();
}
  • 演示结果如下👇

image-20220420230032421

写在后面🍻

感谢观看啦✨
有什么不足,欢迎指出哦💖
掘金的运营同学审核辛苦了💗