Mybatis学习日记(一)

声明:本人通过《深入浅出MyBatis技术原理与实战》来完成学习并总结如文。


Hibernate的相关缺点

1. 全表映射带来的带来的不便,更新要发送所有字段
2. 无法根据不同条件组装SQL
3. 对多表关联和复杂SQL查询支持较差,需要自己写SQL,返回后需要自己将数据组装成POJO
4. 不能有效支持存储过程
5. 性能差,无法做到SQL优化

# POJO:Plain Ordinary Java Objecdt数据库的表和简单JAVA对象的映射关系模型

mybatis

简单介绍:

mybatis是一个基于JAVA的持久层框架。与Hibernate的不同是:除了提供映射文件,还需要提供SQL语句。mybatis提供的映射文件主要包含以下三个部分:
- SQL
- 映射规则
- POJO

mybatis的核心组件:

  • SqlSessionFactoryBuilder(构造器):根据配置信息或代码来生成SqlSessionFactory(工厂接口)
    • 实现方式:
String resource = "mybatis-config.xml";
InputStream inputStream = Resource.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = null;
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputstream);
  • SqlSessionFactory:打开SqlSession(会话)
    • 实现方式:
SqlSession sqlSession = null;
try{
sqlSesssion = sqlSessionFactory.openSesson();
//And code you need
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
}finally{
if(sqlSession != null){
sqlSession.close();
}
}
  • SqlSession:一个发送SQL去执行得到返回结果,并且获取Mapper的接口

    • 类似于前台的一个作用,我们把信息(功能、参数)交给前台(Session),然后前台返回我们需要的结果(Result)。它类似于JDBC里的Connection,当我们完成操作后,需要显示关闭它
    • MyBatis中的SqlSession接口有两种:
      • DefaultSqlSession
      • SqlSessionManager
  • SQL Mapper:由一个Java接口和XML文件(或注解)构成,需要给出对应的SQL和映射规则。负责发送SQL去执行,并返回结果。

简单实现过程:

  1. 创建SqlSessionFactory

    1. 形象化的说法通过一个工厂建造工具来建造一个工厂,这个工具就是上面说的SqlSessionFactoryBuilder
    2. 有两种建造方式:一种通过XML,一种通过JAVA代码,mybatis-config.xml代码的配置,不做赘述,玩家可以自己去搜索
  2. 通过SqlSessionFactory提供一个SqlSession

    打开Session的一般方式正如上文所说,而关于Session的具体用途主要有一下两种:

    1. 获取映射器,让映射器通过命名空间和方法名称找到对应的SQL,发送给数据执行并返回结果。
    2. 直接通过命名信息去执行SQL返回结果,在SqlSession层可以通过update、insert、select、delete等方法,带上SQL的id来操作在XML中配置好的SQL;也支持事务,通过commit、rollback方法提交或者回滚事务。
  3. 通过Mapper来映射数据库项和Java对象,也就是所谓的映射器(映射器是Mybatis的核心内容)

    映射器主要是由Java接口和XML文件共同组成,它(映射器)主要有这样几个功能:

    1. 定义参数类型
    2. 描述缓存
    3. 描述SQL语句
    4. 定义查询结果和POJO的映射关系

    关于映射器的实现,主要也有两种方式:

    1. XML文件方式:在mybatis-config.xml文件中通过如下语句描述了一个xml
      <mappers>
      <mapper resource = "com/blaze/mybatis_try/mapper/Mapper.xml/>
      </mapper>

    它是用来生成Mapper的。

    1. 代码方式:主要是通过在Configuration里面注册Mapper接口,并且写入Java注解。(关于这种方式,各位同学可以自行搜索了解)

    关于映射器实现方式的选择,原书作者给了如下建议:

    强烈建议选择XML的方式实现,理由如下:

    1. SQL很复杂条件很多的情况下,写在Java文件里可读性较差,增加维护成本
    2. 功能不对等,Java注解是受限的而且功能有限,但是Mybatis的Mapper内容相当多而且复杂,并且在功能上非常强大,使用Java注解的方式,对Mybatis的灵活性和功能都会有所损耗。而选择XML实现方式,可以带来更为灵活的空间,体验Mybatis功能的强大和灵活。

核心组件的生命周期

理解生命周期的理由:如果不正确理解Mybatis组件的生命周期可能带来很严重的并发问题,影响对Mybatis应用的正确性和高性能。


  1. SqlSessionFactoryBuilder

