MyBatis - 基础使用Ⅰ

这篇文章将讲解MyBatis的基础使用,MyBatis的学习是非常重要的,在前面学习servlet的时候,我们就能感受到将数据持久化存储的重要性,当时在使用JDBC的时候非常繁琐麻烦,但是在Spring里,提供了一种框架可以轻松且惬意的实现数据存储的功能:MyBatis。

MyBatis的学习只分为俩部分:1.配置MyBatis的环境 2.设置配置信息

1.MyBatis的环境搭建

        在Spring里的MyBatis因为依靠SpringBoot实现的,因此使用MyBatis的话,环境搭建如下:

在依赖注入里面引入这俩依赖,MyBatis配置就完成了 

2.设置MyBatis的配置信息

        2.1 设置数据库连接的相关信息

在application中进行:

 

如果使⽤ mysql-connector-java 是 5.x 之前的使⽤的是“com.mysql.jdbc.Driver”,如果是⼤于 5.x使⽤的是“com.mysql.cj.jdbc.Driver”

        2.2 设置MyBatis的xml保存路径和命名方式

 这时候 环境就搭建完成咯~~
 

3.Mybatis基本使用

 上图来看 每个Mybatis的使用(命令)包括俩个组件:Inteface和xml,Interface是供Controller使用的接口,而xml就是sql语句放在这里,但是xml怎么实现接口的方法呢?Mybatis通过代理的方式:生成一个代理对象:会将interface方法的声明和xml方法的实现组成一个代理对象,进行填充。这里可以用一个例子来解释,你有一个苹果手机和一个安卓数据线,这时候你无法进行充电,但是如果说有一个转换头,就可以实现充电的功能,这个转换头就是Mybatis,将Interface和xml进行组合变成一个虚拟对象,就可供其他类或者方法进行调用了。

        Mybatis有俩部分组成:Inteface(让其他层进行调用/注入) 和 xml(提供了具体的实现sql语句)

        我们想要从数据库里获取数据到页面上,我们就需要做以下步骤:

由于在xml文件中已经规范了Mybatis的保持路径和命名规范了,因此:

xml文件: 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
    <select id="getAll" resultType="com.example.demo.entity.UserEntity">
        select * from userinfo
    </select>
</mapper>

select标签内 id 是方法名字,resultType 是返回的类所在的位置。

如果我们想不通过输入网址的方式来实现测试功能的话,我们就要涉及到单元测试的相关知识了

接下来简单讲一下单元测试的使用方法:

4.单元测试基础使用

        由于在Spring里内置了相关单元测试的框架,因此在使用单元测试的时候,我们就不必再引入一个新的依赖了,具体使用如下:

        

 @SpringBootTest的注解表明当前的类还是在Spring上运行的

 那就写一个按id查询返回操作的代码吧:

在接口的代码中,关于传参还是要用到注解,这里的@Param注解内部写的“id”意思是把你传入的参数id命名为id存进spring中(换句话说存到了MyBatis中)。

         4.2 获取动态参数

        在xml文件中的sql语句里我们在设置条件的时候 用到了 ${} 这样的形式来获取动态参数,这里其实就是直接替换的方式,啥意思呢?就是直接将 id = 后面的值直接更换成在Spring中存取的id的值,还有一种方式 是 #{} ,它的意思是先写成 id = ? 的形式,就是先用个占位符,然后再替换值,二者有啥区别?

        正如上面的代码,因为是id数值型数据,我们无法感知到啥区别,但如果传递的参数是String的呢?用直接替换的方式的话,需要在外面加上个 ' ',因为sql语句进行存在String操作的时候需要加上单引号,而直接替换的方式,无法进行自动加' ' ,#{}则不同,先使用的是占位符,然后识别到String 再进行替换,替换的时候就相当于自动加上了' '

在 MyBatis 中,#{} 和 ${} 都是用于 SQL 语句中的变量替换,但它们的使用方式和作用是不同的。

#{} 主要用于向 SQL 中传递参数,可以防止 SQL 注入攻击。在 SQL 执行前,MyBatis 会将 #{} 替换成一个占位符 "?", 然后使用 PreparedStatement 进行预编译,最终执行 SQL 语句时将参数值设置到占位符中。因此,使用 #{} 可以提高 SQL 执行的安全性和效率。

例如:SELECT * FROM user WHERE id = #{id}

${} 主要用于替换 SQL 语句中的表名、列名等部分,不能防止 SQL 注入攻击,不会对参数进行预编译处理。在 SQL 执行前,MyBatis 会直接将 ${} 替换成变量的值,然后与其他 SQL 文本一起拼接成最终的 SQL 语句。因此,使用 ${} 可以方便地构造动态 SQL,但同时也带来了安全隐患。

例如:SELECT * FROM ${tablename} WHERE id = ${id}

总结一下,#{} 主要用于传递参数,防止 SQL 注入攻击;${} 主要用于替换 SQL 语句中的表名、列名等部分,方便构建动态 SQL,但存在 SQL 注入风险

