MyBatis(一):MyBatis入门

南楼画角 提交于 2020-02-01 15:11:54

MyBatis概述

1.什么是MyBatis

        MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plan Old Java Objects,普通的Java对象)映射成数据库中的记录.

       每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。

        用xml文件构建SqlSessionFactory实例是非常简单的事情。推荐在这个配置中使用类路径资源(classpath resource),但你可以使用任何Reader实例,包括用文件路径或file://开头的url创建的实例。MyBatis有一个实用类----Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。

2.ORM工具的基本思想

无论是用过的hibernate,mybatis,你都可以法相他们有一个共同点:

  • 从配置文件(通常是XML配置文件中)得到 sessionfactory.
  • 由sessionfactory  产生 session
  • 在session 中完成对数据的增删改查和事务提交等.
  • 在用完之后关闭session 。
  • 在Java 对象和 数据库之间有做mapping 的配置文件,也通常是xml 文件。

3.MyBatis和JDBC的比较

 

MyBatis核心组件

MyBatis的核心组件分为4个部分

  • SqlSessionFactoryBuilder(构造器):根据xml或java代码生成SqlSessionFactory。
  • SqlSessionFactory(工厂接口):使用它生成Sqlsession,工厂模式下生成。
  • Sqlsession(会话):可以发送SQL执行返回结果和获取Mapping的接口。在大多数开发中,我们使用MyBatis提供的 SQL Mapping 接口编程技术,这提高了可读性和可维护性。
  • SQL Mapping(映射器):由一个java接口和XML文件(或者是@注解)构成,生成了对应SQL与映射的规则,发送SQL执行并返回结果。

 

SqlSessionFactory

如何使用MyBatis,首先就是xml或java代码生成SqlSessionFactory,MyBatis给我们提供了SqlSessionFactoryBuilder(构造器),org.apache.ibatis.session.Configuration这个类作为引导,使用的是Builder模式。

在MyBatis中有两种形式生成SqlSessionFactory,一种是XML,一种是java代码实现。这里小编推荐使用XML的形式,也是大多数企业开发的选择。配置XML或java代码后,MyBatis会读取配置文件,通过Configuration类对象构建MyBatis的上下文。

需要提醒大家的是SqlSessionFactory是一个接口,而它的实现类为SqlSessionManager和DefaultSqlSessionFactory两个类。

一般用DefaultSqlSessionFactory,DefaultSqlSessionFactory在多线程中,而它的具体实现依靠DefaultSqlSessionFactory。

 

使用XML构建SqlSessionFactory

主要分为两类:一类是基础配置文件,通常只有一个,主要配置最基础的上下文参数和运行环境:另一类为映射文件,主要配置映射关系、SQL、参数等。

基础配置文件:一般命名为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>
    <typeAliases><!--b别名-->
        <typeAlias type="com.feiyu.POJO.User" alias="user" />
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <!-- 配置数据库连接信息 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
                <property name="username" value="root" />
                <property name="password" value="123456" />
            </dataSource>
        </environment>
    </environments>
 
    <mappers>
        <!-- 注册userMapper.xml文件,
        userMapper.xml位于com.feiyu.mapping这个包下,所以resource写成com/feiyu/mapping/userMapper.xml-->
        <mapper resource="com/feiyu/mapping/userMapper.xml"/>
    </mappers>
 
</configuration>

<typeAliases>元素:定义一个别名,代表com.feiyu.POJO.User这个类,在上下文中科院代替全限定名使用。

<environment>元素:默认为开发者,里面的<transactionManager>是配置事务管理器,采用JDBC管理器方式,使用 <dataSource>配置数据库,type="POOLED"为MyBatis内部提供的连接池方式。

<mapping>元素:代表引入的那些映射器。

        //mybatis的配置文件
        String resource = "mybatis-config.xml";
        //使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)
        InputStream inputStream = Test1.class.getClassLoader().getResourceAsStream(resource);
        //构建sqlSession的工厂
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件)
        //Reader reader = Resources.getResourceAsReader(resource);
        //构建sqlSession的工厂
        //SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        //创建能执行映射文件中sql的sqlSession
        SqlSession session = sessionFactory.openSession();
        /*
         * 映射sql的标识字符串,
         * com.feiyu.mapping.userMapper是userMapper.xml文件中mapper标签的namespace属性的值,
         * getUser是select标签的id属性值,通过select标签的id属性值就可以找到要执行的SQL
         */
        String statement = "com.feiyu.mapping.userMapper.getUser";//映射sql的标识字符串
        //执行查询返回一个唯一user对象的sql
        User user = session.selectOne(statement, 1);
        System.out.println(user);

读取mybatis-config.xml,然后通过SqlSessionFactoryBuilder的Builber方法创建SqlSessionFactory。

 

SqlSession

作用相当于一个JDBC中的Connection对象,代表一个连接资源的启用。有以下三个作用:

  1. 获取Mapping接口
  2. 发送SQL给数据库
  3. 控制数据库事务
SqlSession sqlSession = SqlSessionFactory.openSession();

下面我们来看看SqlSession在操作事务时的伪代码:

//定义SqlSession
SqlSession sqlSession = null;
try{
    //打开SqlSession会话
    sqlSession = SqlSessionFactory.openSession();
    sqlSession.commit();//提交事务
}catch (Exception ex) {
    sqlSession.rollback();//回滚事务
}finally {
    //在finally语句中确保资源被顺利关闭
    if (sqlSession != null) {
       sqlSession.close();
    }
}

