MyBatis框架
尚硅谷java研究院
版本:V 1.0
1)MyBatis是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation 迁移到了Google Code,随着开发团队转投Google Code旗下, iBatis3.x 正式更名为MyBatis ,代码于2013年11月迁移到Github
2)iBatis一词来源于"internet"和"abatis"的组合,是一个基于Java的持久层框架。 iBatis 提供的持久层框架包括SQL Maps和Data Access Objects(DAO)
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录
半自动ORM(Object Relation Mapping`)框架
SQL夹在Java代码块里,耦合度高导致硬编码内伤
维护不易且实际开发需求中sql是有变化,频繁修改的情况多见
长难复杂SQL,对于Hibernate而言处理也不容易
内部自动生产的SQL,不容易做特殊优化
基于全映射的全自动框架,大量字段的POJO进行部分映射时比较困难。导致数据库性能下降
对开发人员而言,核心sql还是需要自己优化
sql和java编码分开,功能边界清晰,一个专注业务、一个专注数据
https://github.com/mybatis/mybatis-3/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1PFS411W-1599703793287)(media/image1.png)]{width=“5.141510279965004in” height=“2.6034722222222224in”}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sx0XBz3H-1599703793289)(media/image2.png)]{width=“5.537738407699037in” height=“0.9722222222222222in”}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qt3FA6BS-1599703793291)(media/image3.png)]{width=“4.839622703412074in” height=“2.5748468941382328in”}
±--------------------------------------+
| > myBatis-3.4.1.jar |
| > |
| > mysql-connector-java-5.1.37-bin.jar |
| > |
| > log4j.jar |
±--------------------------------------+
±--------------------------------------------------------------------------------------------+
| |
| |
| |
| |
|
| |
|
| |
| |
| |
|
| |
| |
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
±--------------------------------------------------------------------------------------------+
±---------------------------------------+
| – 创建库 |
| |
| CREATE DATABASE test_mybatis; |
| |
| – 使用库 |
| |
| USE test_mybatis; |
| |
| – 创建表 |
| |
| CREATE TABLE tbl_employee( |
| |
| id INT(11) PRIMARY KEY AUTO_INCREMENT, |
| |
| last_name VARCHAR(50), |
| |
| email VARCHAR(50), |
| |
| gender CHAR(1) |
| |
| ); |
±---------------------------------------+
±--------------------------------------------------------------------------------------------------------------------------+
| public class Employee { |
| |
| private Integer id ; |
| |
| private String lastName; |
| |
| private String email ; |
| |
| private String gender ; |
| |
| public Integer getId() { |
| |
| return id; |
| |
| } |
| |
| public void setId(Integer id) { |
| |
| this.id = id; |
| |
| } |
| |
| public String getLastName() { |
| |
| return lastName; |
| |
| } |
| |
| public void setLastName(String lastName) { |
| |
| this.lastName = lastName; |
| |
| } |
| |
| public String getEmail() { |
| |
| return email; |
| |
| } |
| |
| public void setEmail(String email) { |
| |
| this.email = email; |
| |
| } |
| |
| public String getGender() { |
| |
| return gender; |
| |
| } |
| |
| public void setGender(String gender) { |
| |
| this.gender = gender; |
| |
| } |
| |
| @Override |
| |
| public String toString() { |
| |
| return “Employee [id=” + id + “, lastName=” + lastName + “, email=” + email + “, gender=” + gender + “]”; |
| |
| } |
±--------------------------------------------------------------------------------------------------------------------------+
±-----------------------------------------------------------------------------------+
| “1.0” encoding=“UTF-8” ?> |
| |
| | |
| PUBLIC “-//mybatis.org//DTD Config 3.0//EN” |
| |
| “http://mybatis.org/dtd/mybatis-3-config.dtd”> |
| |
|
| |
| |
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
| |
| |
|
| |
|
| |
|
| |
|
±-----------------------------------------------------------------------------------+
±--------------------------------------------------------------------------------------------+
| “1.0” encoding=“UTF-8” ?> |
| |
| | |
| PUBLIC “-//mybatis.org//DTD Mapper 3.0//EN” |
| |
| “http://mybatis.org/dtd/mybatis-3-mapper.dtd”> |
| |
|
| |
| |
| |
|
±--------------------------------------------------------------------------------------------+
±---------------------------------------------------------------------+
| @Test |
| |
| public void test() throws Exception { |
| |
| String resource = “mybatis-config.xml”; |
| |
| InputStream inputStream = Resources.getResourceAsStream(resource); |
| |
| SqlSessionFactory sqlSessionFactory = |
| |
| new SqlSessionFactoryBuilder().build(inputStream); |
| |
| System.out.println(sqlSessionFactory); |
| |
| SqlSession session = sqlSessionFactory.openSession(); |
| |
| try { |
| |
| Employee employee = |
| |
| session.selectOne(“suibian.selectEmployee”, 1001); |
| |
| System.out.println(employee); |
| |
| } finally { |
| |
| session.close(); |
| |
| } |
| |
| } |
±---------------------------------------------------------------------+
±--------------------------------------------------+
| public interface EmployeeMapper { |
| |
| public Employee getEmployeeById(Integer id ); |
| |
| } |
±--------------------------------------------------+
在Mppper映射文件中的
标签中的namespace中必须指定Mapper接口 的全类名
±-----------------------------------------------------------+
| @Test |
| |
| public void test() throws Exception{ |
| |
| String resource = “mybatis-config.xml”; |
| |
| InputStream inputStream = |
| |
| Resources.getResourceAsStream(resource); |
| |
| SqlSessionFactory sqlSessionFactory = |
| |
| new SqlSessionFactoryBuilder() |
| |
| .build(inputStream); |
| |
| SqlSession session = |
| |
| sqlSessionFactory.openSession(); |
| |
| try { |
| |
| //[Mapper]{.ul}接口:获取[Mapper]{.ul}接口的 代理实现类对象 |
| |
| EmployeeMapper mapper = |
| |
| session.getMapper(EmployeeMapper.class); |
| |
| Employee employee = |
| |
| mapper.getEmployeeById(1006); |
| |
| System.out.println(employee); |
| |
| } finally { |
| |
| session.close(); |
| |
| } |
| |
| } |
±-----------------------------------------------------------+
MyBatis 的配置文件包含了影响 MyBatis 行为甚深的设置(settings)和属性(properties)信息。
configuration 配置
properties 属性
settings 设置
typeAliases 类型命名
typeHandlers 类型处理器
objectFactory 对象工厂
plugins 插件
environments 环境
environment 环境变量
transactionManager 事务管理器
dataSource 数据源
databaseIdProvider 数据库厂商标识
mappers 映射器
±---------------------------------------------------------------+
|
| |
|
| |
|
| value=“jdbc:mysql://localhost:3306/test_mybatis” /> |
| |
|
| |
|
| |
|
±---------------------------------------------------------------+
±---------------------------------------------------------+
| jdbc.driver=com.mysql.jdbc.Driver |
| |
| jdbc.url=jdbc:mysql://[localhost]{.ul}:3306/mybatis_1129 |
| |
| jdbc.username=root |
| |
| jdbc.password=1234 |
±---------------------------------------------------------+
±------------------------------------------------------------+
| |
| |
|
±------------------------------------------------------------+
3)在environment元素的dataSource元素中为其动态设置
±-------------------------------------------------------------+
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
| value="${jdbc.username}" /> |
| |
|
| |
| value="${jdbc.password}" /> |
| |
|
| |
|
| |
|
±-------------------------------------------------------------+
这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。
包含如下的setting设置:
±--------------------------------------------------------------------------+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| value=“equals,clone,hashCode,toString”/>\ |
|
±--------------------------------------------------------------------------+
±----------------------------------------------------------+
|
| |
|
| |
| alias=“emp”/> |
| |
|
±----------------------------------------------------------+
±--------------------------------------------------+
|
| |
|
| |
|
±--------------------------------------------------+
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d01d4dmN-1599703793293)(media/image4.png)]{width=“5.757638888888889in” height=“2.6909722222222223in”}
MyBatis可以配置多种环境,比如开发、测试和生产环境需要有不同的配置
每种环境使用一个environment标签进行配置并指定唯一标识符
可以通过environments标签中的default属性指定一个环境的标识符来快速的切换环境
environment-指定具体环境
id:指定当前环境的唯一标识
transactionManager、和dataSource都必须有
±-----------------------------------------------------------------+
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
±-----------------------------------------------------------------+
type: JDBC | MANAGED | 自定义
JDBC:使用了 JDBC 的提交和回滚设置,依赖于从数据源得到的连接来管理事务范 围。 JdbcTransactionFactory
MANAGED:不提交或回滚一个连接、让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 ManagedTransactionFactory
自定义:实现TransactionFactory接口,type=全类名/别名
type: UNPOOLED | POOLED | JNDI | 自定义
UNPOOLED:不使用连接池, UnpooledDataSourceFactory
POOLED:使用连接池, PooledDataSourceFactory
JNDI: 在EJB 或应用服务器这类容器中查找指定的数据源
自定义:实现DataSourceFactory接口,定义数据源的获取方式。
用来在mybatis初始化的时候,告诉mybatis需要引入哪些Mapper映射文件
mapper逐个注册SQL映射文件
resource : 引入类路径下的文件
url : 引入网络路径或者是磁盘路径下的文件
class : 引入Mapper接口.
有SQL映射文件 , 要求Mapper接口与 SQL映射文件同名同位置.
没有SQL映射文件 , 使用注解在接口的方法上写SQL语句.
±---------------------------------------------------------------+
|
| |
|
| |
|
| |
|
| |
|
±---------------------------------------------------------------+
±------------------------------------------------+
|
| |
|
| |
|
±------------------------------------------------+
MyBatis 的真正强大在于它的映射语句,也是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好。
SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序):
cache – 给定命名空间的缓存配置。
cache-ref – 其他命名空间缓存配置的引用。
resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加 载对象。
parameterMap –
已废弃!老式风格的参数映射。内联参数是首选,这个元素可能在将来被移除,这里不会记录。sql – 可被其他语句引用的可重用语句块。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语
±-------------------------------------------------------+
| |
±-------------------------------------------------------+
±-------------------------------------------------------------------------------------------+
|
| |
| parameterType=“com.atguigu.mybatis.beans.Employee” |
| |
| databaseId=“mysql”> |
| |
| insert into tbl_employee(last_name,email,gender) values(#{lastName},#{email},#{gender}) |
| |
|
±-------------------------------------------------------------------------------------------+
±--------------------------------------------------+
|
| |
| update tbl_employee set last_name = #{lastName}, |
| |
| email = #{email}, |
| |
| gender = #{gender} |
| |
| where id = #{id} |
| |
|
±--------------------------------------------------+
±-------------------------------------------+
|
| |
| delete from tbl_employee where id = #{id} |
| |
|
±-------------------------------------------+
支持主键自增,例如MySQL数据库
不支持主键自增,例如Oracle数据库
±-------------------------------------------------------------------------------------------+
|
| |
| databaseId=“mysql” |
| |
| useGeneratedKeys=“true” |
| |
| keyProperty=“id”> |
| |
| insert into tbl_employee(last_name,email,gender) values(#{lastName},#{email},#{gender}) |
| |
|
±-------------------------------------------------------------------------------------------+
这种情况MyBatis可直接使用这个参数,不需要经过任 何处理。
取值:#{随便写}
任意多个参数,都会被MyBatis重新包装成一个Map传入。Map的key是param1,param2,或者0,1…,值就是参数的值
取值: #{0 1 2 …N / param1 param2 … paramN}
为参数使用@Param起一个名字,MyBatis就会将这些参数封装进map中,key就是我们自己指定的名字
取值: #{自己指定的名字 / param1 param2 … paramN}
当这些参数属于我们业务POJO时,我们直接传递POJO
取值: #{POJO的属性名}
我们也可以封装多个参数为map,直接传递
取值: #{使用封装Map时自己指定的key}
会被MyBatis封装成一个map传入, Collection对应的key是collection,Array对应的key是array. 如果确定是List集合,key还可以是list.
取值:
Array: #{array}
Collection(List/Set): #{collection}
List : #{collection / list}
±-------------------------------------------------------------------+
| public Employee getEmployeeByIdAndLastName |
| |
| (@Param(“id”)Integer id, @Param(“lastName”)String lastName); |
±-------------------------------------------------------------------+
±-----------------------------------------------------------------------------------------+
| public Object getNamedParams(Object[] args) { |
| |
| final int paramCount = names.size(); |
| |
| if (args == null || paramCount == 0) { |
| |
| return null; |
| |
| } else if (!hasParamAnnotation && paramCount == 1) { |
| |
| return args[names.firstKey()]; |
| |
| } else { |
| |
| final Map
javaType、jdbcType、mode、numericScale、resultMap、typeHandler、jdbcTypeName、expression
±-------------------------------------------------------------------------------------------------------------------------------------------------+
| > insert into orcl_employee(id,last_name,email,gender) values(employee_seq.nextval,#{lastName, ,jdbcType=NULL },#{email},#{gender}) --Oracle |
±-------------------------------------------------------------------------------------------------------------------------------------------------+
获取参数的值,预编译到SQL中。安全。 PreparedStatement
注意: 取单个普通类型的参数,${}中不能随便写,必须使用 _parameter
_parameter 是Mybatis的内置参数.
获取参数的值,拼接到SQL中。有SQL注入问题。 Statement
原则: 能用#{}取值就优先使用#{},#{}解决不了的可以使用${}.
例如: 原生的JDBC不支持占位符的地方,就可以使用${}
Select column1 ,column2… from 表 where 条件group by 组标识 having 条件 order by 排序字段 desc/asc limit x, x
±----------------------------------------------------------+
| @MapKey(“id”) // 指定使用对象的哪个属性来充当map的key |
| |
| public Map
±----------------------------------------------------------+
autoMappingBehavior默认是PARTIAL,开启自动映射的功能。唯一的要求是列名和javaBean属性名一致
如果autoMappingBehavior设置为null则会取消自动映射
数据库字段命名规范,POJO属性符合驼峰命名法,如A_COLUMNaColumn,我们可以开启自动驼峰命名规则映射功能,mapUnderscoreToCamelCase=true
自定义resultMap,实现高级结果集映射
id :用于完成主键值的映射
result :用于完成普通列的映射
association :一个复杂的类型关联;许多结果将包成这种类型
collection : 复杂类型的集
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZBiqwcNj-1599703793294)(media/image5.png)]{width=“5.768055555555556in” height=“1.6027777777777779in”}
±---------------------------------------------------------------------------+
| |
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
±---------------------------------------------------------------------------+
±------------------------------------+
| public class Department { |
| |
| private Integer id ; |
| |
| private String departmentName ; |
| |
| // 省略 get/set方法 |
| |
| [}]{.ul} |
±------------------------------------+
±--------------------------------+
| public class Employee { |
| |
| private Integer id ; |
| |
| private String lastName; |
| |
| private String email ; |
| |
| private String gender ; |
| |
| private Department dept ; |
| |
| // 省略 get/set方法 |
| |
| } |
±--------------------------------+
±----------------------------------------------------------------------------------------------------------------------------------------------------+
| |
| |
|
| |
|
| |
|
| |
|
| |
|
| |
| |
| |
|
| |
|
| |
|
±----------------------------------------------------------------------------------------------------------------------------------------------------+
±----------------------------------------------------------------------------------------+
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
±----------------------------------------------------------------------------------------+
对于查询员工信息并且将对应的部门信息也查询出来的需求,就可以通过分步的方式
完成查询。
先通过员工的id查询员工信息
再通过查询出来的员工信息中的外键(部门id)查询对应的部门信息.
±----------------------------------------------------------------------------------------------------+
| |
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
| column=“d_id” fetchType=“eager”> |
| |
|
| |
|
±----------------------------------------------------------------------------------------------------+
Settings中进行如下的配置:
±----------------------------------------------------------------+
| |
| |
|
| |
| |
| |
|
±----------------------------------------------------------------+
±------------------------------------+
| public class Department { |
| |
| private Integer id ; |
| |
| private String departmentName ; |
| |
| private List
| |
| } |
±------------------------------------+
±-------------------------------------------------------------------------------------+
| |
| |
|
| |
|
| |
|
| |
| |
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
±-------------------------------------------------------------------------------------+
对于查询部门信息并且将对应的所有的员工信息也查询出来的需求,就可以通过分步的方式完成查询。
先通过部门的id查询部门信息
再通过部门id作为员工的外键查询对应的部门信息.
±-----------------------------------------------------------------------------------------+
| |
| |
|
| |
|
| |
|
| |
|
| |
| select=“com.atguigu.mybatis.dao.EmployeeMapper.getEmpsByDid” |
| |
| column=“id”> |
| |
|
| |
|
±-----------------------------------------------------------------------------------------+
Map来进行传递,语法如下: {k1=v1, k2=v2…}
时所用的key来取值.
fetchType=“eager”.
动态 SQL是MyBatis强大特性之一。极大的简化我们拼装SQL的操作
动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似
MyBatis 采用功能强大的基于 OGNL 的表达式来简化操作
if
choose (when, otherwise)
trim (where, set)
foreach
表达式语言,通过它可以非常方便的来操作对象属性。 类似于我们的EL,SpEL等
访问对象属性: person.name
调用方法: person.getName()
调用静态属性/方法: @java.lang.Math@PI
@java.util.UUID@randomUUID()
调用构造方法: new com.atguigu.bean.Person(‘admin’).name
运算符: +,-*,/,%
逻辑运算符: in,not in,>,>=,<,<=,==,!=
注意:xml中特殊符号如",>,<等这些都需要使用转义字符
If用于完成简单的判断.
Where用于解决SQL语句中where关键字以及条件中第一个and或者or的问题
±---------------------------------------------------------------------------------------------+
| |
±---------------------------------------------------------------------------------------------+
prefix: 添加前缀
prefixOverrides: 去掉前缀
suffix: 添加后缀
suffixOverrides: 去掉后缀
±-----------------------------------------------------------------------------------------------+
| |
±-----------------------------------------------------------------------------------------------+
±-------------------------------------------------------------------------------+
|
| |
| update tbl_employee |
| |
|
| |
|
| |
| last_name = #{lastName}, |
| |
|
| |
|
| |
| email = #{email} , |
| |
|
| |
|
| |
| gender = #{gender} |
| |
|
| |
|
| |
| where id =#{id} |
| |
|
±-------------------------------------------------------------------------------+
±-------------------------------------------------------------------------------------------------+
| |
±-------------------------------------------------------------------------------------------------+
collection: 要迭代的集合
item: 当前从集合中迭代出的元素
open: 开始字符
close:结束字符
separator: 元素与元素之间的分隔符
index:
迭代的是List集合: index表示的当前元素的下标
迭代的Map集合: index表示的当前元素的key
±--------------------------------------------------------------------------------------------------+
| |
±--------------------------------------------------------------------------------------------------+
sql 标签是用于抽取可重用的sql片段,将相同的,使用频繁的SQL片段抽取出来,单独定义,方便多次引用.
抽取SQL:
±-------------------------------------------------------+
|
| |
| select id , last_name, email ,gender from tbl_employee |
| |
|
±-------------------------------------------------------+
|
|
| |
| #{curr_id} |
| |
|
| |
| |
±--------------------------------------------------------------------------------------------------+
sql 标签是用于抽取可重用的sql片段,将相同的,使用频繁的SQL片段抽取出来,单独定义,方便多次引用.
抽取SQL:
±-------------------------------------------------------+
|
| |
| select id , last_name, email ,gender from tbl_employee |
| |
|
±-------------------------------------------------------+