您好,登录后才能下订单哦!
最近在休陪产假,时间比较零碎,准备看2本书充实下,一本是「深入浅出MyBatis:技术原理与实践」,一本是「RabbitMQ实战:高效部署分布式消息队列」,为了加深记忆和理解,会进行整理、扩展和记录。
看书的目标不是把所有的细节都记住,而是从整体上了解一个技术能做什么,包含的特性、基本模块,实现原理和常见使用场景。
本篇分享MyBatis书籍的第一篇,首先回忆下JDBC的相关概念,了解Java提供的访问数据库最基本的方式,然后介绍下MyBatis的基本特性和核心组件,最后说下书的整体结构,了解后续文章的大致内容。
Java程序都是通过JDBC连接数据库的,通过SQL对数据库编程,JDBC是由SUN公司提出的一些列规范,只定义了接口规范,具体实现由各个数据库厂商去实现,它是一种典型的桥接模式。
桥接模式是一种结构型设计模式,它的主要特点是把抽象与行为实现分离开来,分别定义接口,可以保持各部分的独立性以及应对他们的功能扩展。
所谓规范,就是自己定义了标准接口,做了如下抽象:用Connection代表和数据库的连接,用Statement执行SQL,用ResultSet表示SQL返回的结果,提供了对数据的便利。从Connection可以创建Statement,Statement执行查询得到ResultSet。
上面说的Connection、Statement、ResultSet都应该是接口,具体实现由各个数据库提供商提供。有了规范,可以通过统一的接口,访问多种类型的数据库,可随便切换数据库。
上面提到,接口的实现由各个厂商提供,那么实现类的类名就会不统一,去创建Connection对象时,代码就会写死某个实现类,切换数据库时,就需要修改代码,这样不太好。为了解决这个问题,抽象了Driver驱动的概念。
Connection con=MySqlConnectionImpl("127.0.0.1",3306,"mi_user",userName,pwd);
每个数据库都需要实现Driver接口,通过Driver可获得数据库连接Connection,通过反射机制动态创建。
Class.forName("com.mysql.jdbc.Drier");
同一个程序可能访问不同的数据库,通过DriverManager来管理驱动,Driver在初始化的时候,需要注册到DriverManager中。
DriverManager提供了一个getConnection方法,用于建立数据库Connection:
Connection con=DriverManager.getConnection("127.0.0.1",3306,"mi_user",userName,pwd);
如果有多个数据库驱动,DriverManager如何区分呢,需要在数据库连接url中指定,比如mysql需要添加jdbc:mysql前缀:
String url= "jdbc:mysql://127.0.0.1:3306/mi_user";
Connection con=DriverManager.getConnection(url,userName,pwd);
数据源DataSource包含连接池和连接池管理2个部分,习惯上称为连接池。在系统初始化的时候,将数据库连接作为对象存储在内存中,当需要访问数据库时,从连接池中取出一个已建立的空闲连接对象。
使用数据源,获取其DataSource对象,通过该对象动态的获取数据库连接。另外,DataSource对象可以注册到名字服务(JNDI)中,可以通过名字服务获得DataSource对象,无需硬性编码驱动。
DriverManager是JDBC1提供的,DataSource是JDBC2新增的功能,提供了更好的连接数据源的方法。
通过上面的介绍,传统的JDBC编程给我们带来了连接数据库的功能,但其工作量相对较大,首先连接,然后处理JDBC底层事务,处理数据类型,还要对可能产生的异常进行捕捉处理并正确的关闭资源。
实际工作中,很少使用JDBC进行编程,提出了ORM模型,主要解决数据库数据和POJO对象的相互映射。
Hibernate和Mybatis都是ORM模型,Hibernate提供的是一种全表映射的模型,对JDBC的封装程度比较高。但Hibernate也有不少缺点,列举如下:
大型互联网环境中,灵活、SQL优化,减少数据的传递是最基本的优化方法,Hibernate无法满足要求,而MyBatis提哦给你了灵活、方便的方式,是一个半自动映射的框架。
MyBatis需要手工匹配提供POJO、SQL和映射关系,而全表映射的Hibernate只需要提供POJO和映射关系。
MyBatis可以配置动态SQL,可以解决Hibernate的表名根据时间变化,不同的条件下列明不一样的问题。可以优化SQL,通过配置决定SQL映射规则,也能支持存储过程,对于一些复杂和需要优化性能的SQL的查询它更加方便。
核心组件主要包括以下几个:
每个MyBatis应用都是以SqlSessionFactory的实例为中心的,它的任务是创建SqlSession。SqlSesion类似于一个JDBC的Connection对象。
提供了2种方式创建SqlSessionFactory:一种是XML配置的方式,一种是代码的方式,推荐使用XML配置的方式。
定义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>
<properties resource="application.properties">
</properties>
<!-- 定义别名 -->
<typeAliases>
<typeAlias alias="role" type="com.learn.chapter2.po.Role"/>
</typeAliases>
<!-- 定义数据库信息.默认使用development数据库构建环境 -->
<environments default="development">
<environment id="development">
<!-- 采用jdbc事务管理 -->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 定义映射器 -->
<mappers>
<mapper resource="com\learn\chapter2\mapper\roleMapper.xml"/>
</mappers>
</configuration>
创建SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession是一个接口类,扮演者门面的作用,真正干活的是Executor接口。需要保证每次用完正常关闭它。
SqlSession sqlSession=null;
try{
sqlSession=sqlSessionFactory.openSession();
//some code
sqlSession.commit();
} catch(Exception ex){
sqlSession.roolback();
} finally{
if(sqlSession!=null){
sqlSession.close();
}
}
映射器是由Java接口和XML文件(或注解)共同组成的,作用如下:
首先,定义Java接口:
public interface RoleMapper{
public Role getRole(Long id);
}
然后,定义映射XML文件,RoleMapper.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">
<mapper namespace ="com.learn.chapter2.mapper.RoleMapper">
<select id="getRole" paramterType="long" resultType="role" >
select id,role_name as roleName , note from t_role where id=#{id}
</select>
</mapper>
POJO对象Role的定义比较简单,就不列出了。#{id}为这条SQL的参数,SQL列的别名和POJO的属性名称保持一致,会把这条语句的查询结果自动映射到Role属性上,这就是自动映射。
执行查询
RoleMapper roleMapper=sqlSession.getMapper(RoleMapper.class);
Role role=roleMapper.getRole(1L);
String roleName=role.getRoleName();
SqlSessionFactory在MyBatis应用的整个生命周期中,每个数据库只对应一个SqlSessionFactory,可以实现一个工具类,以单例模式获取该对象。
SqlSession的生命周期在请求数据库处理事务的过程中,它是一个线程不安全的对象,在涉及多线程的时候要特别当心。它存活于一个应用的请求和操作,可以执行多条SQL,保证事务的一致性。
Mapper的作用是发送SQL,然后返回需要的结果,或者执行SQL修改数据库的数据,所以它应该在一个SqlSession事务方法之内,如同JDBC中一条SQL语句的执行,它最大的范围和SqlSession是相同的。
本书分为3个部分,依次介绍了MyBatis的基础应用、原理及插件开发、实战应用。
主要介绍如何高效地使用MyBatis:
深入源码理解MyBatis的内部运行原理以及插件的开发方法和技巧:
主要讲解MyBatis的一些实用的场景:
下篇会介绍MyBatis的相关配置,更好的配置MyBatis以适用于不同的业务场景,以及提供给我们的扩展。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。