使用commit方法提交事务,和使用rollback方法回滚事务。

注意:数据库的连接资源使用后要及时的关闭它,如果不及时关闭,数据库的连接资源就会很快被消耗光,整个系统将陷入瘫痪状态,所以这里使用finally语句使其顺利关闭。

 

映射器

在MyBatis中,映射器尤为的重要,也是最复杂的组件,它是由一个接口和对应的XML文件(或@注解)构成。

有以下4个作用:

  1. 描述映射规则
  2. 配置缓存
  3. 提供SQL语句,配置SQL参数类型,返回类型,缓存刷新等
  4. 提供动态SQL

 本文只实现XML文件形式映射器方式,也是大多数开发的选择,下面首先定义一个POJO:

package com.feiyu.POJO;
/**
 * @author gacl
 * users表所对应的实体类
 */
public class User {
    //实体类的属性和表的字段名称一一对应
    private int id;
    private String name;
    private int age;
 
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
    }
}

映射器接口

package com.feiyu.mapping;
 
import com.feiyu.POJO.User;
 
public interface UserMapper {
    public User getUser(int id);
}

引入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="com.feiyu.mapping.UserMapper">
    <!--
        根据id查询得到一个user对象
     -->
    <select id="getUser" parameterType="int"
            resultType="com.feiyu.POJO.User">
        select id, user_name as username, age from tb_user where id = #{id}
    </select>
</mapper>

<mapper>元素:其中的namespace对应的是一个接口的全限定名,这样MyBatis就可以根据上下文找到对应的接口

<select>元素:表明这是一个查询的语句,id作为标识,parameterType="int"说明是传递给SQL是一个int型的参数, resultType="com.feiyu.POJO.User">表明返回的是一个user类型的返回值。

 

用Mapper接口发送SQL

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUser(1);

目前使用Mapper接口编程已成主流,在spring中更为常见

 

MyBatis生命周期

生命周期在MyBatis之中是一个不能忽略的问题,在互联网应用的时代,多线程环境无处不在,所以MyBatis的也经常用于多线程环境中,如果错误的使用将会造成严重的多线程并发问题,导致系统的完全崩溃!

那么什么是生命周期呢?广义上来讲,生命周期就是指一个对象的生老病死(这个对象可以指代很多事物)。在 java 的世界里,我们用完一个对象时,或者说要关闭时,这个对象将被 JVM (java虚拟机)销毁,从而避免继续占用资源,合理的创建、使用、销毁对象对于一个程序来说是非常重要的!

本文中列出了4个MyBatis的核心组件(如需了解详情请阅读上一篇文章(二)MyBatis核心组件)

  • SqlSessionFactoryBuilder(构造器)
  • SqlSessionFactory(工厂接口)
  • Sqlsession(会话)
  • SQL Mapper(映射器)

SqlSessionFactoryBuilder
SqlSessionFactoryBuilder的作用在于创建SqlSessionFactory,创建成功后,SqlSessionFactoryBuilder就失去了作用,所以它只能存在于创建SqlSessionFactory的方法中,而不要让其长期存在。

SqlSessionFactory
SqlSessionFactory可以被认为是一个数据库连接池, 它的作用是创建Sission接口对象。因为MyBatis的本质就是Java对数据库的操作,所以SqlSessionFactory的生命周期存在于整个MyBatis的应用之中,所以一旦创建 了SqlSessionFactory,就要长期保存它,直至不再使用MyBatis应用,所以可以认为SqlSessionFactory的生命周期就等同于MyBatis的应用周期。由于SqlSessionFactory 是一个对数据库的连接池,所以它占据着数据库的连接资源,如果创建多个SqlSessionFactory, 那么就存在多个数据库连接池,这样不利于对数据库资源的控制,也会导致数据库连接资源被消耗光,出现系统宕机等情况,所以尽量避免发生这样的情况。因此在一般的应用中我们往往希望SqlSessionFactory作为一个单例(Singleton), 让它在应用中被共享。

SqlSession
如果说SlssonFactory相当于数据库连接池,那么SqlSession就相当于一个数据库连接(Conection对象),你可以在一个事务里面执行多条SQL,然后通过它的commit、rollback等方法,提交或者回滚事务。所以它应该存活在一个业务请求中,处理完整个请求后,应该关闭这条连接,让它归还给SqlSessionFactory, 否则数据库资源就很快被耗费精光,系统就会瘫痪,所以用try{}catch{} fnally{}语句来保证其正确关闭。

//定义SqlSession
SqlSession sqlSession = null;
try{
    //打开SqlSession会话
    sqlSession = SqlSessionFactory.openSession();
    sqlSession.commit();//提交事务
}catch (Exception ex) {
    sqlSession.rollback();//回滚事务
}finally {
    //在finally语句中确保资源被顺利关闭
    if (sqlSession != null) {
       sqlSession.close();
    }
}

Mapper
Mapper是个接口, 它由Ssesion所创建,所以它的最大生命周期至多和SqlSession一致,随着SqlSession的关闭,它的数据库连接资源也会消失,所以。Mapper生命周期SqlSession生命周期。Mapper是一个请求中的业务处理,所以它应该在一个请求中, 当相关业务处理完毕后就应该销毁它。

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!