享学源码,一起行动。
说Mybatis之前得先讲讲JDBC
public class JDBCTest {
public static void main(String[] args) throws Exception {
String url = "jdbc:mysql://127.0.0.1:3306/test";
String user = "root";
String password = "123456";
try {
// 1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接
Connection connection = DriverManager.getConnection(url, user, password);
// 3.获取statement,preparedStatement
String sql = "select * from user where id=?";
PreparedStatement prepareStatement = connection.prepareStatement(sql);
// 设置参数
prepareStatement.setLong(1, 1l);
// 4.执行查询,获取结果,
ResultSet rs = prepareStatement.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("userName"));
System.out.println(rs.getString("name"));
System.out.println(rs.getInt("age"));
}
} finally {
// 5.关闭连接,释放资源
if (rs != null) {
rs.close();
}
if (prepareStatement != null) {
prepareStatement.close();
}
if (connection != null) {
connection.close();
}
}
}
}
如果我们在一个项目中所有与数据库打交道的地方都写一堆这样这个东西,肯定是不友好的。
我们分析存在的问题:
DriverManager.getConnection(url, user, password);
写一遍吧。好的写法是对其封装一个类工厂,只在工厂类中写一遍,直接从工厂类中获取Connection针对这5个步骤的问题,我们自己也可以写出几个工具类出来,其实就是在造轮子了。
Mybatis 就是这么一个框架,帮助我们解决JDBC在使用上的不方便。
mybatis-config.xml: 数据库连接等全局配置信息的集中管理
<configuration>
<environments default="test">
<environment id="test">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test" />
<property name="username" value="root" />
<property name="password" value="123456" />
dataSource>
environment>
environments>
<mappers>
<mapper resource="mappers/UserMapper.xml" />
mappers>
configuration>
UserMapper.xml: SQL也维护到XML中,使其从JAVA代码中脱离出来,进行集中管理。
<mapper namespace="UserMapper">
<select id="selectUser" resultType="com.wqd.model.User">
select * from user where id= #{id}
select>
mapper>
// 读取配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//根据配置文件,构建sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
try{
//执行SQL,获取结果集
//(SQL通过命名空间+SQLID 的格式定位)
User user = sqlSession.selectOne("MyMapper.selectUser", 1);
}finally {
sqlSession .close();
}
相对于JDBC:
将大量的编码工作,改为了配置工作。
仍然存在的可优化的点:
1. SQL的定位仍然需要字符串的形式进行定位,不够优雅。
2. session 的关闭仍然要自己关闭。
为了解决SQL定位的问题,Mybatis还提供了Mapper功能。
通常,我们习惯用一个Dao来表示对数据库的访问操作。
package com.wqd.mapper
public interface UserMapper {
public User selectUser();
}
UserMapper.xml
<mapper namespace="com.wqd.mapper.UserMapper">
<select id="selectUser" resultType="com.wqd.model.User">
select * from user where id= #{id}
select>
mapper>
编码使用
// 读取配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//根据配置文件,构建sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
try{
//获取Mapper ,执行操作
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.selectUser(1);
}finally{
sqlSession.close();
}
可以看出SQL的定位,通过方法调用的方式来解决了。 这样是比较符合开发人员的开发习惯的。
可优化点:
对于session的关闭,往往是开发人员经常遗忘的东西。有时候程序是比人靠谱的。在一些不要控制session.commit的场合,能自动关闭最好。
解决这个问题,Mybitis还提供了一个类SqlsessionManager。
从上图我们可以看出,SqlsessionManager是Sqlsession的实现类,也就是SqlsessionManager与DefaultSqlSession 是平级的,两个都可以表示会话。
但是
// 读取配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//根据配置文件,构建sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSessionManager sqlSessionManager = SqlSessionManager.newInstance(sqlSessionFactory);
UserDao userMapper =sqlSessionManager.getMapper(UserDao.class);
我们看到SqlsessionManager 不需要我们手动关闭session了。是不是又轻松了许多?
其实,SqlsessionManager通过AOP技术,在执行逻辑后进行了增强,使用的开发人员不必关心connection/session的关闭问题。
当让SqlsessionManager 还解决了DefaultSqlSeesion线程不安全问题。具体SqlsessionManager 是如何实现的,在后续文章中再说。
万能框架spring,也我们准备了一个JDBC的轮子Spring-JDBC
Spring-JDBC其实就是我们常说的:JDBCTemplate
不同于mybatis的是
Mybatis 通过对JDBC的封装,使我们可以更加灵活的操作数据库。
接下来,我将通过源码去探索Mybatis内部一些优秀的设计,来解开Mybatis设计的秘密。
如果本文任何错误,请批评指教,不胜感激 !
微信公众号:源码行动
享学源码,行动起来,来源码行动