mybatis增强
MyBatis SQL参数传递(掌握)
SQL映射器Mapper接口(掌握)Myb
atis批量操作(理解掌握)
(多对一)关联映射(掌握)
(一对多,多对多)集合映射
MyBatis原理回顾(Object Relational Mapping,简称ORM)
ORM的缺点是会牺牲程序的执行效率和会固定思维模式。
从系统结构上来看,采用ORM的系统一般都是多层系统,系统的层次多了,效率就会降低。ORM是一种完全的面向对象的做法,而面向对象的做法也会对性能产生一定的影响。
在我们开发系统时,一般都有性能问题。性能问题主要产生在算法不正确和与数据库不正确的使用上。ORM所生成的代码一般不太可能写出很高效的算法,在数据库应用上更有可能会被误用,主要体现在对持久对象的提取和和数据的加工处理上,如果用上了ORM,程序员很有可能将全部的数据提取到内存对象中,然后再进行过滤和加工处理,这样就容易产生性能问题。
在对对象做持久化时,ORM一般会持久化所有的属性,有时,这是不希望的。
但ORM是一种工具,工具确实能解决一些重复,简单的劳动。这是不可否认的。但我们不能指望工具能一劳永逸的解决所有问题,有些问题还是需要特殊处理的,但需要特殊处理的部分对绝大多数的系统,应该是很少的。
S(spring)S(springmvc)M(mybatis)集成(掌握)
MyBatis是一个ORM持久化框架,应用到系统持久层(Dao);
一个MyBatis的应用程序都以一个SqlSessionFactory对象(单例)的实例为核心
SqlSession对象完全包含以数据库为背景的所有执行SQL操作的方法
MyBatis是针对数据库交互的一个辅助框架,也是对jdbc做了的简单封装,以xml配置代替Java代码来管理数据库的交互细节!!
MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口(Mapper)和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中一条记录。
MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。
加入mybatis
- MyBatis SQL参数传递
#{OGNL表达式} 和 ${OGNL表达式} 的区别
1.1. #{OGNL表达式}
MyBatis会把这个表达式使用?(占位符)替换,作为一个sql参数使用:推荐使用
比如name的值为:
定义SQL: select * from t_user where name = #{name}
最终SQL: select * from t_user where name = ?
1.2. ${OGNL表达式}
MyBatis会把这个表达式的值替换到sql中,作为sql的组成部分;
该方式主要用于程序拼接SQL;
如果sql中使用${OGNL},并且参数的类型是(integer,string....)那么OGNL表达式可以写成任意东西;
1.3. ${OGNL}表达式的应用场景:
1.3.1. 不能用在登录,会出现sql注入
比如登录功能,在输入name的时候可以人为的制造成功:
User user=new User();
user.setName("\"admin\" or \"1=1\" ");
user.setPassword("\"admin\" ");
定义SQL: select id,name,password from t_user where name = ${name} and password=${password}
最终SQL: select id,name,password from t_user where name="test" or "1=1" and password="test" 出现sql注入
可以用在order by + limit的场景
#{}和${}的使用
resultMap和ParameterMap书写拼写要使用#{},resultType 和parameterType类型使用${},使用例子如下:
Select ID,COMMAND from Message where COMMAND=#{command}
Select ID,COMMAND from Message where COMMAND=‘${command}’
前者解析为:
Select ID,COMMAND from Message where COMMAND=?具有预编译效果
后者解析为:
Select ID,COMMAND from Message where COMMAND=段子 不具有预编译效果
但是,例如当页面向后台传递一个列名(属性名)的时候,是不希望被预编译出一个?的,此时要用到$格式;
如:加上 order by${param} ,此时param是一个列名。
#{}和 ognl表达式
一般参数的拼写还是保证统一风格为好,便于人读。
经常碰到这样的面试题目:#{}和${}的区别是什么?
网上的答案是:#{}是预编译处理,$ {}是字符串替换。mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;mybatis在处理 $ { } 时,就是把 ${ } 替换成变量的值。使用 #{} 可以有效的防止SQL注入,提高系统安全性。
对于这个题目我感觉要抓住两点:
(1)$ 符号一般用来当作占位符,常使用Linux脚本的人应该对此有更深的体会吧。既然是占位符,当然就是被用来替换的。知道了这点就能很容易区分$和#,从而不容易记错了。
(2)预编译的机制。预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。我们知道,SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入。
最后想说的是,对于mybatis 以及 sql 而言,每一个考点背后都是有一个深刻的思想存在的,应该好好的体会。这样才能真正的做到技术提升,成为技术大牛。
这第三个例子虽然说的是#{}和{}通用的问题,也就是说在此种情况下#{}和
{}是通用的,只不过需要些小的转换.如例子中需要手动
拼接单引号 ' ' 到变量值的前后,确保sql语句正常.
简单说#{}是经过预编译的,是安全的,而${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在sql注入.
这里先说一下只能的情况,从我们前面的例子中也能看出,orderby是肯定只能用
{}了,用#{}会多个' '导致sql语句失效.此外还有一个like 语句后也需要用${},简单想一下
就能明白.由于仅仅是简单的取值,所以以前sql注入的方法适用此处,如果我们orderby语句后用了
{},那么不做任何处理的时候是存在sql注入危险的.你说怎么防止,那我只
能悲惨的告诉你,你得手动处理过滤一下输入的内容,如判断一下输入的参数的长度是否正常(注入语句一般很长),更精确写查询一下输入的参数
- SQL映射器Mapper接口
MyBatis基于代理机制,可以让我们无需再编写Dao的实现。直接把以前的dao接口定义成符合规则的Mapper。
Mybatis的批量操作(foreach)
<!-- delete from product where id in ( ? , ? ) 批量删除:
collection="list":传入的list,相当于map的key,通过list得到传入的整个集合的值;
index="index" :每次循环的索引
item="id" :每次循环的这个值
open="(" :以什么开始
separator=",":分隔符
close=")":以什么结束
-->
<delete id="deleteBatch" parameterType="java.util.List">
delete from product where id
in
<foreach collection="list" index="index" item="id" open="("
separator="," close=")">
#{id}
</foreach>
</delete>
<!-- 批量插入:
insert into product(productName,salePrice,costPrice,cutoff,supplier,brand,dir_id)
values (?,?,?,?,?,?,?) , (?,?,?,?,?,?,?)
parameterType:传入参数是:java.util.List的类型的;
对传入的list进行foreach循环:取出值填入插入的values中:
collection="list":这个不能修改,表示传入的一个list类似于一个key是list,得到传入的list集合
index="index":每一次遍历的序号
item="item":每次遍历的这个对象别名,可以修改
separator=",":每遍历一次后的分隔符
-->
<insert id="insertBatch" parameterType="java.util.List">
insert into
product(productName,salePrice,costPrice,cutoff,supplier,brand,dir_id)
values
<foreach collection="list" index="index" item="item"
separator=",">
(#{item.productName},#{item.salePrice},#{item.costPrice},#{item.cutoff},#{item.supplier},#{item.brand},#{item.dir_id})
</foreach>
</insert>
关联映射(多对一)
多对一:
多个员工属于一个部门,domain:在员工这方创建一个部门:在多方有一个外键
一对多:
一个部门有多个员工:Domain:在部门有一个员工list:在多方有一个外键
多对多:
角色和权限:一个角色拥有对个权限,一个权限属于多个角色
Domain:使用list表示:使用中间表维护关系
parameterType ,入参的全限定类名或类型别名
keyColumn ,设置数据表自动生成的主键名。对特定数据库(如PostgreSQL),若自动生成的主键不是第一个字段则必须设置
keyProperty ,默认值unset,用于设置getGeneratedKeys方法或selectKey子元素返回值将赋值到领域模型的哪个属性中
useGeneratedKeys ,取值范围true|false(默认值),设置是否使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。MySQL和SQLServer执行auto-generated key field,因此当数据库设置好自增长主键后,可通过JDBC的getGeneratedKeys方法获取。但像Oralce等不支持auto-generated key field的数据库就不能用这种方法获取主键了
statementType ,取值范围STATEMENT,PREPARED(默认值),CALLABLE
flushCache ,取值范围true(默认值)|false,设置执行该操作后是否会清空二级缓存和本地缓存
timeout ,默认为unset(依赖jdbc驱动器的设置),设置执行该操作的最大时限,超时将抛异常
databaseId ,取值范围oracle|mysql等,表示数据库厂家,元素内部可通过`<if test="_databaseId = 'oracle'">`来为特定数据库指定不同的sql语句
---------------------
作者:零下
mybatis增强的更多相关文章
- Spring Boot (八): Mybatis 增强工具 MyBatis-Plus
1. 简介 在上一篇文章<Spring Boot (七): Mybatis极简配置> 中我们介绍了在 Spring Boot 中 Mybatis 的基础使用方式,其中有一部分美中不足的是 ...
- mybatis增强工具MyBatis-plus
如果你正在用mybatis,那MyBatis-plus你不能错过,配合使用可极大简化开发.提高效率! 简介 MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis ...
- 更便捷的Mybatis增强插件——EasyMybatis
easy-mybatis是一个对Mybatis的增强框架(插件).在Spring集成Mybatis的基础上,将项目开发中对数据库的常用操作统一化.使用本框架可以很便捷的对数据库进行操作,提高开发效率, ...
- MyBatis-Pro,新一代的MyBatis增强框架
框架功能 内置提供基础CRUD方法 提供根据方法名自进行单表查询(包括查询.统计.删除等) 接入方法 Spring Boot <dependency> <groupId>com ...
- Mybatis 增强工具包 Mybatis-Plus
原文:https://www.oschina.net/p/mybatis-plus
- 几种 MyBatis 增强插件
1. mybatis-generator/mybatis-generator-gui 2. 通用mapper 3. mybatis-plus 4. fastmybatis 5. mybatis-enh ...
- SpringBoot+Mybatis 自动创建数据表(适用mysql)
Mybatis用了快两年了,在我手上的发展史大概是这样的 第一个阶段 利用Mybatis-Generator自动生成实体类.DAO接口和Mapping映射文件.那时候觉得这个特别好用,大概的过程是这样 ...
- Mybatis原理和代码剖析
参考资料(官方) Mybatis官方文档: https://mybatis.org/mybatis-3/ Mybatis-Parent : https://github.com/mybatis/par ...
- Mybatis-plus快速入门
简介 MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生. 特性 无侵入:只做增强不做改变,引入它不会对现 ...
随机推荐
- python之基于libsvm识别数字验证码
1. 参考 字符型图片验证码识别完整过程及Python实现 2.图片预处理和手动分类 (1)分析图片 from PIL import Image img = Image.open('nums/ttt. ...
- 这篇文章主要介绍了Citrix XenServer 6.1 安装图解教程
本次为使用VirtualBox虚拟机过安装测试机过程,我们在使用Vm(无论是Vbox还是VMware等)我们的CPU都必须可支持Intel-V或AMD-V,并且在VM软件设置和BIOS设置开启虚拟化支 ...
- 前后台得到WEB应用的名称
前台得到当前应用的名称: ${ pageContext.request.contextPath } 后台得到当前应用的名称: request.getServletContext().getContex ...
- 转载:使用Tornado+Redis维护ADSL拨号服务器代理池
我们尝试维护过一个免费的代理池,但是代理池效果用过就知道了,毕竟里面有大量免费代理,虽然这些代理是可用的,但是既然我们能刷到这个免费代理,别人也能呀,所以就导致这个代理同时被很多人使用来抓取网站,所以 ...
- pandas 数据处理实例
描述:行标签为日期,列标签为时间,表哥的值是 float 的数值# 一. 读取 csv 文件df=pd.read_csv("delay_3.csv",encoding = &quo ...
- 洛谷P1379 八数码难题
传送门 1.先用dfs枚举9!的全排列,存到hash数组里(类似离散化),因为顺序枚举,就不需要排序了 2.朴素bfs,判重就用二分找hash:如果发现当前状态=要求状态,输出步数结束程序 上代码 # ...
- easyui commobox省市区县三级联动
1.前端代码 <div class="col-6 f-group"> <label class="col-4 left_red"> 省名 ...
- HTML5_canvas_图片加载_双缓冲_跳帧闪烁问题
canvas 图片加载 pen.drawImage(ele, showX, showY, imgWidth, imgHeight); ele 将 img 元素 加载到画布上 步骤 1. 创建一个 ...
- 2018-2019-1 20189210 《LInux内核原理与分析》第九周作业
进程的切换和系统的一般执行过程 (1)进程调度的时机 1.schedule是一个内核函数,不是一个系统调用,进程的调度只发生在内核中,进程调度函数schedule()只能在内核中被调用,用户进程无法调 ...
- 23 创建ArcMap启动日志
在ArcMap的启动过程中,我们可以看到软件的界面上分别会显示[初始化许可……].[初始化应用……].[加载文档……]字样,当ArcMap打开出现问题时,我们可以根据以上文字来判断出现错误的情况,还有 ...