文档章节

Mybaties入门介绍

王子城
 王子城
发布于 07/22 23:38
字数 2193
阅读 51
收藏 0

    Mybaties和Hibernate是我们在Java开发中应用的比较多的两个ORM框架。当然,目前Mybaties正在慢慢取代Hibernate,这是因为相比较Hibernate而言Mybaties性能更好,响应更快,更加灵活。我们在开发当中也深有感觉,虽然在使用Mybaties的时候我们需要自己编写SQL,但是这样一来我们的系统业务更加灵活,可以应对互联网目前需求变化比较快的特点。不过,归根结底这些框架都是对JDBC的封装(所以JDBC的代码运行效率比这些框架更高一些),这样做都是为了让我们开发起来更加简单快捷。

一、Mybaties核心组件

    SqlSessionFactoryBuilder(构造器):通过Builder模式(建造者模式)来创建Sqlsessionfactory,创建成功后SqlSessionFactoryBuilder就没有作用了,所以它只存在于创建Sqlsessionfactory的方法中。

    SqlSessionFactory(工厂接口):使用工厂模式来生成SqlSession。

    SqlSession(会话):既可以发送SQL执行返回结果,也可以获取Mapper接口。

    SQL Mapper(映射器):由java接口和XML文件(或者注解)构成,主要作用是发送SQL去执行并返回执行结果。

    在这里我们要了解一点,SqlSessionFactory和SqlSession这些都不是类,而是接口。这里利用了设计模式,通过接口可以调用不同的实体类完成系统功能。

二、SqlSessionFactoryBuilder

    SqlSessionFactoryBuilder是一个实体类,它没有继承类或者实现任何接口。如下代码所示,整个类中只实现了build方法,这个build方法是用来创建SqlSessionFactory实例的。虽然下面build方法比较多,但是细细看一下会发现总共只有三个比较重要的方法:

build(Reader reader, String environment, Properties properties)
build(InputStream inputStream, String environment, Properties properties)
build(Configuration config)

前两种方法是通过java方式来创建SqlSessionFactory实例的,唯一区别在于输入的是字节流还是字符流,第三个是通过读取xml配置文件的方式来创建SqlSessionFactory实例,仔细看一下会发现通过读取配置文件创建SqlSessionFactory实例的方式的返回类型和其它方法的返回类型不一样,返回类型为DefaultSqlSessionFactory,这个我们在下面介绍SqlSessionFactory的时候讲解。

public class SqlSessionFactoryBuilder {
    public SqlSessionFactoryBuilder() {
    }

    public SqlSessionFactory build(Reader reader) {
        return this.build((Reader)reader, (String)null, (Properties)null);
    }

    public SqlSessionFactory build(Reader reader, String environment) {
        return this.build((Reader)reader, environment, (Properties)null);
    }

    public SqlSessionFactory build(Reader reader, Properties properties) {
        return this.build((Reader)reader, (String)null, properties);
    }

    public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
        SqlSessionFactory var5;
        try {
            XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
            var5 = this.build(parser.parse());
        } catch (Exception var14) {
            throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
        } finally {
            ErrorContext.instance().reset();

            try {
                reader.close();
            } catch (IOException var13) {
                ;
            }

        }

        return var5;
    }

    public SqlSessionFactory build(InputStream inputStream) {
        return this.build((InputStream)inputStream, (String)null, (Properties)null);
    }

    public SqlSessionFactory build(InputStream inputStream, String environment) {
        return this.build((InputStream)inputStream, environment, (Properties)null);
    }

    public SqlSessionFactory build(InputStream inputStream, Properties properties) {
        return this.build((InputStream)inputStream, (String)null, properties);
    }

    public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
        SqlSessionFactory var5;
        try {
            XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
            var5 = this.build(parser.parse());
        } catch (Exception var14) {
            throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
        } finally {
            ErrorContext.instance().reset();

            try {
                inputStream.close();
            } catch (IOException var13) {
                ;
            }

        }

        return var5;
    }

    public SqlSessionFactory build(Configuration config) {
        return new DefaultSqlSessionFactory(config);
    }
}

