目录
主要参考:
https://blog.csdn.net/a745233700/article/details/80977133
1、Mybatis作用
- 概念:对象关系映射框架。(做POJO和数据库的映射。 POJO<----->数据库)
- 作用:在使用数据库的时候,只需要关注SQL语句本身的逻辑,程序员可以直接编写原生态SQL语句去操作数据库。不再需要再手动去做JDBC的全套工作(处理加载驱动、创建连接、。。。等等这些不是本文的重点,略)
- 工作方式:通过xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过java对象和 statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。(从执行sql到返回result的过程)。即 (生成sql语句(配置要执行的statement ,映射) --- 执行sql语句 ---返回sql执行结果(返回形式为java对象,POJO))
2、优缺点和适用场景
优点:
这个只好通过使用来理解记忆了,总之主要特点是:
- 灵活轻便;
- 兼容性好;
(1)基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
(2)与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;
(3)很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。
(4)能够与Spring很好的集成;
(5)提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
缺点:
- SQL语句需要一定要求;
- 依赖于数据库,因此移植性差。
(1)SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。
(2)SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
适用场合:
- 灵活的DAO层解决方案;
- 对性能的要求较高、需求变化较多的项目。如互联网项目
3、Mybatis和Hibernate的区别
Mybatis | Hibernate | |
SQL | 需要程序员手动编写 | |
数据库无关性 | 差 | 较好 |
(1)SQL语句。Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句。
(2)数据库无关性。
- Mybatis直接编写原生态sql,可以严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一但需求变化要求迅速输出成果。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套sql映射文件(一个sql映射文件 -- 一个数据库),工作量大。
- Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用hibernate开发可以节省很多代码,提高效率。
4、Mybatis如何防止SQL注入?
一句话:Mybatis通过SQL预编译防止SQL注入。
例子:
- 首先书写SQL语句,用#{}修饰具体数据
<select id="selectByNameAndPassword" parameterType="java.util.Map" resultMap="BaseResultMap"> select id, username, password, role from user where username = #{username,jdbcType=VARCHAR} and password = #{password,jdbcType=VARCHAR} </select>
- 执行前,Mybatis会把如下这个SQL送给数据库预编译(使用占位符 " ? ")
注:SQL注入就发生在编译过程中,而Mybatis的预编译是没有具体的数据的,只是占位符。所以能够防止注入。
select id, username, password, role from user where username=? and password=?
- 执行SQL语句时,直接使用编译好的SQL,替换占位符“?”
这里贴一篇文章 https://www.cnblogs.com/mmzs/p/8398405.html,可以参考理解
1)在书写SQL语句的时候,使用两种特殊语法(#和$)
#{} (井号) | ${} (美元) | |
安全性 | 经过编译的,安全 | 未经过编译,只是取变量的值,不安全 |
生成sql语句 | #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。 eg: where username=#{username} 如果传入的值是111,那么解析成sql时的值为 where username="111"
如果传入的值是id 则解析成的sql为where username="id". | $将传入的数据直接显示生成在sql中。 eg: where username=${username} 如果传入的值是111, 那么解析成sql时的值为 where username=111; |
能够防止SQL注入 | 能够有效防止 | 无法防止 |
注意:
- 一般能用#的就别用$,若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止sql注入攻击。
- 在MyBatis中,“${xxx}”这样格式的参数会直接参与SQL编译,从而不能避免注入攻击。
- 但涉及到动态表名和列名时,只能使用“${xxx}”这样的参数格式。所以,这样的参数需要我们在代码中手工进行处理来防止注入。
【结论】在编写MyBatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止SQL注入攻击。