MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。 MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatement、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
1、 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
2、 Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
3、 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
4、 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。
SqlMapConfig.xml: mybatis的全局配置文件,配置了mybatis的运行环境等信息。
Mapper.xml: sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在sqlMapConfig.xml中加载。
#{}占位符:占位
如果传入的是基本类型,那么#{}中的变量名称可以随意写
如果传入的参数是pojo类型,那么#{}中的变量名称必须是pojo中的属性.属性名(user.username)
${}拼接符:字符串原样拼接(有sql注入的风险)
如果传入的是基本类型,那么${}中的变量名必须是value
如果传入的参数是pojo类型,那么${}中的变量名称必须是pojo中的属性.属性名(user.username)
注意:使用拼接符有可能造成sql注入,在页面输入的时候可以加入校验,不可输入sql关键字,不可输入空格
注意:如果是取简单数量类型的参数,括号中的值必须为value
例: select * from user where username like '%${value}%'
可以这样写来解决sql注入:select * from user where username like '%’ #{name}’%'(开发经常使用)
注意本程序只是为了理解mybatis的使用,实际开发中可能不这样使用
(并不固定,可以写别的名称)mybatis基本配置
经测验映射文件最好和核心配置文件在一个文件夹下
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
配表与pojo关系,以及sql
id: sql语句的唯一标识,与dao接口中的方法名一致
parameterType:定义输入到sql中的映射类型(请求参数),#{id}表示使用preparedstatement设置占位符号并将输入变量id传到sql。id 可以用任意字符代替并不固定
resultType:定义结果映射类型(返回值)。
注意:当返回值是List集合时他的类型就是泛型的类型
别名 | 映射类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
map | Map |
通过mybatis提供的各种标签方法实现动态拼接sql
原始sql语句:
SELECT * FROM USER WHERE username LIKE '%王%' AND sex= ’2’
Mybatis中简单的sql语句:
前缀'and' 被'(' 替换
prefix:前缀覆盖并增加其内容 不写的话默认替换为空
suffix:后缀覆盖并增加其内容 不写的话默认替换为空
prefixOverrides:前缀判断的条件
suffixOverrides:后缀判断的条件
使用动态sql语句:
向sql传递数组或List, mybatis使用foreach解析,可以做批量处理
Sql语句:
SELECT * FROM USER WHERE id IN (1,10,16)
使用foreach赋值:
foreach:循环传入的集合参数
collection:传入的集合的变量名称(要遍历的值)
item:每次循环将循环出的数据放入这个变量中
open:循环开始拼接的字符串
close:循环结束拼接的字符串
separator:循环中拼接的分隔符
批量修改实例:
sql:
UPDATE rc_notify_queue SET queue_status = 'E',execute_time=NOW() WHERE notify_queue_Id IN (3,22,11)
UPDATE rc_notify_queue SET queue_status = 'E',execute_time=NOW()
#{notify.notifyQueueId}
一个大神朋友写的批量修改:
if标签是与(and)的关系,而 choose 是或(or)的关系。
有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。而使用if标签时,只要test中的表达式为 true,就会执行 if 标签中的条件。MyBatis 提供了 choose 元素。choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的sql。类似于Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。
Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的
将where条件抽取出来:
AND username LIKE '%${username}%'
引用:
注意:也可在sql标签中也可以只放if标签
_parameter : 参数的引用
多表查询返回的数据是两个表中的数据这样就出现了数据封装的问题
解决方案一:创建一个有两个表的数据类
和普通方法是一样的,只是要多创建一个po类
解决方案二:不需要新建po类只要在映射文件中配置:
使用:
Type: po类的权限定名,这里使用的是别名
Id: 主键
Result: 普通属性
Column: po类属性
Property: 表字段名
Association: 引用数据类型
Property: 在po类中的名称
JavaType: 全限定名
分两块,第一块使用resultMap标签封装数据,第二块在select中使用resultMap引用封装好的数据;
这种放法优于第一种方法,第一种方法再写po类增加了工作量,也不便于以后对数据的使用,也不能表现表与表之间的关系
返回结果集类型: resultType="java.util.Map"
查询后返回的结果:List
使用resultMap封装数据
Column就是map集合的key Property数据库传来的数据注意:property值对应数据库中的字段值这种方式只能获取一条数据
SqlMapConfig.xml配置:
其余交个spring管理
ApplicationContext.xml
配置dataSource
配置sqlSessionFactory
原生Dao实现:原生Dao实现和普通类的配置一样
Mapper接口代理:
方式一:
注意:
Bean标签中class属性是mybatis提供的接口代理对象所以是固定的
name="mapperInterface"和name="sqlSessionFactory" 代理对象中的属性也是固定的
方式二:包扫描
注意:
使用包扫描的方式批量引入Mapper扫描后引用的时候可以使用类名,首字母小写.
指定要扫描的包的全路径名称,如果有多个包用英文状态下的逗号分隔