三、SqlSessionfactory

    SqlSessionFactory可以被看做是一个数据库连接池,它的作用是创建SqlSession接口对象。由于Mybaties的本质是java对数据库的连接操作,所以SqlSessionFactory的生命周期存在于整个Mybaties的应用中,SqlSessionFactory一旦被创建就会长久保存知道mybaties不再使用,也可以说SqlSessionFactory的生命周期等同于Mybaties的生命周期。由于作为数据库连接池SqlSessionFactory会一直占据着系统的资源,所以SqlSessionFactory一般会作为一个单例被系统共享以避免多过创建SqlSessionFactory消耗资源。

    SqlSessionFactory有两种创建方式我们前面已经提到过,一种是通过java代码的方式,另一种是通过读取xml文件的方式。

    这里先将java代码的方式创建SqlSessionFactory,上面SqlSessionFactoryBuilder类的最下面一个方法就是通过java方式构建SqlSessionFactory如下代码Configuration类(具体这个类建议自己在源码里面开一下,这个类构建了整个Mybaties的上下文)中放置了所有创建SqlSessionFactory所需要的配置信息 ,这里返回的是DefaultSqlSessionFactory而不是SqlSessionFactory的原因是因为SqlSessionFactory仅仅是一个接口,而DefaultSqlSessionFactory则是它的实现类。具体SqlSessionFactory有两个实现类,DefaultSqlSessionFactory和SqlSessionManager,DefaultSqlSessionFactory是在单线程下使用的,SqlSessionManager是在多线程下使用。

public SqlSessionFactory build(Configuration config) {
        return new DefaultSqlSessionFactory(config);
    }

    在SqlSessionFactoryBuilder中其它的方法都是通过xml的方式构建在SqlSessionFactory。当然,通过在xml方式才是我们最经常使用的方式。仔细看看上面方式虽然很多,但是具体的都是调用了两个方法,如下代码,这两个方法的区别在于一个是通过字节流一个是通过字符流。

public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
	SqlSessionFactory var5;
	try {
		XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
		var5 = this.build(parser.parse());
	} catch (Exception var14) {
		throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
	} finally {
		ErrorContext.instance().reset();

		try {
			reader.close();
		} catch (IOException var13) {
			;
		}

	}

	return var5;
}

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
	SqlSessionFactory var5;
	try {
		XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
		var5 = this.build(parser.parse());
	} catch (Exception var14) {
		throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
	} finally {
		ErrorContext.instance().reset();

		try {
			inputStream.close();
		} catch (IOException var13) {
			;
		}

	}

	return var5;
}

    通过java或者xml构建SqlSessionFactory的代码这里就不作展示网上这些应该很多。

四、Sqlsession

    SqlSession是由SqlSessionFactory创建,如果说SqlSessionFactory是数据库连接池,那么SqlSession就相当于一个数据库连接。SqlSession创建如下:

SqlSession sqlSession = SqlSessionFactory.openSession();

    SqlSession作为一个接口,它有两个实现类:DefaultSqlSession和SqlSessionManager。DefaultSqlSession是在单线程下使用的,SqlSessionManager是在多线程下使用。SqlSession的作用类似于JDBC中的Connection对象,代表着一个连接资源的启用。具体有三个作用:获取Mapper接口、发送SQL给数据库和控制数据库事物。当然,SqlSession只是一个门面接口,在Mybaties真正干活的是Executor,它同样是一个接口,由实现类去完成对应功能。

public interface Executor {
    void execute(Runnable var1);
}


    这里有一个问题SqlSessionManager既是SqlSessionFactory的实现类又是SqlSession的实现类,而且都是在多线程下使用的,这个是因为SqlSessionManager同时实现了这两个接口。这个代码下去可以好好研究一下。

    不过,SqlSession想要实现这些功能不容易,因为它不仅需要SqlSessionFactoryBuilder和SqlSessionFactory为其创造实例,还需要映射器完成映射功能。

五、映射器(Mapper)

    映射器可以分为两个部分:接口和xml。我们一般通过接口中的方法名去对应xml中对应sql的id去执行映射。如下图是一个基本的例子。

    其实除了使用xml还有一种使用注解实现映射器的方式,这个就是通过注解在接口的方法上编写SQL语句,由于这样做局限性比较大,所以在这里就不多做介绍。

    同样,映射器也有一个核心接口Mapper,这个接口是由Sqlsession创建,因此它的生命周期和SqlSession一致或者小于SqlSession的生命周期。Mapper接口可以协助SqlSession来发送SQL。我们上面再SqlSession中讲过它有发送SQL的功能,我们可以打开SqlSession的实现类DefaultSqlSession方法查看里面的方法这里是一个简单的selectOne方法,SqlSession本身可以通过这个方法来发送SQL。SqlSession自身在映射器实现映射的基础上可以发送Sql,但是SqlSession同时也可以通过Mapper接口发送SQL。但是,我们现在一般使用Mapper来发送SQL,因为相较于SqlSession自身来发送SQL而言,使用Mapper发送SQL可以消除SqlSession带来的功能性代码,提高可读性。

 

