Mybaties入门介绍

    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同时实现了这两个接口。这个代码下去可以好好研究一下。

af9e53587b67ca6fd6f9bf5e45f4b2728d0.jpg

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

五、映射器(Mapper)

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

99e4dbbbad70342c9efceae901aaf517b8f.jpg2b6444f8ef519f9a9d58e7c96402df04179.jpg

    其实除了使用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处理器和映射器。

 

转载于:https://my.oschina.net/zicheng/blog/1861117

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值