MyBits的创建与使用

文章目录

  • 前言
  • MyBits的优点
      • 这里简单回忆下用JDBC的流程
  • MyBits的调用流程
    • MyBits的配置
    • 传递参数之# 与 $ 的区别
  • 当mysql与程序属性映射不一致时的解决方案


前言

上篇博客讲述了 Spring后端与前端进行交互的过程, 而这篇博客将讲述Spring与数据库的交互 , 众所周知 后端与数据库的关系是十分紧密的, 当然数据库也是有框架的 为 MyBits 是基于JDBC开发的

MyBits的优点

  • MyBatis 是⼀款优秀的持久层框架,它⽀持⾃定义 SQL、存储过程以及⾼级映射。
  • MyBatis 去除了⼏乎所有的JDBC代码以及设置参数和获取结果集的⼯作。
  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接⼝和JavaPOJO(Plain Old Java Objects,普通⽼式 Java 对象)为数据库中的记录。

这里简单回忆下用JDBC的流程

① 建立数据源 :DataSource
② 通过DataSource 与数据库进行链接 connection
③ 编写要执行的SQL语句 , 不确定的参数 用 ? 进行占位
④ 通过Connection 与 编写的SQL 语句 创建命令对象 Statement
⑤ 替换Statement 中的占位符 , 用指定的数据类型
⑥ 执行SQL语句 , 查询用 executeQuery(), 增加/ 删除 /修改用 executeUpdate()
⑦ 处理结果集
⑧ 关闭资源 ,从后往前关

MyBits的调用流程

MyBits 主要学习俩方面的内容 , 第一个是老生常谈的配置环境 ,第二个 是学习MyBits的语法 与模式
还记得上文中画的那张图五大类注解的图吗?如下 , 通过这张图 ,可以明显的看出来数据库是与持久层进行交互的 , 持久层主要有俩个 东西来进行交互 ,一个是接口 ,这里面提供给服务层可以调用的接口 , 一个是XML文件用来实现接口 ,同时操作数据库的SQL语句也是在这里面存放的,
在这里插入图片描述

我们学的MySQL数据库是关系型数据库 , 而Mybits 也是一个ORM 框架 ,

ORM 中文意思为 : 对象关系映射 ,意思 是在 : 面向对象的编程语言 中 , 将关系型数据库中的数据 与对象建立起映射关系 ,进而自动的完成 数据与对象的互相转换

MyBits 将输⼊数据(即传⼊对象)+SQL 映射成原⽣ SQL , 将结果集映射为返回对象,即输出对象
映射关系如下 :
数据库表(table)–> 类(class)

记录(record,⾏数据)–> 对象(object)

字段(field) --> 对象的属性(attribute)

MyBits的配置

① 创建一个SpringBoot项目 , 往项目中添加MyBits的框架 , 如下图
MyBits的创建与使用_第1张图片
② 在application配置文件中,添加mysql的配置
MyBits的创建与使用_第2张图片
③配置MyBits的xml的实现接口, 要与配置文件中写的一致

MyBits的创建与使用_第3张图片
④创建接口类与实体类 :
实体类 相当于一张表 ,里面的属性要与数据库中的字段对应
接口内 相当于提供给服务层的使用接口 ,调用接口实际上调用的是XML中的语句
在这里插入图片描述
MyBits的创建与使用_第4张图片

⑤构建Mapper层的代码实现
比如在接口类中写入什么 , 就必须在XML中构造出来 , ID要一致, 传过去的参数也要对应上

这是接口类中写入的
int getArtCountByUid(@Param("uid") Integer uid);
这是XML中写入的

MyBits的创建与使用_第5张图片

其中 #{uid} 代表着动态接受传参 () 这个有俩种写法下面讲)

⑥在服务层调用接口
服务器只需要属性注入相对应的接口类的对象, 然后写一个普通方法提供给控制类使用, 普通方法中调用对应的接口方法即可

MyBits的创建与使用_第6张图片
⑦ 在控制类中调用服务层写的方法 . 写给前端的返回逻辑
MyBits的创建与使用_第7张图片

注 : 这里说一下, 在接口类中传递对象时 , 在XML中赋值使用的是对象的属性
MyBits的创建与使用_第8张图片

传递参数之# 与 $ 的区别

结论: $ 有SQL注入的问题 , 而# 没有
原因: $ 是直接替换语句 ,而 # 是预处理语句
预编译处理是指:MyBatis 在处理#{}时,会将 SQL 中的 #{} 替换为?号
直接替换:是MyBatis 在处理 ${} 时,就是把 ${} 替换成变量的值。

比如 : 这个SQL语句

