MyBatis框架——1.MyBatis核心、基础配置

1.持久层的概念、MyBatis特点介绍

1.1 MyBatis介绍

MyBatis框架——1.MyBatis核心、基础配置_第1张图片

MyBatis 本是 apache 的一个开源项目 iBatis, 2010 年这个项目由 apache software foundation 迁移到了google code,并且改名为 MyBatis 。2013 年 11 月迁移到 Github。
iBATIS 一词来源于“internet”和“abatis”的组合,是一个基于 Java 的持久层框架。iBATIS 提供的持久层框架包括 SQL Maps 和 Data Access Objects(DAOs)。
MyBatis 是支持普通 SQL 查询、存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的 JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和Java 的 POJOs(Plain Ordinary Java Objects,普通的 Java 对象)映射成数据库中的记录。

1.2 持久层的概念、MyBatis的特点

持久层可以将业务数据存储到磁盘,具备长期存储能力,只要硬盘不损坏,在断电或其他情况下,重启系统仍然可以读取出这些数据。一般执行持久任务的都是数据库系统,持久层可以使用巨大的磁盘空间,也比较廉价,但缺点是比较慢。当然慢是针对内存而言,在一般的系统中运行是没有问题的,但如果在互联网秒杀场景下,每秒都要执行成千上万次数据操作,慢是不能承受的,可能导致系统宕机,在这样的场景下考虑使用Redis(NoSQL)来处理。

Java互联网应用可以通过MyBatis框架来访问数据库,如下图所示。

MyBatis框架——1.MyBatis核心、基础配置_第2张图片

而使用MyBatis的原因,是其具备以下几点优势:

  1. 不屏蔽 SQL。这意味着程序员可以更精确的定位SQL语句,可以对其进行优化和改造,这有利于互联网系统性能的提高,符合互联网需要性能优化的特点。
  2. 提供强大灵活的映射机制。它提供动态SQL,允许我们根据不同条件组装SQL,满足各种应用系统的同时也满足了需求经常变化的互联网应用的要求。
  3. 提供Mapper接口编程。这样只需一个接口和一个XML就能创建映射器,进一步简化工作,使很多框架API在MyBatis中消失,让开发者更集中与业务逻辑。

2.MyBatis核心组件

2.1 核心组件关系图

MyBatis的核心组件有以下四个:

  • SqlSessionFactoryBuilder(构造器):它会根据配置或者代码来生成SqlSessionFactory,采用的是分步建造的建造者模式(Builder)。
  • SqlSessionFactory(工厂接口):使用它来生成SqlSession,采用的是工厂模式。
  • SqlSession(会话):一个既可以发送SQL执行返回结果,也可以获取Mapper的接口。在现有的技术中,一般我们会让其在业务逻辑代码中”消失“,使用MyBatis提供的SQL Mapper接口编程技术,能够提高代码的可读性和可维护性。
  • SQL Mapper(映射器):MyBatis新设计的组件,它由一个Java接口和XML文件(或注解)构成,需要给出对应的SQL和映射规则。它负责发送SQL去执行并返回结果。

MyBatis框架——1.MyBatis核心、基础配置_第3张图片

2.2 SqlSessionFactory(工厂接口)

使用MyBatis首先是用配置或者代码去生产SqlSessionFactory,MyBatis提供了构造器SqlSessionFactoryBuilder。一般采用读取配置XML文件的形式生成SqlSessionFactory,读取后通过Configuration类对象构建整个MyBatis的上下文。

SqlSessionFactory是一个接口,在MyBatis中它存在两个实现类:SqlSessionManager和DefaultSqlSessionFactory。一般而言,具体是由DefaultSqlSessionFactory去实现的,而SqlSessionManager使用在多线程的环境中,它的具体实现依靠DefaultSqlSessionFactory。

MyBatis框架——1.MyBatis核心、基础配置_第4张图片

每个基于MyBatis的应用都是以一个SqlSessionFactory的实例为中心的,而SqlSessionFactory的唯一作用就是生产MyBatis的核心接口对象SqlSession,所以说他的责任是唯一的,这样,我们就用单例模式去处理它。

2.3 SqlSession(会话)

