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代码的配置,不做赘述,玩家可以自己去搜索
  1. 通过SqlSessionFactory提供一个SqlSession

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

  1. 获取映射器,让映射器通过命名空间和方法名称找到对应的SQL,发送给数据执行并返回结果。
  2. 直接通过命名信息去执行SQL返回结果,在SqlSession层可以通过update、insert、select、delete等方法,带上SQL的id来操作在XML中配置好的SQL;也支持事务,通过commit、rollback方法提交或者回滚事务。
  1. 通过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),并且可以通过它建造多个这样的工厂。一旦完成建造工厂的任务,我们就应该废弃它,回收空间。所以它的生命周期只存在方法局部,完成工厂的建造即结束。

  1. SqlSessionFactory

SqlSessionFactory的作用就是创建会话(SqlSession),相当于JDBC的Connection连接。每当我们需要访问数据库时,就要通过SqlSessionFactory创建会话,所以SqlSessionFactory的生命周期应该是整个Mybatis的生命周期。但是如果打开过多的SqlSession,就相当于JDBC创建了过多的Connection,那么连接资源就会很快被耗尽,所以对于每一个数据库,只对应一个SqlSessionFactory,以此来管理数据资源的分配,防止连接资源被过度消耗。

  1. SqlSession

SqlSession相当于JDBC的connnection,生命周期应该是在请求数据库处理事务的过程中,它存活于一个应用的请求和操作,可以执行多个SQL,保证事务的一致性。此外,它还是个线程不安全的对象,在多线程中应当注意数据库的隔离级别和数据库锁等高级特性。并且当SqlSession完成自身工作时需要及时关闭,以防止数据库连接池的活动资源减少,影响系统性能。

  1. 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. 使用理由:

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

    1. 假设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配置文件相关设置配置信息。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容