准备MyBatis环境

对于MyBatis的包和源码,我们建议将包和源码都下载下来,对于mybatis的包,我们需要在工程路径下配置引入它。对于源码,我们在分析MyBatis运行原理时会用到。
使用mybatis还可以阅读相关的参考手册,网址是http://www.mybatis.org/mybatis-3/zh/getting-started.html
-解压Mybatis的包,可以得到如下图

image.png

使用MyEclipse环境进行配置,也可以使用包括NetBeans等开发环境,无论什么环境都可以轻松搭建。

  • 右键项目名->properities->add external AJR找到解压后的mybatis的lib包还有mybatis-3.4.1.jar,全部加入即可搭建好MyBatis的开发环境


    image.png

MyBatis的核心组件

  • SqlSessionFactoryBuider(构造器):它会根据配置 或者代码来生成SqlSessionFactory,采用的是分步构建的Builder模式

  • SqlSessionFactory(工厂方法):依靠它来生成Sqlsession,使用的是工厂模式

  • SqlSession(会话):一个既可以发送sql执行返回结果,也可以获取Mapper的接口。在现有的技术中,一般我们会让其在业务逻辑代码中“消失”,而使用的是MyBatis的提供的SQL Mapper接口的编程技术,它能提高代码的可读性,和可维护性

  • SQL Mapper(映射器):MyBatis 新设计存在的组件,它由一个java接口和XML文件构成,需要给出对应的SQL和映射规则则,它负责发送SQL执行,并返回结果

使用XML构建SqlSessionFactory

首先,在MyBatis的XML分为两类,一类是基础配置文件,通常是有一个,主要是配置一些最基本的上下文参数和运行环境;另一类是映射文件,它可以配置映射关系,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>
<typeAlias alias="role" type="com.learn.ssm.chapter3.pojo.Role" />
</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/ssm"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

我们描述一下MyBatis的配置文件:

  • <typeAlias>元素定义了一个别名role。它代表着com.learn.ssm.chapter3.oiji.Role这个类。这样定义后mybatis的上下文都可以使用别名代表全限定名。

  • <enviroment>元素的定义,这里采用描述的是描述库,它里面的<transactionManager>元素是配置事务管理器,这里采用的是MyBatis的JDBC管理器的方式
    然后dataSource元素配置事务管理器,这里采用的是type=“POOLED”代表采用MyBatis内部提供的连接池方式,最后定义一些关于JDBC的属性信息。

  • mapper 元素代表引入的那些映射器,在谈到映射器时会详细讨论它。

通过XML构建SqlSessionFactory

package com.learn.ssm.chapter3.mapper;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class demoFactory{
    
public static void main(String[] args) {
    SqlSessionFactory sqlSessionFactory=null;
    String resource="mybatis-conifg.xml";
    InputStream inputstream;
    try{
        inputstream=Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputstream);
    }catch(IOException e){
        e.printStackTrace();
    }

}

}

首先读取mybatis-config.xml,然后通过SqlSessionFactoryBuilder的builer方法去创建SqlSessionFactory。整个过程比较简单,而里面的步骤还是比较繁琐,只是MyBatis采用了Builder模式为开发者隐藏这些细节。
采用XML创建的形式,信息在配置文件中,有利于以后的代码维护和修改。
补充:

  • Resources
    Resources 类为从类路径中加载资源,提供了易于使用的方法。处理 ClassLoader 是一项
    富于挑战的工作,尤其是应用服务器/容器的情况下。
    加载一个资源有很多方式,包括:
    1.对于简单的只读文本数据,加载为 Reader。
    Reader getResourceAsReader(String resource);
  1. 对于简单的只读二进制或文本数据,加载为 Stream。

Stream getResourceAsStream(String resource);

3.对于可读写的二进制或文本文件,加载为 File。

File getResourceAsFile(String resource);

  1. 对于只读的配置属性文件,加载为 Properties。