在MyBatis中,SqlSession是其核心接口。在MyBatis中有两个实现类,DefaultSqlSession(单线程)和SqlSessionManager(多线程)。SqlSession的作用类似一个JDBC中的Connection对象,代表着一个资源的启用,具体作用有三个:

  • 获取Mapper接口。
  • 发送SQL给数据库。
  • 控制数据库事务。

SqlSession只是一个门面接口,实际进行这些功能操作的是Executor。

由于SqlSession的获取Mapper接口和发送SQL的功能都要先实现映射器的功能,而映射器接口本身也能实现发送SQL功能,所以一般使用映射器(Mapper)直接发送SQL。

2.4 SQL Mapper(映射器)

映射器是MyBatis中最重要、复杂的组件,由一个接口和对应的XML文件(或注解)组成,它可以配置如下内容:

  • 描述映射规则。
  • 提供SQL语句,可以配置SQL参数类型、返回类型、缓存刷新等信息。
  • 配置缓存。
  • 提供动态SQL。

映射器的主要作用就是将SQL查询到的结果映射为一个POJO,或者将POJO的数据插入到数据库中,并定义一些关于缓存的重要内容。

2.4.1 使用SqlSession发送SQL

以后面的实例中getRole这条语句为例,此处的selectOne方法表示使用查询并且只返回一个对象,而参数则是一个String对象和一个Object对象。这里是一个Long参数,是它的主键。

Role role=sqlSession.selectOne("com.ssm.mapper.RoleMapper.getRole",2L);

String对象是由一个命名空间家SQL id组合而成的,它完全定位了一条SQL,使MyBatis能够找到对应的SQL。如果在MyBatis中只有一个id为getRole的SQL,那么也可以简写为:

Role role=sqlSession.selectOne("getRole",2L);

2.4.2 使用Mapper接口发送SQL

SqlSession还可以通过获取Mapper接口,通过其来发送SQL。

RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role = roleMapper.getRole(2L);//指定用户id来查找

通过SqlSession的getMapper方法来获取一个Mapper接口,就可以调用它的方法了。

两种SQL发送方式的比较:

1.使用Mapper接口编程可以消除SqlSession带来的功能性代码,提高可读性,类似roleMapper.getRole(2L)是完全面向对象的语言,更能体现业务的逻辑。

2.使用SqlSession发送SQL,需要一个SQL id去匹配SQL,使用sqlSession.selectOne("getRole",2L)语句,IDE不会提示错误和校验,只有在运行中才能知道是否会产生错误。

现在,Mapper接口编程是主流,建议采用这种方式发送SQL。

2.5 生命周期

生命周期是每一个对象应该存活的时间,比如一些对象一次用完后就要关闭,使他们被JVM销毁,以避免继续占用资源。

生命周期是组件的重要问题,尤其是在多线程的环境中,比如互联网应用、Socket请求等,而MyBatis也常用于多线程的环境中,错误使用会造成严重的多线程并发问题,因此我们需要掌握MyBatis中组件的生命周期。

在实际应用中应该根据每一个组件的作用去确定去生命周期。

2.5.1 SqlSessionFactoryBuilder

它的作用是创建SqlSessionFactory,然后就不再有其它作用了,所以它应该只存在于创建SqlSessionFactory的方法中。

2.5.2 SqlSessionFactory

它可以视为一个数据库连接池,作用就是创建SqlSession接口对象。因为MyBatis的本质就是Java对数据库的操作,所以SqlSessionFactory的生命周期存在于整个MyBatis的应用之中,因此它的生命周期等于MyBatis的应用周期。

2.5.3 SqlSession

如果说SqlSessionFactory相当于数据库连接池,那么SqlSession则相当于一个数据库连接(Connection对象)。我们可以在一个事务里面执行若干条SQL,然后通过commit、roolback等方法进行事务的提交和回滚,因此,它存活在一个业务请求中,处理完这个请求后就应该关闭这条连接,把它归还给SQLSessionFactory,否则数据库资源会被耗尽。

2.5.4 Mapper

Mapper是一个接口,由SqlSession所创建,它代表的是一个请求中的业务处理,所以它应该存活在一个请求中,一旦处理完了相关的也业务,就应该关闭它。

MyBatis框架——1.MyBatis核心、基础配置_第5张图片

