MyBatis的基础应用
1.MyBatis介绍
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
IBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)
MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
- Mybatis提供一种“半自动化”的ORM实现。MyBatis需要手动写SQL,后期可以逆向工程!
- 这里的“半自动化”,是相对Hibernate等提供了全面的数据库封装机制的“全自动化”ORM实现而言,“全自动”ORM实现了POJO和数据库表之间的映射,以及
SQL 的自动生成和执行。 - 下载地址: MyBatis下载地址:https://github.com/mybatis/mybatis-3/releases
- 使用版本:3.4.5
Hibernate** 全自动框架 SQL语句可以自动生成,不用人工书写SQL! 笨重
**MyBatis** 半自动 SQL语句还是需要自己书写,后期有一些插件可以自动生成SQL! 灵活
ORM概念: Object Ralation Mapping 对象关系映射 框架
数据库表------>实体类
数据库表中字段----->实体类的属性
数据库表中字段的类型----->实体类中属性的类型
常见的ORM框架哪些:
MyBatis
Hibernate
Spring Data
......
2.MyBatis特点
- 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
- 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。 - 提供映射标签,支持对象与数据库的orm字段关系映射
提供对象关系映射标签,支持对象关系组建维护
提供xml标签,支持编写动态sql(SQL动态拼接) - 性能: JDBC > MyBatis(半自动) > Hibernate(全自动)
- 效率:JDBC < MyBatis(半自动) <> Hibernate(全自动)
3.MyBatis基础应用
3.1 搭建MyBatis环境
3.1.1 环境准备
- Jdk环境:jdk1.8
- Ide环境:IDEA(装MyBatis插件)
- 数据库环境:MySQL 5.1
- Mybatis:3.4.5
3.1.2 下载MyBatis
mybaits的代码由github.com管理,下载地址:https://github.com/mybatis/mybatis-3/releases
Mybatis-3.4.5.jar:mybatis的核心包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bruceliu.mybatis</groupId>
<artifactId>mybatis-20190902</artifactId>
<version>1.0-SNAPSHOT</version>
<!--导入MyBatis开发环境的依赖-->
<dependencies>
<!-- myBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- Junit测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--Log4J日志工具 打印运行日志用的!-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<!--如果是WEB项目,那么不用创建bulid标签-->
<build>
<!--编译的时候同时也把包下面的xml同时编译进去-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
3.1.3 添加日志配置-log4j.properties
log4j.rootLogger=DEBUG, Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
3.1.4 准备数据库
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`birthday` date DEFAULT NULL COMMENT '生日',
`sex` char(1) DEFAULT NULL COMMENT '性别',
`address` varchar(256) DEFAULT NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', '王五', '2018-09-06', '1', '四川成都');
INSERT INTO `user` VALUES ('10', '张三', '2014-07-10', '1', '北京市');
INSERT INTO `user` VALUES ('16', '张小明', '2018-09-06', '1', '河南郑州');
INSERT INTO `user` VALUES ('22', '陈小明', '2018-09-05', '1', '河南郑州');
INSERT INTO `user` VALUES ('24', '张三丰', '2018-09-13', '1', '河南郑州');
INSERT INTO `user` VALUES ('25', '陈小明', '2018-09-12', '1', '河南郑州');
INSERT INTO `user` VALUES ('26', '王五', '2018-09-05', '0', '河南郑州');
3.1.5.创建主配置文件:mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 引入外部配置文件 -->
<properties resource="jdbc.properties"/>
<!-- 环境 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!--映射Mapper文件-->
<!--引入映射文件-->
<mappers>
<mapper resource="com/bruceliu/mapper/UserMappper.xml"></mapper>
</mappers>
</configuration>
jdbc.properties:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatisdb?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123
3.2 实现MyBatis的查询
3.2.1 获取SqlSession对象(核心对象)
MyBatis框架中涉及到的几个API
SqlSessionFactoryBuilder:该对象负责根据MyBatis配置文件mybatis-config.xml构建SqlSessionFactory实例 负责生产session
SqlSessionFactory:每一个MyBatis的应用程序都以一个SqlSessionFactory对象为核心。该对象负责创建SqlSession对象实例。
SqlSession:该对象包含了所有执行SQL操作的方法,用于执行已映射的SQL语句
3.2.2 创建实体类 User
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", birthday=" + birthday + ", sex=" + sex + ", address=" + address + "]";
}
}
3.2.3 创建接口层 UserMapper
/**
* @ClassName: UserMapper
* @author: BRUCELIU
* @date: 2018年9月28日 下午5:17:06
* @Description:TODO
*/
public interface UserMapper {
public List<User> getList();
}
3.2.4 创建接口实现层 UserMapper实现层实现层
public class UserMapperImpl implements UserMapper {
public List<User> getList() {
InputStream inputStream = null;
SqlSessionFactory sqlSessionFactory = null;
SqlSession session = null;
try {
String resource = "mybatis-config.xml"; // 配置文件
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
session = sqlSessionFactory.openSession(); //获取session
List<User> list = session.selectList("com.bruceliu.dao.UserMapper.getList");
return list;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
session.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
3.2.5 创建接口Mapper文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bruceliu.dao.UserMapper">
<!-- 返回值类型 -->
<select id="getList" resultType="com.bruceliu.bean.User">
select * from user
</select>
</mapper>
3.2.6 测试类
public class TestMyBatis {
UserMapperImpl um = new UserMapperImpl();
@Test
public void test1() {
List<User> list = um.getList();
for (User u : list) {
System.out.println(u);
}
}
}
3.2.6.Mybatis使用步骤总结:
- 创建SqlSessionFactory
- 通过SqlSessionFactory创建SqlSession对象
- 通过SqlSession操作数据库
- 调用session.commit()提交事务
- 调用session.close()关闭会话
3.3封装获取MyBatis中Session的工具类
/**
* @author bruceliu
* @create 2019-09-02 15:37
* @description 获取sesison和关闭session的工具类
*/
public class MyBatisUtils {
/**
* 01-获取SqlSession
* @return
*/
public static SqlSession getSession(){
SqlSession session=null;
InputStream inputStream=null;
try {
//配置文件的路径
String resource = "mybatis-config.xml";
//加载配置文件,得到一个输入流
inputStream = Resources.getResourceAsStream(resource);
//获取MyBatis的Session工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通过session工厂获取到一个session (此session非Servlet中Session,这个Session表示MyBatis框架和数据库的会话信息)
//获取到session就表示MyBatis连接上数据库啦!!类似于JDBC中 Connection对象
session = sqlSessionFactory.openSession(true);//自动提交事务
//调用session的查询集合方法
return session;
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* 02-关闭SqlSession
* @param session
*/
public static void closeSession(SqlSession session){
if(session!=null){
session.close();
}
}
}
4.编写DAO的实现类发现的问题
- 冗余的代码多;
- 调用Statement不方便;
- 通用性不好,实现方法非常的类似;
4.1 使用动态代理实现接口的实现类(不需要Mapper实现类)
如何得到动态代理:
/**
* @author bruceliu
* @create 2019-09-02 10:58
* @description
*/
public class TestMybatis {
SqlSession session=null;
UserMappper um=null;
//在每次调用测试方法之前,自动调用init()方法
@Before
public void init(){
//MyBatis在底层使用动态代理(反射)自动生成Mapper实现类,不需要人工写实现类!
session = MyBatisUtils.getSession();
//um就是Mapper的实现类
um = session.getMapper(UserMappper.class);
}
@Test
public void testQuery(){
List<User> list = um.findList();
for (User user : list) {
System.out.println(user);
}
}
/*
* MyBatis增删改 需要手动提交事务
*/
@Test
public void testAdd(){
User u=new User("刘老师",new Date(),"女","日本东京");
int count = um.addUser(u);
System.out.println(count>0?"新增成功":"新增失败");
}
//每次调用测试方法之前,自动调用一下destory()
@After
public void destory(){
MyBatisUtils.closeSession(session);
}
}
注意:
1、保证命名空间和接口的全路径一致;
2、Statement的id和接口中的方法名一致
3、加入到mybatis-config.xml中
4.2 使用动态代理总结
使用mapper接口不用写接口实现类即可完成数据库操作,使用非常简单,也是官方所推荐的使用方法。
使用mapper接口的必须具备以几个条件:
1) Mapper的namespace必须和mapper接口的全路径一致。
2) Mapper接口的方法名必须和sql定义的id一致。
3) Mapper接口中方法的输入参数类型必须和sql定义的parameterType一致。
4) Mapper接口中方法的输出参数类型必须和sql定义的resultType一致。
5.Mybatis-Config配置
- properties 属性
- settings 设置
- typeAliases 类型别名
- typeHandlers 类型处理器
- objectFactory 对象工厂
- plugins 插件
- environments 环境
environment 环境变量
transactionManager 事务管理器
dataSource 数据源 - mappers 映射器
Mybatis的配置文件中配置项是有顺序的,即按照上面的顺序;
5.1 Properties
5.2.typeAliases(别名)
类型别名是为 Java 类型命名一个短的名字。 它只和 XML 配置有关, 只用来减少类完全限定名的多余部分。
自定义别名:
<!--实体类取别名-->
<typeAliases>
<!--直接给所有的实体类取别名。默认的实体类的别名就是类名(不区分小大写)
User实体类:User、user、USER
-->
<package name="com.bruceliu.bean"/>
</typeAliases>
注意:
使用定义的别名是不区分大小写的,但一般按java规则去使用即可,即user或者User
5.3.mappers
mapper映射文件的引入有3种方式:
路径相对于资源目录跟路径:
<mappers>
<mapper resource="com/bruceliu/dao/UserMapper.xml" />
</mappers>
使用完整的文件路径:
<mappers>
<mapper class="com.bruceliu.dao.UserMapper"/>
</mappers>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中
可直接配个扫描包:
<!--引入映射文件-->
<mappers>
<!-- <mapper resource="com/bruceliu/mapper/UserMappper.xml"></mapper>-->
<!--<mapper class="com.bruceliu.mapper.UserMappper"></mapper>-->
<!--直接映射包的名字,那么这个包下面所有的Mapper接口全部映射!-->
<package name="com.bruceliu.mapper"/>
</mappers>
6.Mapper XML 文件
Mapper映射文件是在实际开发过程中使用最多的,也是我们学习的重点。
Mapper文件中包含的元素有:
cache – 配置给定命名空间的缓存。
cache-ref – 从其他命名空间引用缓存配置。
resultMap – 映射复杂的结果对象。
sql – 可以重用的 SQL 块,也可以被其他语句引用。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语句
6.1.CRUD
6.1.1.select
<select id="getById" parameterType="int" resultType="User">
select * from user where id=#{id}
</select>
select标签叫Statement
id,必要属性,在当前的命名空间下不能重复。
指定输出类型,resultType
parameterType (不是必须)如果不指定,自动识别。
6.1.2. insert
<!-- 增删改返回的都是int值 不用写返回值 -->
<insert id="addUser">
INSERT INTO USER VALUES (null,#{username},#{birthday},#{sex},#{address})
</insert>
insert标签叫Statement
id,必要属性,在当前的命名空间下不能重复。
parameterType (不是必须)如果不指定,自动识别。
6.1.3.如何获得到自增id
<!-- 增删改返回的都是int值 不用写返回值 -->
<insert id="addUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO USER VALUES (null,#{username},#{birthday},#{sex},#{address})
</insert>
useGeneratedKeys:开启自增长映射
keyProperty:指定id所对应对象中的属性名
当执行完saveUser()方法后,其返回值依然是执行sql影响的行数,并不是要获取的自增ID!Mybatis会自动将返回的主键值赋值给对象User的属性id,因此你可以通过属性的get方法获得插入的主键值: System.out.println(User.getId());
- 另外一种写法
在插入操作完成之前或之后,可以配置标签获得生成的主键的值,获得插入之前还是之后的值,可以通过配置order属性来指定。
LAST_INSERT_ID:该函数是mysql的函数,获取自增主键的ID,它必须配合insert语句一起使用
<!-- 增删改返回的都是int值 不用写返回值 -->
<insert id="addUser" parameterType="User">
<selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO USER VALUES (null,#{username},#{birthday},#{sex},#{address})
</insert>
6.1.4.update
<update id="updateUser" >
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
</update>
update标签叫Statement
id,必要属性,在当前的命名空间下不能重复。
parameterType (不是必须)如果不指定,自动识别。
6.1.5.删除
<delete id="deleteUser" parameterType="int">
delete from user where id=#{id}
</delete>
delete标签叫Statement
id,必要属性,在当前的命名空间下不能重复。
parameterType (不是必须)如果不指定,自动识别。
7. #和$区别(面试题)
在映射文件配置标签执行查询操作。
注意:
- {}:相当于占位符
{id}:其中的id可以表示输入参数的名称,如果是简单类型名称可以任意 - ${}:表示拼接sql语句
- ${value}:表示输入参数的名称,如果参数是简单类型,参数名称必须是value
<!--
根据id查询用户,User findById(int id)
select:配置查询语句
id:可以通过id找到执行的statement,statement唯一标识
parameterType:输入参数类型
resultType:输出结果类型
#{}:相当于占位符
#{id}:其中的id可以表示输入参数的名称,如果是简单类型名称可以任意
-->
<select id="getById" parameterType="int" resultType="User" >
select * from user where id=#{id}
</select>
<!--
根据用户名称来模糊查询用户信息列表;
${}:表示拼接sql语句
${value}:表示输入参数的名称,如果参数是简单类型,参数名称必须是value
-->
<select id="findByUsername" parameterType="java.lang.String"
resultType="User">
select * from user where username like '%${value}%'
</select>
在Mybatis的mapper中,参数传递有2种方式,一种是#{}另一种是${},两者有着很大的区别:
# {} 实现的是sql语句的预处理参数,之后执行sql中用?号代替,使用时不需要关注数据类型,Mybatis自动实现数据类型的转换。并且可以防止SQL注入。
${} 实现是sql语句的直接拼接,不做数据类型转换,需要自行判断数据类型。不能防止SQL注入。
总结:
# {} 占位符,用于参数传递。
${}用于SQL拼接。
8.parameterType的传入参数
传入类型有三种:
1、简单类型,string、long、integer等
2、Pojo类型,User等
3、HashMap类型。
8.1 .传入参数是HashMap类型
查询需求:
<select id="getUsers" parameterType="map" resultType="User">
select * from user where birthday between #{startdate} and #{enddate}
</select>
查询测试:
@Test
public void test7(){
HashMap<String, Object> map=new HashMap<String, Object>();
map.put("startdate", "2018-09-07");
map.put("enddate", "2018-09-25");
List<User> users = mapper.getUsers(map);
for (User user : users) {
System.out.println(user);
}
}
注意:map的key要和sql中的占位符保持名字一致
8.2 分页查询
查询需求:
<!-- 分页:map传参 -->
<select id="selectAuthorByPage" resultType="User">
SELECT * FROM USER LIMIT #{offset}, #{pagesize}
</select>
接口:
/**
* 根据分页参数查询
* @param paramList 分页参数
* @return 分页后的用户列表
*/
List<User> selectAuthorByPage(Map<String, Object> paramList);
测试:
@Test
public void testSelectAuthorByPage() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("offset", 0);
map.put("pagesize", 2);
List<User> authorList = mapper.selectAuthorByPage(map);
for (int i = 0; i < authorList.size(); i++) {
System.out.println(authorList.get(i));
}
}
8.2.1使用注解
注意:mapper文件中的参数占位符的名字一定要和接口中参数的注解保持一致
mapper:
<!-- 分页:map传参 -->
<select id="selectUserByPage2" resultType="User">
SELECT * FROM USER LIMIT #{offset}, #{pagesize}
</select>
接口:
/**
* 根据分页参数查询
* @param offset 偏移量
* @param pagesize 每页条数
* @return 分页后的用户列表
*/
List<User> selectUserByPage2(@Param(value = "offset") int offset, @Param(value = "pagesize") int pagesize);
测试:
@Test
public void testSelectAuthorByPage2() {
List<User> authorList = mapper.selectUserByPage2(0, 2);
for (int i = 0; i < authorList.size(); i++) {
System.out.println(authorList.get(i));
System.out.println("----------------------");
}
}
8.2.2 使用参数顺序
注意:mapper文件中参数占位符的位置编号一定要和接口中参数的顺序保持一致
mapper:
<!-- 分页:传参顺序 -->
<select id="selectUserByPage3" parameterType="map" resultType="User">
SELECT * FROM USER LIMIT #{param1},#{param2}
</select>
接口:
/**
* 根据分页参数查询
* @param offset 偏移量
* @param pagesize 每页条数
* @return 分页后的用户列表
*/
List<User> selectUserByPage3(int offset, int pagesize);
测试:
@Test
public void testSelectAuthorByPage3() {
List<User> users = mapper.selectUserByPage3(1, 1);
for (int i = 0; i < users.size(); i++) {
System.out.println(users.get(i));
System.out.println("----------------------");
}
}
9.返回Map类型查询结果
Mybatis中查询结果集为Map的功能,只需要重写ResultHandler接口,,然后用SqlSession 的select方法,将xml里面的映射文件的返回值配置成 HashMap 就可以了。具体过程如下
9.1 xml文件配置
<resultMap id="resultMap1" type="HashMap">
<result property="key" column="r1" />
<result property="value" column="r2" />
</resultMap>
<select id="getResult" resultMap="resultMap1">
select count(*) r1, max(birthday) r2 from user
</select>
接口:
public HashMap<String, Object> getResult();
测试:
@Test
public void test8(){
HashMap<String, Object> result = mapper.getResult();
System.out.println(result);
}
返回多个值:
<select id="getResult" resultType="map">
select count(*) r1, max(birthday) r2,min(id) r3 from user
</select>
10.解决数据库字段和实体类属性不同
在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演示一下这种情况下的如何解决字段名与实体类属性名不相同的冲突。
上面的测试代码演示当实体类中的属性名和表中的字段名不一致时,使用MyBatis进行查询操作时无法查询出相应的结果的问题以及针对问题采用的两种办法:
- 解决办法一: 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致,这样就可以表的字段名和实体类的属性名一一对应上了,这种方式是通过在sql语句中定义别名来解决字段名和属性名的映射关系的。
- 解决办法二: 通过来映射字段名和实体类属性名的一一对应关系。这种方式是使用MyBatis提供的解决方式来解决字段名和属性名的映射关系的。
11.MyBatis整体架构
Mybatis是一个类似于Hibernate的ORM持久化框架,支持普通SQL查询,存储过程以及高级映射。Mybatis通过使用简单的XML或注解用于配置和原始映射,将接口和POJO对象映射成数据库中的记录。
由于Mybatis是直接基于JDBC做了简单的映射包装,所有从性能角度来看:
JDBC > Mybatis > Hibernate
1、配置2类配置文件,其中一类是:Mybatis-Config.xml (名字不是写死,随便定义),另一类:Mapper.xml(多个),定义了sql片段;
2、通过配置文件得到SqlSessionFactory
3、通过SqlSessionFactory得到SqlSession(操作数据库)
4、通过底层的Executor(执行器)执行sql,Mybatis提供了2种实现,一种是基本实现,另一种带有缓存功能的实现;