Properties getResourceAsProperties(String resource);

  1. 对于只读的通用资源,加载为 URL。
    按以上的顺序,Resources 类加载资源的方法如下:

Url getResourceAsUrl(String resource);

SqlSession

在MyBatis中,SqlSession是其核心接口,在MyBatis中有两个实现类,DefaultSqlSession和SqlSessionManager,前者是单线程使用,后者是多线程使用。
SqlSession的作用类似一个JDBC中的connection对象,代表着一个连接资源的启用。

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

创建SqlSessionFactory创建的SqlSession就十分简单
SqlSession sqlsession=SqlSessionFactory.openSession();
注意,SqlSession只是一个门面,它有很多方法,可以直接发送SQL,它就好像一家软件公司的商务人员,是一个门面,而实际干活的是软件工程师,在MyBatis中,真正干活的是Executor,我们会在底层看到它。

  • Sqlsesssion控制数据库事务的方法
//  定义SqlSession
    SqlSession sqlsession=null;
    try{
//      打开SqlSession会话
        sqlsession=sqlSessionFactory.openSession();
//      some code
        sqlsession.commit();
//      提交事务
        
    }catch(Exception e){
        sqlsession.rollback();
//      回滚事务
    }
    finally{
//      在finally语句中确保资源被关闭
        if(sqlsession!=null){
            sqlsession.close();
        }
    }

这里使用commit方法提交事务,或者使用rollback方法回滚事务,因为它代表着一个数据库的连接资源,使用后要及时关闭它,如果不关闭,那么数据库的连接资源就会很快被耗费光,整个系统就会被陷入崩溃煮状态、所以用finally的语句关闭。
由于SqlSession的获取Mapper接口和发送SQL功能需要先实现映射器的功能,而映射器接口也可以实现发送SQL功能,那么我们应该采取何种方式会更好一些。

映射器:

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

  • 描述映射规则
  • 提供SQL语句,并可以配置SQL参数类型,返回类型,缓存刷新等信息
  • 配置缓存
  • 提供动态SQL
    本节阐述两种实现映射器的方式,XML文件形式和注解形式。
    不过在此之前先定义一个POJO(简单JavaBean类)
package com.learn.ssm.chapter3.pojo;


public class Role {

    private Long id;
    private String roleName;
    private String note;

    /** setter and getter **/
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

}

映射器的主要作用就是将sql查询的结果映射到为一个POJO,或者POJO的数据插入到数据库中,并定义一些关于缓存的重要内容、
注意:开发只是一个接口,而不是一个实现类,接口不能直接运行,mybatis运用了动态代理技术使得接口能运行起来。

用XML实现映射器
public interface RoleMapper {
public Role getRole(Long id);
}

在用XML方式创建SqlSession的配置文件中有这样一段代码:

 <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>

它的作用就是引入一个xml文件,用xml方式创建映射器

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.learn.ssm.chapter3.mapper.RoleMapper">
<select id="getRole" parameterType="long" resultType="role">
select id,role_name as roleName,note from t_role where id=#{id}

</select>
</mapper>


  • <mapper>元素中的属性namespace所对应的是一个接口的权限定名,于是mybatis可以通过上下文找到对用的接口、
  • select元素表明这是一条查询语句,而属性id标识了这条SQL,属性parameterType=“long” 说明传递给SQL的是一个long类型的参数,而resultType=“role‘表明返回的是一个role类型的返回值,而role是之前配置文件mybatisconfig.xml配置的别名,指代的是com.learn.ssm.chapter3.pojo.Role
  • 这条sql#{id}表示的是传递的参数
    注意,我们并没有配置SQL执行后和role的对应关系,它是如何映射的呢?其实这里用的是一种被称为自动映射的功能,这里SQL返回的是列名id和name是可以和之前定义的POJO的属性POJO对应起来即可,而表里的列role_name通过SQL别名的改写,使其成为roleName,也是和POJO对应起来。所以此时的MyBatis就可以把SQL查询的结果通过自动映射的功能映射成为一个POJO

注解实现映射器

不同于xml实现注射器,注解方式之需要一个接口就可以通过MyBatis的注解来注入SQL

package com.learn.ssm.chapter3.mapper;

import org.apache.ibatis.annotations.Select;

import com.learn.ssm.chapter3.pojo.Role;

public interface RoleMapper2 {
@Select("select id,role_name as roleName,note from t_role wherer id=#{id}")
public Role getRole(Long id);
}

这完全等同于XML方式创建映射器,也许你会觉得使用注解的方式比XML方式要简单的多,如果它和XML方式同时定义,XML方式将覆盖掉注解的方式,因此使用官方的xml方式比较好。
XML可以相互使用,而注解是不可以的,所以在一些复杂的环境下,使用XML方式会更加的灵活和方便。
这个注解接口可以在mybatis-config.xmlz中进行配置:

mappers>
    <mapper resource="com/learn/ssm/chapter3/mapper/RoleMapper.xml"/>
    <!--构建SqlsessionFactory -->
     <mapper class="com.learn.ssm.chapter3.mapper.RoleMapper2"/> 
     <!-- 注解实现映射器 -->
  </mappers>

SqlSession发送sql

有了映射器就可以通过SqlSession发送SQL了,我们以getRole这条SQL为例看看如何发送SQL

Role role=(Role)sqlSession.selectOne("com.learn.ssm.chapter3.mapper.RoleMapper.getRole",1L)
常量后面跟这个一般是指类型,1L表示1是长整型,如果是1f 表示是float型

selectOne方法标识使用查询并且只返回一个对象,而参数则是一个String对象和一个Object对象,这里是一个long参数,long参数是它的主键。
String 对象是由一个命名空间加上SQL id组合而成的,它完全定位一条SQL ,这样MyBatis就会找到对应的SQL,如果在MyBatis中只有一个id为getRole的SQL,那么也可以简写成
Role role=()sqlsession.selectOne("getRole" ,1L);

用Mapper接口发送SQL

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

RoleMapper roleMapper=sqlSession.getMapper(RoleMapper.class)
Role role=roleMapper.getRole(1L)

通过SqlSession的getMapper方法来获取一个Mapper接口,就可以调用它的方法了,因为XML文件或者接口注解定义的SQL都可以通过“类的权限定名+方法名”查找。所以MyBatis会启用对应的SQL进行运行,并返回结果、

对比两种发送SQL的方式;
  • 一种用的是SqlSession直接发送,另外一种通过SqlSession获取Mapper接口再发送。
    建议大家使用SqlSession获取Mapper的方式,理由如下:
  • 使用Mapper接口编程可以消除SqlSession带来的功能性代码,提高可读性。而sqlsession发送SQL需要一个SQLID去配对SQL。使用Mapper接口,类似roleMapper.getRole(1L)则是完全面向对象的语言。
  • 使用Mapper.getRole(1L)语法,IDE会提示错误和校验,而使用sqlSession.selectOne('getRole',1L)语法,只有在运行中才能知道是否会产生错误。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,277评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,689评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,624评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,356评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,402评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,292评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,135评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,992评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,429评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,636评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,785评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,492评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,092评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,723评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,858评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,891评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,713评论 2 354

推荐阅读更多精彩内容

  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,519评论 0 4
  • Mybatis介绍 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache...
    day_Sunny阅读 2,662评论 0 6
  • MyBatis 理论篇 [TOC] 什么是MyBatis  MyBatis是支持普通SQL查询,存储过程和高级映射...
    有_味阅读 2,897评论 0 26
  • 总是被这样问:“你干什么了?你在家干什么了?”问的我一脸无辜 不知该如何回答。 早上十点起床 属实有一点晚,习惯了...
    薛艳云阅读 270评论 0 0
  • 暗恋是一个人兵荒马乱,承蒙你的出现,让我体会到小小的心动。我是这样喜欢你,从一而终,认真且怂。
    不认输的靠谱青年阅读 253评论 0 0