传统的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编程中对结果的解析处理过程
参考链接: