[01] MyBatis概述
传统的JDBC来做DAO层,做了下面这几件事:
- 加载驱动
- 获取连接
- 执行SQL语句
- 获取操作结果封装信息
- 返回操作结果
而实际上DAO层最关心的是什么呢,就是后面三点就完事,JDBC显得太繁琐:
- 执行SQL语句
- 获取操作结果封装信息
- 返回操作结果
所以说MyBatis作为持久层框架的出现,必然是有一个核心对象来只做上面这些事情,这个对象叫做SqlSession,从命名来说也很贴切了。
那么SqlSession到底有什么作用:
- 向SQL语句传入参数
- 执行SQL语句
- 获取执行SQL语句的结果
- 事务的控制
那么如何得到SqlSession:
- 通过配置文件获取数据库连接相关信息
- 通过读取到的配置信息构建SqlSessionFactory
- 通过SqlSessionFactory打开数据库会话
<!--maven pom-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
12
1
<!--maven pom-->
2
<dependency>
3
<groupId>org.mybatis</groupId>
4
<artifactId>mybatis</artifactId>
5
<version>3.4.6</version>
6
</dependency>
7
8
<dependency>
9
<groupId>mysql</groupId>
10
<artifactId>mysql-connector-java</artifactId>
11
<version>5.1.6</version>
12
</dependency>
public class Demo {
public static void main(String[] args) throws IOException {
//读取配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//获取工厂类
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//获取SqlSession数据库会话对象
SqlSession sqlSession = factory.openSession();
//...
}
}
12
1
public class Demo {
2
public static void main(String[] args) throws IOException {
3
//读取配置文件
4
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
5
//获取工厂类
6
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
7
//获取SqlSession数据库会话对象
8
SqlSession sqlSession = factory.openSession();
9
10
//...
11
}
12
}
这个配置文件 "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>
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC"/>
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/dbgirl"/>
<property name="username" value="root"/>
<property name="password" value="dev"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="sqlmapper/GirlMapper.xml"/>
</mappers>
</configuration>
23
1
2
3
4
5
6
<configuration>
7
<environments default="development">
8
<environment id="development">
9
<!-- 使用jdbc事务管理 -->
10
<transactionManager type="JDBC"/>
11
<!-- 数据库连接池 -->
12
<dataSource type="POOLED">
13
<property name="driver" value="com.mysql.jdbc.Driver"/>
14
<property name="url" value="jdbc:mysql://localhost:3306/dbgirl"/>
15
<property name="username" value="root"/>
16
<property name="password" value="dev"/>
17
</dataSource>
18
</environment>
19
</environments>
20
<mappers>
21
<mapper resource="sqlmapper/GirlMapper.xml"/>
22
</mappers>
23
</configuration>
我们说过,SqlSession可以执行SQL语句,那么这个SQL语句又是哪里来?注意如上的配置文件中 <mapper resource="sqlmapper/GirlMapper.xml"/>,我们再来看看这个家伙:
<?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="dulk.learn.mybatis.dao.GirlDao">
<select id="findById" parameterType="long" resultType="dulk.learn.mybatis.pojo.Girl">
SELECT * FROM girl WHERE id = #{id}
</select>
</mapper>
10
1
2
3
4
5
6
<mapper namespace="dulk.learn.mybatis.dao.GirlDao">
7
<select id="findById" parameterType="long" resultType="dulk.learn.mybatis.pojo.Girl">
8
SELECT * FROM girl WHERE id = #{id}
9
</select>
10
</mapper>
原来如此,SQL语句直接写到xml文件中了,我们通过读取配置文件来获取SqlSessionFactory时,数据库连接信息和SQL语句就都是在配置文件里。既然这两样都有了,是不是意味着我们就可以直接用了?所以接着之前的Demo我们是这样用的,来获取一个对应数据库表的Girl对象:
public class Demo {
public static void main(String[] args) throws IOException {
//读取配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//获取工厂类
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//获取SqlSession数据库会话对象
SqlSession sqlSession = factory.openSession();
//获取一个对应数据库表的Girl对象
Girl girl = sqlSession.selectOne("dulk.learn.mybatis.dao.GirlDao.findById", 1L);
}
}
13
1
public class Demo {
2
public static void main(String[] args) throws IOException {
3
//读取配置文件
4
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
5
//获取工厂类
6
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
7
//获取SqlSession数据库会话对象
8
SqlSession sqlSession = factory.openSession();
9
10
//获取一个对应数据库表的Girl对象
11
Girl girl = sqlSession.selectOne("dulk.learn.mybatis.dao.GirlDao.findById", 1L);
12
}
13
}
我们在配置Mapper时,其中<mapper>标签的 "namespace" 属性,是为了限定和隔离不同的语句,避免重名。还有一点是, namespace 可以绑定接口,这意味着假如你的 namespace 的值为某个接口名(如上例中的 <mapper namespace="dulk.learn.mybatis.dao.GirlDao"> ),那么你可以直接通过MyBatis来获取一个该接口的实例,并调用其方法:
public class Demo {
public static void main(String[] args) throws IOException {
//读取配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//获取工厂类
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//获取SqlSession数据库会话对象
SqlSession sqlSession = factory.openSession();
//获取一个对应数据库表的Girl对象
//Girl girl = sqlSession.selectOne("dulk.learn.mybatis.dao.GirlDao.findById", 1L);
GirlDao girlDao = sqlSession.getMapper(GirlDao.class);
Girl girl = girlDao.findById(1L);
}
}
x
1
public class Demo {
2
public static void main(String[] args) throws IOException {
3
//读取配置文件
4
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
5
//获取工厂类
6
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
7
//获取SqlSession数据库会话对象
8
SqlSession sqlSession = factory.openSession();
9
10
//获取一个对应数据库表的Girl对象
11
//Girl girl = sqlSession.selectOne("dulk.learn.mybatis.dao.GirlDao.findById", 1L);
12
GirlDao girlDao = sqlSession.getMapper(GirlDao.class);
13
Girl girl = girlDao.findById(1L);
14
}
15
}
到这里,大概已经能看到一些MyBatis的优势了:
- 不需要重复处理注册驱动,创建连接,设置参数等操作
- SQL语句在配置文件中,而不是硬编码到代码中
- 传统JDBC从数据库获取数据转为对象需要我们手动从ResultSet中get数据然后set到Java对象中,而MyBatis帮我们自动进行了转换
可以看到,MyBatis是对JDBC数据库的过程进行了封装,执行我们写好的SQL并将结果映射成Java对象返回:
注:
1、MyBatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器
2、MappedStatement也是个底层封装对象,它包装了MyBatis配置信息及SQL映射信息等。mapper.xml文件中一个SQL对应一个MappedStatement对象,SQL的id即是MappedStatement的id
3、MappedStatement对SQL执行输入参数进行定义,包括HashMap、基本类型、POJO,Executor通过MappedStatement在执行SQL前将输入的Java对象映射至SQL中,输入参数映射就是JDBC编程中对PreparedStatement设置参数
4、MappedStatement对SQL执行输出结果进行定义,包括HashMap、基本类型、POJO,Executor通过MappedStatement在执行SQL后将输出结果映射至Java对象中,输出结果映射过程相当于JDBC编程中对结果的解析处理过程
参考链接: