这里我们就使用Eclipse创建一个最简单的Java Project就好了,MyBatis说白了也是实现VO到数据库表的映射,所以我们准备类文件以及数据库的表。类的定义如下:
数据库表的定义如下:
从网上百度一下就可以找到Mybatis的jar包下载的地方,我们最好是将Mybatis的源代码的jar包和依赖的jar包都扔到自己的DEMO空间下面,方便后面的学习。
点击我们的JavaProject,然后选择属性,找到buildPath将Mybatis下面的jar包引入到当前的项目中。
下面是我引入的jar包的列表:
asm-3.3.1.jar
cglib-2.2.2.jar
commons-logging-1.1.1.jar
javassist-3.17.1-GA.jar
log4j-1.2.17.jar
log4j-api-2.0-rc1.jar
log4j-core-2.0-rc1.jar
mybatis-3.2.6.jar
mysql-connector-java-3.1.6-bin.jar
slf4j-api-1.7.5.jar
slf4j-log4j12-1.7.5.jar
在src文件夹的下面创建了一个文件,将其命名为MyBatis-config.xml,里面的内容如下:
下面是对这个文件中的元素进行的简单介绍:
MyBatis文件的内容是非常复杂的,这里只是几个必要的文件,上面的第一行,也就是?xml的一行,是XML文件要求的,我们在xml文件中都会看到这一行的内容。第二行的内容是用来解析当前XML的dtd文件的,dtd文件中规定了当前的文件由什么内容组成,对XML起了约束作用。根据XML的规范,当前的XML只有一个根元素,这个根元素的名字被命名为configuration,这个基本的XML中,含有了三个子节点,第一个子节点是setting,第二个子节点的内容是environments第三个子节点的内容是mapper。当然,它可以有更多的配置,但基于当前的文档,我们依次来看这三个节点的作用。
第一个节点是setting,顾名思义,这个是mybatis的配置项,一个软件的灵活程度取决于可以配置的项。在这一点上mybatis提供了大量的配置项,logImpl=LOG4J这里,我们采用这样的配置命令MyBatis采用Log4j来实现日志功能。
第二个节点是environments,在这个项目中,可以配置多个环境,在这个节点中,我们配置的是数据库相关的信息,默认的环境是development,这个节点中transactionManager是用来配置事务属性的,事务在数据库处理的作用的重要性是毋庸置疑的。如何配置事务也是在框架设计中一个非常重要的事情,可以这么说,凡是影响到业务数据准确性的设置,都是非常严重,并且必须给予充分重视的。下面的dataSource是用来配置dataSource所需要的必要选项,使用一个dataSource我们必须要提供必要的信息,这些信息主要是用来描述连接到哪一个数据库以及使用什么样子的信息来连接数据库:数据库的URL地址,端口号,使用什么样子的驱动,用户名,密码,在这个DEMO中,上面的配置采用了POOLED的数据源,这样配置项中肯定还有一些关于数据库连接池的配置项,这里我们全部采用默认了。
第三个节点,是mapper,这是一个非常重要的文件,它的主要作用就是建立了Object与数据库表之间的映射关系,更确切的来说,通过在Mapper中配置SQL语句,来建立SQL语句查询结果集与Object的映射关系,从而隐藏java文件中对象与数据库表之间的实现。这其实与Hibernate做的是一个差不多的事情,只是一个是前言中说的机床与削皮机的区别了。
在src文件夹的下面,建立一个名字叫做tiger.xml的文件,这个文件主要是建立数据库表与对象的映射关系,这个文件中的语句如下;
对这个简单的文件的一点描述,第一行,仍旧是我们喜闻乐见的XML的描述符,所有的XML文件中,都很容易找到这一行,第二行,是当前文件的dtd文件。下面就是建立了一个映射mapper,具体描述了如何通过数据库表找到对应的对象。其中的#{id},告诉我们,这个select语句缺少一个名字为id的参数,增加了这个参数之后,就可以执行这条sql语句得到对应的java对象。
根据官方文档中的有关几个重要对象声明周期的描述,我们将SqlSessionFactory通过简单单例模式的方式来创建对象。相关的代码如下,在Src文件夹的下面创建一个名字为: MybatisUtil的文件,这个文件中的内容下:
这个工具类的作用就是在第一次请求的SqlSessionFactory的时候实例化一个对象,如果后面继续请求该对象的时候,直接返回该对象的实例。其中,上面的Resources对象是Mybatis提供的用于找到xml文件的一个公共类,我们在使用的时候直接按照上面的顺序调用就可以了。
但是这里需要明白几个概念,这几个概念分别是Resources、SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper对于这五个对象,依次做一个说明:
Resources是Mybatis提供的用于找到资源文件的工具类,其实就是一个比较好用的工具类,这种工具类在框架中是随处可见的,是能够有效的防止重复早轮子的有效措施,其实做的事情是比较简单的,我们完全可以自己写一个,但是写了能有人家已经提供的好么?所以只需要记住这个类可以拿来用就好了。有钳子为什么要用手呢?
SqlSessionFactoryBuilder是用来创建SqlSessionFactory对象的类,这个对象存在的意义就是来创建SqlSessionFactory,他利用我们提供的资源文件或者自己定义的其他对象,创建出一个SqlSessionFactory,看到这个builder我们就可以想象成一个一次性工程的包工队,你给我制造出制造SqlSession的工厂(SqlSessionFactory)之后,就可以解散了,所以这个方法的生命周期,最好的是一个方法级别的,当方法结束了之后,这个包工队就可以解散了,否则我们将会为这个包工队提供生存的吃喝拉撒的资源,这就不划算了,因为他们后面没有活干了,我们还养闲人,这太划不来了。如果再需要怎么办?首先,我们一般碰不到这种需求,其次,就算是需要重建,我们只需要重新组织包工队就ok了。
SqlSessionFactory这个对象,该对象主要是用来生产SqlSession的一个工厂,这个是我们源源不断得到SqlSession的工厂,最好的实践就是,整个项目只保留一个SessionFactory。就类似于我们在玩红色警戒中的那个核电厂,有了这个东西,我们就可以源源不断的获取SqlSession了,但是只需要一个就好了,也就是上面代码中的那个方法。上面是单例模式的实现,如果不懂的话,可以好好体会一下,静态+获取方法,重点在于,这个对象只是被实例一次,而不会实例第二次的。
最后是这个最重要的对象SqlSession,session的英文意思是会话的意思了,会话,就是一次交谈过程。我们可以从这个角度上来记忆这个方法的生存周期,也就是一次会话。从Mybatis的官方文档中的建议,我们可以看到,如果没有DI框架,我们自己调用Mybatis的时候,应该让SqlSession对象的生命周期限制在一次会话中。sqlSession对象的生命周期,出生于SqlSessionFactory.openSession()方法,终结于SqlSession.close()方法。为了保证这个sqlSession是被关闭的,所以要将其写在finally块中。
上面的文件都写好之后,我们就可以写一个main方法来让我们上面的代码产生作用了,在Src中随便写一个类,然后在里面编写一个main方法,方法的内容如下
为了看到整个执行的过程,我们可以配置一个简单的log4j.properties让Log4j的配置生效,将含有下面内容的log4j.properties放到src文件夹下:
点击执行,如果前面的步骤没有错误的话,后台就会输出下面的内容:
DEBUG [main] -Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl'adapter.
DEBUG [main] -Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl'adapter.
DEBUG [main] -PooledDataSource forcefully closed/removed all connections.
DEBUG [main] -PooledDataSource forcefully closed/removed all connections.
DEBUG [main] -PooledDataSource forcefully closed/removed all connections.
DEBUG [main] -PooledDataSource forcefully closed/removed all connections.
DEBUG [main] -Opening JDBC Connection
DEBUG [main] -Created connection 14962806.
DEBUG [main] -Setting autocommit to false on JDBC Connection[com.mysql.jdbc.Connection@e45076]
DEBUG [main] -==> Preparing: select * from Tigerwhere id = ?
DEBUG [main] -==> Parameters: 1(Integer)
DEBUG [main] -<== Total: 1
100
DEBUG [main] - Resettingautocommit to true on JDBC Connection [com.mysql.jdbc.Connection@e45076]
DEBUG [main] -Closing JDBC Connection [com.mysql.jdbc.Connection@e45076]
DEBUG [main] -Returned connection 14962806 to pool.
看上面的执行过程,大概是:首先创建一个日志的对象类适配器,建立连接池,打开一个JDBC连接,设置当前连接的autoCommit属性,执行preparedstatement,返回查询结果,解析resultset,最后将autocommit设置为true,最后关闭当前的connection,将当前的连接还给连接池。
另外,Mybatis还支持注解的方式来避免xml文件,使用注解现在有两个优势,第一个优势就是可以使用IDE的自动提示功能,这个功能对于我们这些依赖IDE的开发人员来说是非常有用的,第二个就是可以减少错误的发生,因为XML毕竟是一个文件,基于字符串的,排查字符串的错误是比较麻烦的。
我们将上面的工程修改为注解的方式,如下。
添加一个TigerMapper.java接口文件如下:
修改MybatisUtil.java文件如下:
修改main方法内容如下:
执行结果如下
DEBUG [main] - Logginginitialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG [main] - PooledDataSourceforcefully closed/removed all connections.
DEBUG [main] - PooledDataSourceforcefully closed/removed all connections.
DEBUG [main] - PooledDataSourceforcefully closed/removed all connections.
DEBUG [main] - PooledDataSourceforcefully closed/removed all connections.
DEBUG [main] - Opening JDBCConnection
DEBUG [main] - Createdconnection 32960703.
DEBUG [main] - Settingautocommit to false on JDBC Connection [com.mysql.jdbc.Connection@1f6f0bf]
DEBUG [main] - ==> Preparing: select * from Tiger where id = ?
DEBUG [main] - ==>Parameters: 1(Integer)
DEBUG [main] - <== Total: 1
ziwen
DEBUG [main] - Resettingautocommit to true on JDBC Connection [com.mysql.jdbc.Connection@1f6f0bf]
DEBUG [main] - Closing JDBCConnection [com.mysql.jdbc.Connection@1f6f0bf]
DEBUG [main] - Returnedconnection 32960703 to pool.
这个是一个官方提供的一个最简单的Demo,后续,将在这个Demo的基础上,一步步来探索官方提供的其他特性,从而加深对Mybatis的理解。