【JavaEE】MyBatis框架要点总结(2)
文章目录
- 【JavaEE】MyBatis框架要点总结(2)
- 1. 单表查看操作
- 1.1 (条件查询)通过id查找用户
- 1.1.1 接口上声明方法
- 1.1.2 xml文件中去实现方法
- 1.1.3 测试
- 1.2 传递参数的重点问题:sql注入问题
- 1.2.1 ${}方式
- 1.2.2 #{}方式
- 1.2.3 必须用到${}的情景
- 1.2.4 ${}和#{}的区别和注意事项
- 2. 简单的增删改操作
- 2.1 修改操作
- 2.2 删除操作
- 2.3 增加操作
- 3. 模糊匹配like
- 4. 常见疑问
- 4.1 返回对象的属性名与字段名对应不上
- 4.1.1 修改成一致
- 4.1.2 重命名列名
- 4.1.3 返回字典
- 4.1.4 注解TableField
- 4.2 sql关键字作为属性名
- 4.3 传入的参数是多个对象
在上一篇文章中,我们主要讲解的内容就是MyBatis是什么,MyBatis环境的搭建,简单地体验了MyBatis的写法去查询数据库
而本文的内容就是,MyBatis更深入的讲解,以及更多的数据库操作,如增删改查…
**知道怎么进行开发,这才是重点!**之后再去了解一下xml文件去实现接口的一些原理~
参数最好不要写基本数据类型,这是因为前端不传参数过来的话,可以传默认值
- 服务器报错,服务器并不会关闭,只是捕捉到了异常打印了日志
对象中的成员是基本数据类型除外:
只有null表示真正意义的空
这个@Param注解的作用就是,确定这个参数替换到sql语句的哪~
返回规则:根据返回的信息,也就是一张结果表,列名对应属性名
接口内就不报错了:
${id}
,这个花括号里的id对应的就是那个参数的注解括号里面的值
${}
的方式去写,原理就是简单的字符串拼接,所以如果传递的是字符串的话,还得自己传引号过去,比较麻烦不加注解,那么它对应的就是参数的名字,但是不是所有的电脑都适合这种写法,而注解则是所有人都适合
select * from userinfo where id = null
,显然是错误的,那么后端就会传500的响应,代表服务器出现异常,在前端就会被ajax的error属性接受,没被success接受,那么这次请求就相当于失效了Postman中发送请求:
前端不传id过去,Integer就为空:
sql注入是什么?
${} 和 #{} 有什么区别?
这是MyBatis中很常见的面试题!
可见这是一种简单的替换,可以理解为字符串拼接,也就是说,字符串类型的数据我们要手动加引号:
以用户名查找用户为例:
效果:
但是如果不加双引号:
就会报错,这个是sql语句执行失败的意思~
- (我们之前的一个配置让sql执行就打印相关日志)~
并且,字符串拼接的话,就会出现影响原sql语句结构的问题,即sql注入问题:
例如传的字符串是这样的:
sql语句变为:
那么,就可能会出现危险的一种情况,就是改变原sql语句的结构,然后多加一条sql语句,对数据库进行攻击!
轻则sql语句因为非法而失效,服务器报500
重则:
总之,可以 巧妙地设计 出很多==危险的sql语句==
也就是说,${}
是**即使执行的,比较危险!**
例子:
- 用户登录密码错误仍能登录成功:
恶意传参:
- 不需要密码也能登录
服务器的日志:
而这个方式对应就不会出现这个问题:
查看日志:
这也就是 之前JDBC的 ? 占位符,然后用参数【value替换】的思想,也就是username的值就是这个String类型的值,id就是这个Integer类型的值
【可以这么理解】:String类型默认加引号,并且字符串内部的每一个字符都是用其unicode码的转义代替,内部在代码看来就是只是存粹的数据,没 有引号的概念,自然不会出现引号将字符串分割而导致的错误
- mybatis这一点就省去了原本的繁琐步骤,因为传过来的参数就能决定是setInt还是setString了…
底层帮我们去正确地赋值(避免了手动对字符串类型加引号的过程,也保证了不会出现添加字符串是危险sql语句而导致数据库被恶意影响的情况出生,因为只会被看成一个整体,一个普通的字符串的内容而已)~
- 所以#{}也可以完成一些奇葩字符串的保存进表里,例如
"''"'""'
,这种字符串如果拼接的话,很有可能会错(因为外部引号包裹的规定)- 但是#{}会把这个看成整体,就跟普通字符串除了值不同外没啥区别,就是一坨二进制数据,并不会有所影响
所以,#{}
是 预执行的,比较安全!
那么${}
这么危险,为什么还存在呢?
#{}
无法实现的一个典型的例子就是:
select * from userinfo order by id ${option};
在sql后面如果是desc,就是逆序;如果是asc或者啥也没有,就是顺序~
效果:
日志:
日志:
空字符串也可以:
${}
可以实现的,#{}
基本都能实现,所以能用#{}
就用#{}
${}
是及时执行的,而#{}
是预执行的,可以防止sql注入的问题${}
巧妙地构造出危险的sql语句${}
也是有使用场景的,在传参的值是sql语句的本体的一部分/关键字的时候,则必须使用${}
#{}
,被字符串替换,代表的含义一定是“值”而不是关键字,跟不能被认定为sql语句本体的一部分(可以理解为带了引号)${}
是不安全的,所以应该为${option}
提供有限个选项(可枚举的),不能有用户自主输入传递的字符串,而是选择,并且这些选项不能让sql语句最终是危险的!
对于这三个操作,语句的返回值一定是int型的“受影响行数”
我想,你现在有很多想法,试着根据刚才这些规则去实现吧!
测试:
将username为ad的用户的state置为0:
查看数据库:
测试:
数据库:
目前我们的知识只能运行我们固定的去传值:
insert into userinfo (username, password) values('张三', '123456')
我的意思就是,这一段是我们写死了的:
不能根据实体类值的属性而决定,如属性值为空则添加的时候不设置,不为空则这里就会设置,因为我们现在是sql结构写死了的静态sql,所以无法实现这种情况,等待下一篇文章“动态sql”的学习!
效果:
数据库中:
补充:
- 有时候我们增加完成之后,是需要用到自增id的~
- 因为这个自增id我们不需要自己去设,自然不知道它的值(如果不查表的话)
- 也就是说我们传递的对象id属性是null值(一般情况下我们传递的是实体类对象,而不是一个个参数,即使如此,也应该有id参数)
例如:提交博客后,跳转到刚才的博客的详情页里;或者注册用户信息后,跳转到主页(省略一次登录)
- 这些功能就需要这个自增id~
写法:
- 设置useGeneratedKeys
- 意思就是“使用 自主生成的 键值对”,为true,否则框架不会在sql执行后专门返回这个键值对,我们目前知道的自增键值对就是我们的自增主键!
- 设置映射关系,keyColumn和keyProperty
- 也就是让自增主键返回到哪里
- keyColumn为列名
- keyProperty为赋值给对象的哪个属性的属性名
测试:
这个UserInfo对象参数,身兼数职
根据我们目前的理解,应该写成这样:
测试:
命令行报错:
原因可想而知,就是因为预执行的问题,导致的语法错误
这么说的话那么“拼接sql”,及时执行的${}
可以解决咯?
我们可以用mysql中的concat(字符串拼接)方法来有效解决这个问题!
#{}
了~效果:
查看日志:
疑问:为什么有时候一些字段是存在值的,但是属性却是null值?
这里提供几个解决方案:
其实这种对应不上的问题,在一开始写代码的时候规定下来就完事了,统一一下命名就行了,也就是写代码的时候规范一点,一般就不会出现
但是,有时候重复利用一段代码作用于另一个是实体类的时候,确实可能会出现这种情况~
这是个简单直接的代码,就是改变定义咯, name变为username
如果用了@Data 注解,修改定义就比较简单,改属性名后方法会自动重新定义
这也是比较有效的方法,利用的原理就是:
也就是说,属性名和列名对应的上,也是可能出现属性名没有被赋值的情况的:
所以就可以通过重命名的方式来展现:
通过定义resultMap的,将属性名和字段名进行手动规定的映射
resultMap的定义:
- 含义就是,返回UserInfo对象,对这个对象进行手动赋值,或者叫做手动建立映射关系
select标签定义:
效果:
如果啥也没有,就跟之前的写法一致:
不过这个注解来自MyBatisPlus框架的,使用方法如下:
@TableField("username");
private String name;
这样就可以建立对应关系了~
不过MyBatis plus 我暂不讲解,感兴趣的同学可以去了解一下~
疑问:会不会因为需要反引号去包起来属性名,才能正确的返回值?
如果是在sql语句中写字段名,那么就需要 反引号` 去包起来;
如果是作为返回值赋值给对象的属性的话,因为显示出来的列名本来就没有反引号
测试表:
测试:(代码省略)
写代码是根据实际情况的,传入多个自定义对象作为参数很不合理!
不要制造没有意义的冲突!
我们要学的是正常的开发所用到的,而不是去研究一些奇葩的特殊情况的现象是咋样的,咋处理的,这样写会咋样,这样的不常规写法会咋样,研究这些作死一点的写法,返回的结果是咋样,这些都没意义!写正常的代码就行了!
文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭!代码仓库:mybatis_demo · 游离态/马拉圈2023年8月 - 码云 - 开源中国 (gitee.com)