MyBatis源码分析(二)
MyBatis的xml配置(核心配置)
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
MyBatis的Mapper映射
Mapper映射文件只有几个顶级元素(按照应被定义的顺序如下):
cache – 对给定命名空间的缓存配置。
cache-ref – 对其他命名空间缓存配置的引用。
resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
sql – 可被其他语句引用的可重用语句块。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语句
MyBatis也可以使用注解开发
生成代码时候,配置:
<javaClientGenerator type="ANNOTATEDMAPPER"...
生成注解代码,不生成xml代码了
MyBatis开发使用注解还是xml?
方式 | 优点 | 缺点 |
Xml | Xml与接口分离,方便管理,复杂的SQL不影响代码的可读性 | 过多的Xml配置文件 |
Annotation | 接口就能看到SQL语句,可读性强,不需要去找xml文件,方便 | 代码和SQL混杂,复杂一点过于混乱 |
MyBatis批量插入
1 普通for循环(此种方式对于数据库的I/O过于频繁,不适合大数据量的操作)
for (int i = ; i < ; i++) {
user = new User();
user.setId("id" + i);
user.setName("name" + i);
userMapper.insert(user);
}
2 ExeutorType.BATCH(设置批量模式),把SQL语句发个数据库,数据库预编译好,然后数据库等待需要运行的参数,接收到参数一次性运行
session = sqlSessionFactory.openSession(ExecutorType.BATCH, true);
for (int i=; i<; i++) {
UUserInfo userInfo = new UUserInfo();
userInfo.setPhone("1346262122" + i);
userInfo.setUserName("张" + i);
uUserInfoMapper.insert(userInfo);
}
3 传入一个数组或集合,标签<foreach>插入
<foreach item="item" collection="strs.split(',')" separator="," open="(" close=")">
#{item}
</foreach>
方式 | 性能 | 说明 |
For循环 | 性能低,IO高 | |
ExeutorType.BATCH | 性能居中 | |
<foreach>标签拼SQL | 性能最高 |
有SQL长度限制,mysql默认接收SQl的长度为10486576(1M),该方式若超过1M 会抛出异常 |
MyBatis联合查询
一对一关系
在一对一关系中,A表中的一行最多只能匹配B表的一行,反之亦然.这种关系并不常见,因为一般来说,这种关系的信息会保存在一张表中,当然也可以利用一对一关系来保存,比如分割具有多列的表.(如:一个人只有一个身份证)
<association>标签
<resultMap id="OneToOneBaseResultMap" type="com.test.mybatis.model.Person">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="nick" jdbcType="VARCHAR" property="nick" />
<result column="phone" jdbcType="VARCHAR" property="phone" />
<result column="sex" jdbcType="INTEGER" property="sex" />
<association property="idCard" javaType="com.test.mybatis.model.IdCard">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="personId" jdbcType="INTEGER" property="personid" />
<result column="realName" jdbcType="VARCHAR" property="realname" />
<result column="idCard" jdbcType="VARCHAR" property="idcard" />
</association>
</resultMap>
一对多关系
一对多是最普通的一种关系,在这种关系中,A表的一行可以匹配B表中的多行,但是B表中的一行只能匹配A表中的一行.举例:(一个部门可以有多个员工)
<collection>标签
<resultMap type="com.mybatis.bean.Department" id="MyDept">
<id column="did" property="id"/>
<result column="dept_name" property="departmentName"/>
<!--
collection定义关联集合类型的属性的封装规则
ofType:指定集合里面元素的类型
-->
<collection property="emps" ofType="com.mybatis.bean.Employee">
<!-- 定义这个集合中元素的封装规则 -->
<id column="eid" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
</collection>
</resultMap>
多对多关系
在多对多的关系中,A表的一行可以匹配B表的多行.反之亦然.要创建这种关系,需要定义第三张表,也可以称之为结合表或者关系表.它的主键是由A表和B表的外部键组成. 举例(一个用户有多个角色,一个角色可以对应多个用户)
<collection>标签
MyBatis插入并返回主键
方式一:(数据库要设置主键自增长)
<insert id="insertSelective" useGeneratedKeys="true" keyProperty="id" keyColumn="id"
parameterType="com.test.mybatis.model.UUserInfo">
useGeneratedKeys="true"表示使用主键自增 keyProperty="id"表示将主键自增后的主键值赋值给实体类中的id属性
parameterType="com.test.mybatis.model.UUserInfo" 实体类,自增后的主键值将会赋值给该实体类的id属性
方式二:(一般用在<insert>标签里面)
<selectKey keyProperty="id" resultType="integer" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
SELECT LAST_INSERT_ID()表示查询出刚刚插入的的记录自增长id order='AFTER' 表示先执行插入语句,之后再执行查询语句 MyBatis的SQL注入攻击
注入攻击的危害
1:数据库被拖库(把数据从数据库拉取出来,造成数据泄露)
2.重要信息被泄露
注入的本质是把用户输入的数据当做有效代码执行.
Mybatis的预编译机制可以有效防止SQL注入攻击.
'#{}' 和 '${}'的区别:
'#{}':MyBaits会首先对其进行预编译,将#{user_ids}替换成?占位符,然后在执行时替换成实际传入的user_id值,**并在两边加上单引号,以字符串方式处理。
'${}':简单的字符串拼接
栗子:
uUserInfoMapper.selectByIn("select user_name from u_user_info");
where user_name in (${userName})
可使用MyBatis自带循环标签解决SQL语句动态拼接的问题:
select * from news where id in
<foreach collection="ids" item="item" open="("separator="," close=")">
#{item}
</foreach>
MyBatis的自定义类型转换器(实现数据类型和数据库数据类型的映射关系 如:String和VARCHAR的对应关系) 需求:实现对数据库身份证存储的加密
、定义自己的HandlerType实现TypeHandler接口或者继承BaseTypeHandler类
、覆盖其四个方法;
、在核心配置文件mybatis-config.xml中配置<typeHandlers>标签或者在映射文件的增、改、查位置单独配置; <typeHandlers>
<typeHandler javaType="com.test.mybatis.typehandler.UserIdCard" handler="com.bjpowernode.mybatis.typehandler.CryptTypeHandler"/>
</typeHandlers> <result column="idCard" jdbcType="VARCHAR" property="userIdCard" javaType="com.bjpowernode.mybatis.typehandler.UserIdCard"
typeHandler="com.test.mybatis.typehandler.CryptTypeHandler"/> <if test="userIdCard != null">
#{userIdCard, jdbcType=VARCHAR, typeHandler=com.test.mybatis.typehandler.CryptTypeHandler},
</if>
系统自带的类型转换器StringTypeHandler
public class StringTypeHandler extends BaseTypeHandler<String> { @Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
throws SQLException {
ps.setString(i, parameter);
} @Override
public String getNullableResult(ResultSet rs, String columnName)
throws SQLException {
return rs.getString(columnName);
} @Override
public String getNullableResult(ResultSet rs, int columnIndex)
throws SQLException {
return rs.getString(columnIndex);
} @Override
public String getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
return cs.getString(columnIndex);
}
}
MyBatis的动态SQL
if --判断标签
choose (when, otherwise) --多项选择 ,与页面的 jstl 标签非常类似
trim (where, set) --修剪、格式化,添加前后缀的一个标签
foreach --循环
<select id="dynamicChoose" parameterType="News" resultType="News">
select * from news where =
<choose>
<when test="title != null">
and title = #{title}
</when>
<when test="content != null">
and content = #{content}
</when>
<otherwise>
and owner = "zhangsan"
</otherwise>
</choose>
</select>
MyBatis的SQL片段使用
<sql id="Base_Column_List">
id, name
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from user
where id = #{id,jdbcType=INTEGER}
</select>
MyBatis的一级.二级缓存
一级缓存是sqlSession级别,默认开启
二级缓存是mapper级别,默认关闭,缓存命中率低
MyBatis的事务管理:
<transactionManager type="JDBC">
<property name="..." value="..."/>
</transactionManager>
如果你正在使用 Spring + MyBatis,则没有必要配置事务管理器, 因为 Spring 模块会使用自带的管理器来覆盖前面的配置.
MyBatis源码分析(二)的更多相关文章
- mybatis源码分析二
这次分析mybatis的xml文件 1. <?xml version="1.0" encoding="UTF-8" ?> <configura ...
- mybatis 源码分析二
1.SqlSession下的四大对象 Executor.StatementHandler.ParameterHandler.ResultSetHandler StatementHandler的作用是使 ...
- 精尽MyBatis源码分析 - MyBatis初始化(二)之加载Mapper接口与XML映射文件
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- 精尽MyBatis源码分析 - SQL执行过程(二)之 StatementHandler
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- Mybatis源码分析--关联表查询及延迟加载原理(二)
在上一篇博客Mybatis源码分析--关联表查询及延迟加载(一)中我们简单介绍了Mybatis的延迟加载的编程,接下来我们通过分析源码来分析一下Mybatis延迟加载的实现原理. 其实简单来说Myba ...
- Mybatis源码分析之SqlSession和Excutor(二)
通过上一篇文章的分析我们,我初步了解了它是如何创建sessionFactory的(地址:Mybatis源码分析之SqlSessionFactory(一)), 今天我们分析下Mybatis如何创建Sql ...
- MyBatis 源码分析 - 插件机制
1.简介 一般情况下,开源框架都会提供插件或其他形式的拓展点,供开发者自行拓展.这样的好处是显而易见的,一是增加了框架的灵活性.二是开发者可以结合实际需求,对框架进行拓展,使其能够更好的工作.以 My ...
- MyBatis 源码分析 - 配置文件解析过程
* 本文速览 由于本篇文章篇幅比较大,所以这里拿出一节对本文进行快速概括.本篇文章对 MyBatis 配置文件中常用配置的解析过程进行了较为详细的介绍和分析,包括但不限于settings,typeAl ...
- Mybatis源码分析之Cache二级缓存原理 (五)
一:Cache类的介绍 讲解缓存之前我们需要先了解一下Cache接口以及实现MyBatis定义了一个org.apache.ibatis.cache.Cache接口作为其Cache提供者的SPI(Ser ...
随机推荐
- js原型链、继承、this指向等老生常谈却依然不熟的知识点——记录解析
开始记录学习过程—— 很详细的解析过程——https://juejin.im/post/5c72a1766fb9a049ea3993e6 借鉴阅读——https://github.com/KieSun ...
- Spring WebFlux 学习笔记 - (一) 前传:学习Java 8 Stream Api (2) - Stream的中间操作
Stream API Java8中有两大最为重要的改变:第一个是 Lambda 表达式:另外一个则是 Stream API(java.util.stream.*). Stream 是 Java8 中处 ...
- RabbitMQ是什么
1.引入MQ 1.1什么是MQ MQ(Message Quene):翻译为 消息队列,通过典型的 生产者 和 消费者 模型,生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息.因为消息的 ...
- php 常用的redis操作语法
String 类型操作 string是redis最基本的类型,而且string类型是二进制安全的.意思是redis的string可以包含任何数据.比如jpg图片或者序列化的对象 $redis-> ...
- 循环语句&编码了解
循环语句&编码了解 用户交互 input: input接收的内容是str 循环语句 if语句 语法规则: if 条件判断: 代码块1 else ...
- [转] Ubuntu的apt-get 设置代理的方法
点击阅读原文 新立得软件管理器这种图形化的代理设置很明了,这里介绍下终端命令行的网络代理设置,这样大家就可以通过代理进行apt-get了. 方法一: 如果只是想临时使用http代理,可以在使用apt- ...
- 一个简单的CSS登录页
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- linux安装mysql使用yum安装
安装MySQL 安装mysql客户端: yum install mysql 安装mysql 服务器端: yum install mysql-server 至此我就可以使用Yum简单地管理MySQL更新 ...
- C++入门-控制台版的通讯录管理系统
通讯录管理系统 1.系统需求 通讯录是一个可以记录亲人.好友信息的工具. 本教程主要利用C++来实现一个通讯录管理系统 系统中需要实现的功能如下: 添加联系人:向通讯录中添加新人,信息包括(姓名.性别 ...
- winXP vc6行号显示插件-VC6LineNumberAddin方法-可用-无需注册
1.VC6LineNumberAddin 修改日期是2008.6.3可用,其它需要注册码 http://codefish.googlecode.com/files/VC%E6%98%BE%E7%A4% ...