浅析mybatis源码(一)整体思路

大体思路

感受好多事物都遵循28原则,Mybatis也不例外,2成的代码可以完成8成的需求。我就准备分析一下主要的代码。如下是大纲(待定)java

JDBC和mybatis

mybatis是基于jdbc的。jdbc提供了java客户端与关系型数据库的一套标准接口。可以完成链接数据库、提交sql语句等基本功能。那mybatis又主要作了哪些事情呢?mysql

  1. 可以选择使用链接池,复用数据库链接。
  2. 可以经过注解或xml来管理sql语句。
  3. 可以将结果集映射为java bean。
  4. 缓存、懒加载、插件扩展等。

再来对比并复习下jdbc和mybatis的demo吧。sql

import java.sql.*;

public class HelloWorld {
    static final String user = "";
    static final String password = "";
    static final String url = "";
    public static void main(String[] args) throws Throwable{
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection(url,user, password);
        Statement statement = connection.prepareStatement("select * from product where id = ?");
        ((PreparedStatement) statement).setInt(1, 1);
        ResultSet resultSet = ((PreparedStatement) statement).executeQuery();
        while (resultSet.next()){
            String name = resultSet.getString("name");
            double price = resultSet.getDouble("price");
            String imgUrl = resultSet.getString("img_url");
            System.out.println("name: "+name+" price: "+price+" imgUrl: "+imgUrl);
        }

    }
}

以上是jdbc的demo。能够看到很是的简单粗暴。加载相应的数据库驱动后,就能经过url、帐号、密码来获取链接了。再经过Statement来构造sql语句。结果存储在ResultSet中。具体能够查看jdbc的文档。
接下来看下mybatis的demo数据库

//Product实体类
import lombok.Data;

@Data
public class Product {
    private long id;
    private String name;
    private String imgUrl;
    private double price;
}
//Product Mapper
public interface ProductMapper {
    @Select("select * from product where id = #{id}")
    Product detail(long id);
}
//DataSource工厂类
public class DataSourceFactory {
  public static DataSource getDataSource() {
    String driver = "com.mysql.jdbc.Driver";
    String url = "";
    String username = "";
    String password = "";
    return new PooledDataSource(driver, url, username, password);
  }
}
//Environment工厂类
public class EnvironmentFactory {
  static Environment getEnvironment(){
    return new Environment("dev", new JdbcTransactionFactory(), DataSourceFactory.getDataSource());
  }
}
//SQLSession工具类
public class SqlSessionFactoryUtil {
  private static SqlSessionFactory sqlSessionFactory = null;
  private static Object lock = new Object();
  private static void addMapper(Configuration configuration){
    configuration.addMapper(ProductMapper.class);
  }
  public static void initSqlSessionFactory() {
    sqlSessionFactory = null;
    Environment environment = EnvironmentFactory.getEnvironment();
    Configuration configuration = new Configuration(environment);
    addMapper(configuration);
    synchronized (lock){
      if(sqlSessionFactory == null){
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
      }
    }
  }
  public static SqlSession getSqlSession() {
    if(sqlSessionFactory == null){
      initSqlSessionFactory();
    }
    return sqlSessionFactory.openSession();
  }
}

代码可能比较多。可是仔细看,其实都是很简单的代码。Product实体类和ProductMapper就不说了。DataSourceFactory就是设置了下帐号密码等用来链接数据库,使用的类主要是PooledDataSource,使用链接池方式链接数据库。EnvironmentFactory就是设置了下数据源是刚刚的DataSource,使用jdbc管理事务。SQLSession工具类就是经过SqlSessionFactoryBuilder来获取sqlSessionFactory,再获取SqlSession。接下来看下如何使用吧。缓存

public class TestOrderMapper {
    private SqlSession sqlSession = null;
    private ProductMapper productMapper= null;
    @Before
    public void init(){
        sqlSession = SqlSessionFactoryUtil.getSqlSession();
        productMapper = sqlSession.getMapper(ProductMapper.class);
    }
    @Test
    public void getProduct(){
        Product product = productMapper.detail(1);
        System.out.println(product);
    }
    @After
    public void close() {
        sqlSession.close();
    }
}
demo对比

经过这两段代码的对比。咱们可以看到mybatis的主要优势是:
1.管理了数据库链接。能够看到咱们操做的并非数据库链接,而是SQLSession。
2.经过注解管理sql语句。
3.将结果集映射到sql语句。
是否是和上面作的比较对应上了。mybatis

如何实现mybatis

接来下该进入主题了,如何实现mybatis。
如下均为基本思路,后面各个章节会细讲。
数据库链接管理咱们只考虑链接池,基本思路:数据库链接后,将其放在一个list中。每次获取SQLSession,list中有则取出来,若list中没有而且未超过链接池最大链接数则获取新的链接,不然等待。每次关闭SQLSession,则将链接放回list中。app

sql语句管理咱们只考虑注解的方式。由于xml最终仍是会转化为java对象。经过demo中能够看到,咱们是将sql定义在了接口的方法注解上。咱们能够经过反射来获取到注解上sql语句,以及选项。这时咱们就知道这个方法该如何执行sql语句了,就能够用动态代理生成这个方法了。工具

结果集映射结果集映射,首先咱们要获取方法的返回类型,所以最重要的仍是反射。若是还考虑懒加载的话,那就要用到动态代理了。ui

相关文章
相关标签/搜索