Mybatis

397 阅读3分钟

MyBatis基本概念

  • MyBatis 是一款优秀的持久层框架,它支持定制化 SQL存储过程以及高级映射
  • MyBatis 避免了几乎所有的 JDBC 代码手动设置参数以及获取结果集
  • MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

JDBC

  • JDBC是Java提供的一个操作数据库的API
public class DbUtil {

    public static final String URL = "jdbc:mysql://localhost:3306/imooc";
    public static final String USER = "liulx";
    public static final String PASSWORD = "123456";

    public static void main(String[] args) throws Exception {
        //1. 加载驱动程序
        Class.forName("com.mysql.jdbc.Driver");
        //2. 获得数据库连接
        Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
        //3. 创建statement
        Statement stmt = conn.createStatement();
        //4. 执行SQL语句
        ResultSet rs = stmt.executeQuery("SELECT user_name, age FROM imooc_goddess");
        //5. 处理返回结果
        while(rs.next()){
            System.out.println(rs.getString("user_name")+" 年龄:"+rs.getInt("age"));
        }
        //6. 关闭资源
        rs.close();
        stmt.close()
        conn.close();
        
    }
}

Mybatis 主要组件

SqlSessionFactoryBuilder

  • SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。
  • 可配置多个环境以达到多数据源的效果
  • 最佳作用域是方法作用域,一旦创建了 SqlSessionFactory,就不再需要它
 public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
    try {
       XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
       return build(parser.parse());
    } catch (Exception e) {
       throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
       ErrorContext.instance().reset();
       try {
         reader.close();
       }  catch (IOException e) {
         // Intentionally ignore. Prefer previous error.
       }
    }
 }
  
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
       XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
       return build(parser.parse());
    } catch (Exception e) {
       throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
       ErrorContext.instance().reset();
       try {
          inputStream.close();
       } catch (IOException e) {
         // Intentionally ignore. Prefer previous error.
       }
    }
  }
  
  public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }
  
    String resource = "mybatis-cfg.xml";
    //读取mybatis-config.xml文件
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //初始化mybatis,创建SqlSessionFactory类的实例
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, "development");
    

SqlSessionFactory

  • 用于创建 SqlSession
  • 拥有 Configuration
  • 一个数据库对应一个SqlSessionFactory
  • 最佳作用域是应用作用域,单例模式或者静态单例模式。

public interface SqlSessionFactory {
    SqlSession openSession(ExecutorType execType, boolean autoCommit);
    SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
    SqlSession openSession(ExecutorType execType, Connection connection);
    Configuration getConfiguration();
}

SqlSession

  • 封装一系列数据库操作的方法
  • 最佳的作用域是请求或方法作用域
  • 每个线程都应该有它自己的 SqlSession 实例
  • SqlSession 放在一个和 HTTP 请求对象相似的作用域
  • 拥有 Connection、Configuration
  • 内部执行方法是excute、涉及缓存
public interface SqlSession extends Closeable {

    <T> T selectOne(String statement, Object parameter);
    <E> List<E> selectList(String statement, Object parameter);
    <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);
    int insert(String statement, Object parameter);
    int update(String statement, Object parameter);
    int delete(String statement, Object parameter);
    void commit(boolean force);
    void rollback(boolean force);
    List<BatchResult> flushStatements();
    <T> T getMapper(Class<T> type);
    
    void clearCache();
    Configuration getConfiguration();
    Connection getConnection();

<?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="org.mybatis.example.BlogMapper">
  <select id="selectBlog" resultType="Blog">
    select * from Blog where id = #{id}
  </select>
</mapper>

//完全限定名调用
Blog blog = (Blog) session
        .selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
        
//完全限定名可以直接映射到在命名空间中同名的 Mapper 类,并将已映射的 select 语句中的名字、参数和返回类型匹配成方法
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);
// 注解方式,适用简单SQL
package org.mybatis.example;
public interface BlogMapper {
  @Select("SELECT * FROM blog WHERE id = #{id}")
  Blog selectBlog(int id);
}

Executor

  • SqlSession向用户提供操作数据库的方法,但和数据库操作有关的职责都会委托给Executor
  • 把具体的操作委托给子类进行执行

Cache

  • 提供了和缓存相关的最基本的操作
public interface Cache {
  String getId();
  void putObject(Object key, Object value);
  Object getObject(Object key);
  Object removeObject(Object key);
}

原理