个人理解:这些基础的东西光看是没用的动手去写一下然后再回过头来看一下这写东西才能够体会到它们的作用,如果连Mybaties的基本配置都不会,光看这些理论会越看越糊涂。Mybaties的这些基础理论个人理解就一级一级的创建Mybaties执行需要的组件,SqlSessionFactoryBuilder作为一个实体类生成SqlSessionfactory接口的实例,SqlSessionfactory通过自身的实现类DefaultSqlSessionfactory生成SqlSession的实例,而SqlSession通过Executor执行器配合映射器完成Mybaties的功能,实际上我们平时写代码的时候接触较多的应该是Executor处理器和映射器。

 

© 著作权归作者所有

共有 人打赏支持
王子城
粉丝 3
博文 24
码字总数 21621
作品 0
武汉
程序员
有没有人在Jfinal中集成MyBaties,用MyBaties代替ActiveRecord

有没有人在Jfinal中集成MyBaties,用MyBaties代替ActiveRecord? 在使用JFinal中时,如果业务是和计算相关的时候,弱对象类型的Model就有些不合适了,一个好的思路是使用类似MyBaties的方式,...

萝卜哥
2013/12/06
2.7K
10
mybatis的mapper的代理学习

使用mybatis不用写实现dao实现类,其中注意配置文件中mapper配置中namespace必须是dao的接口的全路径,配置文件中的(select,insert,update)标签ID必须和Dao接口的方法名一致。 注意sprin...

hello_hp
2017/10/19
0
0
mybaties怎么使用Jpa注解?我的意思是用mybaties的jpa标注的bean进行保存的时候是调什么方法保存?mybaties支持JPS注解吗

mybaties怎么使用Jpa注解?我的意思是用mybaties的jpa标注的bean进行保存的时候是调什么方法保存?mybaties支持JPS注解吗

554330833a
2016/06/16
223
1
mybaties怎么使用Jpa注解?

mybaties怎么使用Jpa注解?我的意思是用mybaties的jpa标注的bean进行保存的时候是调什么方法保存

554330833a
2016/06/16
157
1
org.apache.ibatis.builder.IncompleteElementException: Could not find parameter map

由于公司操作数据库的方式使用mybatis,由于个人以前没有用过,才学不久,写好了mapper.xml编译的时候,居然报了这个错误: 其实,使用MyBaties在编写sql配置文件时,都会遇到的一个小问题,...

双月通天
2016/09/21
104
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

qduoj~前端~二次开发~打包docker镜像并上传到阿里云容器镜像仓库

上一篇文章https://my.oschina.net/finchxu/blog/1930017记录了怎么在本地修改前端,现在我要把我的修改添加到部署到本地的前端的docker容器中,然后打包这个容器成为一个本地镜像,然后把这...

虚拟世界的懒猫
今天
1
0
UML中 的各种符号含义

Class Notation A class notation consists of three parts: Class Name The name of the class appears in the first partition. Class Attributes Attributes are shown in the second par......

hutaishi
今天
1
0
20180818 上课截图

小丑鱼00
今天
1
0
Springsecurity之SecurityContextHolderStrategy

注:下面分析的版本是spring-security-4.2.x,源码的github地址是: https://github.com/spring-projects/spring-security/tree/4.2.x 先上一张图: 图1 SecurityContextHolderStrategy的三个......

汉斯-冯-拉特
今天
1
0
LNMP架构(Nginx负载均衡、ssl原理、生成ssl密钥对、Nginx配置ssl)

Nginx负载均衡 网站的访问量越来越大,服务器的服务模式也得进行相应的升级,比如分离出数据库服务器、分离出图片作为单独服务,这些是简单的数据的负载均衡,将压力分散到不同的机器上。有时...

蛋黄_Yolks
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部