SqlSessionFactoryBuilder的作用就是通过XML或者Java代码来建造一个工厂(SqlSessionFactory),并且可以通过它建造多个这样的工厂。一旦完成建造工厂的任务,我们就应该废弃它,回收空间。所以它的生命周期只存在方法局部,完成工厂的建造即结束。

  • SqlSessionFactory
    SqlSessionFactory的作用就是创建会话(SqlSession),相当于JDBC的Connection连接。每当我们需要访问数据库时,就要通过SqlSessionFactory创建会话,所以SqlSessionFactory的生命周期应该是整个Mybatis的生命周期。但是如果打开过多的SqlSession,就相当于JDBC创建了过多的Connection,那么连接资源就会很快被耗尽,所以对于每一个数据库,只对应一个SqlSessionFactory,以此来管理数据资源的分配,防止连接资源被过度消耗。
  • SqlSession
    SqlSession相当于JDBC的connnection,生命周期应该是在请求数据库处理事务的过程中,它存活于一个应用的请求和操作,可以执行多个SQL,保证事务的一致性。此外,它还是个线程不安全的对象,在多线程中应当注意数据库的隔离级别和数据库锁等高级特性。并且当SqlSession完成自身工作时需要及时关闭,以防止数据库连接池的活动资源减少,影响系统性能。
  • Mapper
    Mapper是一个接口,没有任何实现类,作用是发送SQL,返回所需结果。所以它的生命周期应该在一个SqlSession事务方法之内,是一个方法级别的东西,一旦完成一个事务的操作,即可废弃。

配置

\# Mybatis的配置文件对整个Mybatis体系有着很重要的作用,而且具有规定的层次,这些层次是不能随意点到顺序的,颠倒顺序会导致Mybatis在解析XML时出现异常。

Mybatis配置文件层次结构

<?xml version="1.0" encoding="UTF-8"?>
<configuration><!--配置-->
    <properties/><!--属性-->
    <setting/><!--设置-->
    <typeAliases/><!--类型别名-->
    <typeHanlders/><!--类型处理器-->
    <objectFactory/><!--对象工厂-->
    <plugins/><!--插件-->
    <environments><!--配置环境-->
        <environment><!--环境变量-->
            <transactionManager/><!--事务管理器-->
            <dataSource/><!--数据源-->
        </environment>
    </environments>
    <databaseIdProvider/><!--数据库厂商标识-->
    <mapper/><!--映射器-->
</configuration>
properties元素
Mybatis提供三种配置方式:
  1. property子元素
    1. 首先在属性标签中进行配置:
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
</properties>
2. 然后可以再dataSource中使用配置好的属性值,例如:
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
</dataSource>
  1. properties配置文件
    1. 首先写properties配置文件:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis
2.再mybatis-config.xml中进行导入:
<properties resource="jdbc.properties"/>
  1. 程序参数传递

    1. 使用理由:

      实际工作中,系统是由运维人员配置,生产数据库的用户密码对于开发者而言是保密的,为了系统的安全,运维人员要求对配置文件中的数据库用户和密码进行加密,这样我们的配置文件中往往配置的事加密过后的数据库信息,这个时候只能用编码的方式来传递我们所需要的数据库信息。

    2. 假设jdbc.properties的username和password两个属性使用了加密的字符串,首先需要在生成SqlSessionFactory之前,将所需信息转换为明文,接下来使用系统提供的decode(str)方法

      InputStream cfgStream = null;
      Reader cfgReader = null;
      InputStream proStream = null;
      Reader proReader = null;
      Properties properties = null;
      try{
          //读入配置文件流
          cfgStream = Resources.gerResourceAsStream("mybatis-confg.xml");
          cfgReader = new InputStreamReader(cfgStream);
          //读入属性文件
          proStream = Resources.getResourceAsStream(jdbc.properties);
          proReader = new InputStreamReader(proStream);
          properties = new Properties();
          properties.load(proReader);
          //解密为明文
          properties.setProperty("username",decode(properties.getProperty("username")));
          properties.setProperty("password",decode(properties.getProperty("password")));
      }
作者建议:

注意点:当这三种方式同时应用在一次配置中时,第一种方式下的配置信息首先被读取出来,然后再通过第二种方式读取配置信息,并且覆盖已经被读取出的同名属性,最后才对使用第三种方式的配置信息进行读取,并继续产生覆盖。所以通过第三种方式创建的配置信息具有最高优先级。
在实际的操作中,主要注意以下2点:
1. 不要使用混合的方式来对配置信息进行声明
2. 首选第一种方式

如果我们需要对其进行加密或者其他加工以满足特殊的要求,建议使用第三种方式。可以使配置都来自于同一个配置文件,不容易产生没有必要的歧义,同时方便管理

设置(settting)

一般情况下我们都不需要去配置它,或者只需要配置少数几项,由于表格过于庞大,还请读者自己动手去查阅mybatis配置文件相关设置配置信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值