select count(*) from articleinfo where uid=#{uid} : 这是预处理的做法
select * from userinfo order by id ${sort} : 这是直接处理的做法

${} 是有好处的 : 使⽤ ${sort} 可以实现排序查询,⽽使⽤ #{sort} 就不能实现排序查询了,因为当使⽤ #{sort} 查询时,如果传递的值为 String 则会加单引号,就会导致 sql 错误
但是 ${}同样带来了SQL注入的问题 , 比如

select * from userinfo where username=‘ n a m e ′ a n d p a s s w o r d = ′ {name}' and password=' nameandpassword={pwd}’ 本来我想传递俩个参数来获取信息 ,但是如果传递过来前面路径一致, 后面加上 or 1= 1 , 由于${}是直接替换 , 那么就会绕开前面的判断 , 直接返回结果 , 但我们设置拦截器的想法就是 ,不能随意的返回数据, 这与我们最初的想法起了冲突

结论 : ⽤于查询的字段,尽量使⽤ #{} 预查询的⽅式
这里指出一点: 并不是#{} 就是完美无缺的了 , 它同样有着缺陷 , 比如 #{} 不能处理like 这种模糊匹配查询

select * from userinfo where username like ‘%#{username}%’;

这里面的替换后的效果为给username前后加上单引号, mysql不认这种组织方式 ,结果报错

select * from userinfo where username like ‘%‘username’%’

怎么解决 利用mysql内置的拼接函数解决concat , 用mysql自带的拼接函数不会加上单引号

select * from userinfo where username like concat('%',#{usernam
e},'%');

当mysql与程序属性映射不一致时的解决方案

有时候 ,我们会遇到一种情况就是 , 当mysql中的字段名与程序中的属性值不一致该怎么办?
解决方案 : 利用resultMap 解决 MyBits的创建与使用_第9张图片
这张图中 :
resultMap ID为该映射的标识 (名称) ,
type为 要映射的实体类所对应的路径
下面第一行 ID为主键 后面 property对应的是程序中的属性名
接下来的 result column 对应的都是普通的字段 , 后面代表映射的属性值
在映射结束后, 下面写SQL语句就不会出现问题了
还有一种比这更简单的处理方法就是
使用AS起别名的方式来 解决, 字段和属性值不对应的情况
使用方法 , 在SQL语句查询中 , 起别名为程序中对应的属性即可了,
比如说 id 与 username 是SQL语句中的字段名, 而ID与name 是Java程序中的属性名称

select  id as ID , username as name from articleinfo where uid=#{uid}

当上路流程学完之后 , 已经学会了 如何写SQL语句 , 如何创建对应的实体类 , 如何创建一个使用MyBits的项目, 已经能简单写不复杂的SQL 与 Java程序之间的联动了 , 但是还有一种情况我们没有处理 那就是 : 上面解决了字段名称与属性名字不一致的写法 , 但是多对一的映射关系该如何解决

比如说 :在多表查询时,如果使⽤ resultType 标签,在⼀个类中包含了另⼀个对象是查询不出来被包含的对象类对象, 这种情况就要使用一些特殊的标签来表名 该resultMap的映射关系
比如
⼀对⼀映射要使⽤ 标签,具体实现如下(⼀篇⽂章只对应⼀个作者):association标签加到ResultMap中就可以了

<association property="user"
 resultMap="com.example.demo.mapper.UserMapper.BaseMap"
 columnPrefix="u_">
 </association>

以上使⽤ 标签,表示⼀对⼀的结果映射:
property 属性:指定 Article 中对应的属性,即⽤户。
resultMap 属性:指定关联的结果集映射,将基于该映射配置来组织⽤户数据。
columnPrefix 属性:绑定⼀对⼀对象时,是通过反射来绑定的

⼀对多需要使⽤ 标签,⽤法和 相同,如下所示:

<collection property="alist" resultMap="com.example.demo.mapper.ArticleI
nfoMapper.BaseMap"
 columnPrefix="a_">
 </collection>

MyBits还支持动态SQL语句的编写, 这里给大家了官方网址

动态 SQL 是一种根据程序的当前需要来生成和执行 SQL 语句的方法。它允许在程序运行时动态创建 SQL 语句,根据不同的条件或者用户输入生成不同的 SQL 语句,从而满足不同的查询需求。动态 SQL 更加灵活,可以避免预编译 SQL 语句时固定的执行计划,提高查询效率和灵活性,并且可以防止 SQL 注入攻击。动态 SQL 可以在不同的编程语言和数据库系统中实现。

https://mybatis.org/mybatis-3/zh/dynamic-sql.html

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