如果是排序查询的话,那就只能使用${},因为如果是使用占位符的形式的话,因为spring识别到 #{}里面的数据是String类型,在替换的时候,会在外面加上个' '(sql),无法进行正常的排序查询。 

5.增删改操作

        5.1修改操作

         5.2 删除操作

        5.3 增加操作

        5.3.2 返回id的增加操作 

在xml文件修改一下

6. 查询操作

        6.1 单表查询

        查询特定Id的userinfo表:

         6.2 模糊查询

        模糊查询就是在sql语句中使用了like关键字,但是我们如果直接使用 #{}  的话会出问题的,因为先将目标位置替换之后,因为要替换的是String类型, 替换之后会出现  like ' ... '  的形式~~

         这时候sql中一个concat函数就能够有效的帮助我们。

        虽然在增删改操作可以不设置返回的数据类型,返回一个受影响的行数就ok了,但是在查询操作中,必须是要设置返回的类型是啥,我们至今使用的是resultType ,resultType在使用的时候是非常方便的,直接指明你要返回的类型是哪个类,但是如果是实体类中的数据名称,与sql语段的名称,直接使用resultType似乎鸡肋了~~,这时候resultMap就大显神威了。

        6.3 resultMap

 我们先将实体类中的password改成pwd,使用上面BaseMap也能正常运行。

 

         6.2 多表查询

                6.2.1 一对一

        想象一下场景:我们想获取文章表的数据并且在数据里面有用户表的username属性。

     这样就ok了。

         6.2.2 一对多

        我们再假设个场景:当你输入一个uid也就是文章表的用户id,就查询到该用户的所有文章。

7. 动态SQL

        先讲讲为什么用动态sql吧:

使用动态 SQL 可以让 SQL 语句更加灵活、可维护和易于扩展。具体来说,动态 SQL 的优点包括:

  1. 条件分支:动态 SQL 可以根据不同的条件拼接不同的SQL语句,从而实现不同的查询需求,这比使用多个固定 SQL 的方式更加灵活。

  2. 参数化:动态 SQL 可以使用参数化语法,从而可以避免 SQL 注入攻击,并且可以减少 SQL 执行计划的生成次数,提高 SQL 的执行效率。

  3. 可维护性:使用动态 SQL 可以将 SQL 语句拆分成多个小段,每个小段都有明确的含义和作用,这样就方便后期维护和修改,而不必修改整个 SQL 语句。

  4. 可复用性:使用动态 SQL 可以将多个相似的 SQL 语句抽象成一个通用的 SQL 模板,不仅可以减少代码量,还可以提高代码复用性。

总之,使用动态SQL可以让开发者更加简便地编写 SQL 语句,并且可以在不牺牲性能的情况下提高系统的灵活性、可维护性和可扩展性。

        7.1 if标签

         这里常见的适用场景是在我们进入用户信息填写的时候,有的信息是必填也有的是不必填的,那些不是必须要填的,我们往往会空着,意思是就是在insert语句中values后面的值没有他就ok了,那这种类似条件判断的实现就要靠if标签实现了。

我们设计一下添加用户表的场景 具体代码如下:

         7.2 trim标签

注意下面的代码,trim标签里面prefix的意思是这个整体前面加个  "("   suffix则是在结尾处加个 ")"

而suffixOverrides则是去掉最后面的元素(指的是在 )前面的元素),意思就是如果说pwd不为空传进去的话,此时会加上   “  ,” 就会报错,实现suffixOverrides的话就可以避免这种情况了。

        7.3 where标签

        当然有了上面的trim标签似乎也可以实现动态的trim标签就是删除多的元素嘛,开头加个where就ok了,但是还有更简单的方式去实现动态where,那就是where标签。

        实现一个 :你可以传与不传username和id,根据你传还是没传具体的数据来查询表结构。

    <select id="getByDiy" resultType="com.example.demo.entity.UserEntity">
        select * from userinfo
        <where>
            <if test="username != null">
                and username = #{username}
            </if>
            <if test="id">
                and id = #{id}
            </if>
        </where>
    </select>

        7.4 set标签

        一样的道理,set标签相当于是trim简化版~~但需要注意的是where默认是删除前面的,set是默认删除后面的多余的字符。

        7.5 foreach标签

单元测试代码

    //加个事务标签进行回滚操作
    @Transactional
    @Test
    void delByList() {
        List<Integer> list = new ArrayList<>();
        for(int i = 0; i < 2;i++){
            list.add(i);
        }
        articleMapper.delByList(list);
    }

xml文件

    <delete id="delByList">
        delete from articleinfo where id in 
        <foreach collection="list" item="item" open="(" close=")" separator=",">
            #{item}
        </foreach>
    </delete>

接口/声明方法

    int delByList(List<Integer> list);

        collection表明的是具体的传过去的参数集合,item就是遍历时的每一个对象,open、close就是开头结尾加上这俩东西,separator则是自动的在自动的检测添加,给遍历的对象。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值