3.MyBatis基础配置实例 

 我们在idea上建立一个maven项目,进行基本的MyBatis配置,实现与数据库的连接,完成增删改查基本操作。项目构成如图。

MyBatis框架——1.MyBatis核心、基础配置_第6张图片 

  • Test:测试入口。
  • RoleMapper:映射器Mapper接口。
  • RoleMapper.xml:映射器XML文件,描述映射关系、SQL等。
  • Role:POJO对象。
  • SqlSessionFactoryUitls:用来创建SqlSessionFactory、获取SqlSession对象。
  • mybatis-config.xml:MyBatis配置文件。

3.1 POJO:

public class Role implements Serializable {
    private Long id;
    private String roleName;
    private String note;

/*
    getter and setter
**/
}

 3.2 mapper:

interface:

public interface RoleMapper {
    public int insertRole(Role role);
    public int deleteRole(Role role);
    public int updateRole(Role role);
    public Role getRole(Long id);
    public List findRolds(String roleName);

}

xml文件: 







    
        insert into t_role(role_name,note) values (#{roleName},#{note})
    

    
		delete from t_role where id= #{id}
	

    
		update t_role set role_name = #{roleName}, note = #{note} where id= #{id}
	

    

    

3.3 utils:

public class SqlSessionFactoryUtils {

    private final static Class LOCK = SqlSessionFactoryUtils.class;

    private static SqlSessionFactory sqlSessionFactory = null;

    private SqlSessionFactoryUtils() {}

    public static SqlSessionFactory getSqlSessionFactory() {
        synchronized (LOCK) {
            if (sqlSessionFactory != null) {
                return sqlSessionFactory;
            }
            String resource = "mybatis-config.xml";
            InputStream inputStream;
            try {
                inputStream = Resources.getResourceAsStream(resource);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
            return sqlSessionFactory;
        }
    }


    //代码生成SqlSessionFactory
    public static SqlSessionFactory getSqlSessionFactory2() {
        synchronized (LOCK) {
            //数据库连接池信息
            PooledDataSource dataSource = new PooledDataSource();
            dataSource.setDriver("com.mysql.jdbc.Driver");
            dataSource.setUsername("root");
            dataSource.setPassword("root");
            dataSource.setUrl("jdbc:mysql://127.0.0.1/ssm");
            dataSource.setDefaultAutoCommit(false);
            //采用MyBatis的JDBC事务方式
            TransactionFactory transactionFactory = new JdbcTransactionFactory();
            Environment environment = new Environment("development", transactionFactory, dataSource);
            //创建Configuration对象
            Configuration configuration = new Configuration(environment);
            //注册一个MyBatis上下文别名
            configuration.getTypeAliasRegistry().registerAlias("role", Role.class);
            //加入一个映射器
            configuration.addMapper(RoleMapper.class);

            //注解形式
            //configuration.addMapper(RoleMapper2.class);

            //使用SqlSessionFactoryBuilder构建SqlSessionFactory
            sqlSessionFactory =
                    new SqlSessionFactoryBuilder().build(configuration);
            return sqlSessionFactory;
        }
    }

    public static SqlSession openSqlSession() {
        if (sqlSessionFactory == null) {
            getSqlSessionFactory();
        }
        return sqlSessionFactory.openSession();
    }
}

3.4 main:

public class Test {
    public static void main(String[] args) {
        testRoleMapper();
    }
    private static void testRoleMapper() {
        Logger log = LoggerFactory.getLogger(Test.class);
        SqlSession sqlSession = null;
        try {
            sqlSession = SqlSessionFactoryUtils.openSqlSession();
            RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
            Role role = roleMapper.getRole(2L);//指定用户id来查找
            System.out.println("-----取出的用户:"+role.getRoleName()+"------");
            log.info(role.getRoleName());
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
    }
}

3.5 mybatis-config




    
        
    
    
    
        
            
            
                
                
                
                
            
        
    
    
    
        

    
    
    

运行结果:

MyBatis框架——1.MyBatis核心、基础配置_第7张图片

test中进行了查询id为2的用户名的操作,成功取出了Bill。

MyBatis框架——1.MyBatis核心、基础配置_第8张图片

你可能感兴趣的:(SSM框架学习)