博客迁移至:https://blog.csdn.net/wangshihuidev
前言
主要内容如下:
内容来自于《Java EE 企业级应用开发教程》这本书的翻读笔记,内容相对简单,用于基础知识的复习巩固。
MyBatis的工作流程
MyBatis框架在操作数据库时,大体经过了8个步骤。下面就对图6-4中的每一步流程进行详细讲解,具体如下。
(1)读取MyBatis配置文件mybatis-config.xml。mybatis-config.xml作为MyBatis的全局配置文件,配置了MyBatis的运行环境等信息,其中主要内容是获取数据库连接。
(2)加载映射文件Mapper.xml。Mapper.xml文件即SQL映射文件,该文件中配置了操作数据库的SQL语句,需要在mybatis-config.xml中加载才能执行。mybatis-config.xml可以加载多个配置文件,每个配置文件对应数据库中的一张表。
(3)构建会话工厂。通过MyBatis的环境等配置信息构建会话工厂SqlSessionFactory。
(4)创建SqlSession对象。由会话工厂创建SqlSession对象,该对象中包含了执行SQL的所有方法。
(5)MyBatis底层定义了一个Executor接口来操作数据库,它会根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。
(6)在Executor接口的执行方法中,包含一个MappedStatement类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的id、参数等。Mapper.xml文件中一个SQL对应一个MappedStatement对象,SQL的id即是MappedStatement的id。
(7)输入参数映射。在执行方法时,MappedStatement对象会对用户执行SQL语句的输入参数进行定义(可以定义为Map、List类型、基本类型和POJO类型), Executor执行器会通过MappedStatement对象在执行SQL前,将输入的Java对象映射到SQL语句中。这里对输入参数的映射过程就类似于JDBC编程中对preparedStatement对象设置参数的过程。
(8)输出结果映射。在数据库中执行完SQL语句后,MappedStatement对象会对SQL执行输出的结果进行定义(可以定义为Map和List类型、基本类型、POJO类型), Executor执行器会通过MappedStatement对象在执行SQL语句后,将输出结果映射至Java对象中。这种将输出结果映射到Java对象的过程就类似于JDBC编程中对结果的解析处理过程。
MyBatis的核心对象
在使用MyBatis框架时,主要涉及两个核心对象:
- SqlSessionFactory
- SqlSession
SqlSessionFactory
SqlSessionFactory是MyBatis框架中十分重要的对象,它是单个数据库映射关系经过编译后的内存镜像,其主要作用是创建SqlSession。SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象来构建,而SqlSessionFactoryBuilder则可以通过XML配置文件或一个预先定义好的Configuration实例构建出SqlSessionFactory的实例
SqlSessionFactory对象是线程安全的,它一旦被创建,在整个应用执行期间都会存在。如果我们多次地创建同一个数据库的SqlSessionFactory,那么此数据库的资源将很容易被耗尽。为了解决此问题,通常每一个数据库都会只对应一个SqlSessionFactory,所以在构建SqlSessionFactory实例时,建议使用单列模式。
SqlSession
SqlSession是MyBatis框架中另一个重要的对象,它是应用程序与持久层之间执行交互操作的一个单线程对象,其主要作用是执行持久化操作。SqlSession对象包含了数据库中所有执行SQL操作的方法,由于其底层封装了JDBC连接,所以可以直接使用其实例来执行已映射的SQL语句。每一个线程都应该有一个自己的SqlSession实例,并且该实例是不能被共享的。同时,SqlSession实例也是线程不安全的,因此其使用范围最好在一次请求或一个方法中,绝不能将其放在一个类的静态字段、实例字段或任何类型的管理范围(如Servlet的HttpSession)中使用。使用完SqlSession对象之后,要及时地关闭它,通常可以将其放在finally块中关闭
MyBatis 配置文件
configuration
在MyBatis框架的核心配置文件中,<configuration>元素是配置文件的根元素,其他元素都要在<configuration>元素内配置。
properties
<properties>是一个配置属性的元素,该元素通常用于将内部的配置外在化,即通过外部的配置来动态地替换内部定义的属性。例如,数据库的连接等属性,就可以通过典型的Java属性文件中的配置来替换,具体方式如下。
在项目的src目录下,添加一个全名为db.properties的配置文件,编辑后的代码如下所示。
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root
在MyBatis配置文件mybatis-config.xml中配置<properties... />属性,具体如下。
<properties resource="db.properties" />
修改配置文件中数据库连接的信息,具体如下。
<dataSource type="POOLED">
<! -- 数据库驱动 -->
<property name="driver" value="${jdbc.driver}" />
<! -- 连接数据库的url -->
<property name="url" value="${jdbc.url}" />
<! -- 连接数据库的用户名 -->
<property name="username" value="${jdbc.username}" />
<! -- 连接数据库的密码 -->
<property name="password" value="${jdbc.password}" />
</dataSource>
完成上述配置后,dataSource中连接数据库的4个属性(driver、url、username和password)值将会由db.properties文件中对应的值来动态替换。这样就为配置提供了诸多灵活的选择。
settings
<settings>元素主要用于改变MyBatis运行时的行为,例如开启二级缓存、开启延迟加载等。虽然不配置<settings>元素,也可以正常运行MyBatis,但是熟悉<settings>的配置内容以及它们的作用还是十分必要的。<settings>元素中的常见配置及其描述如表所示。
typeAliases
<typeAliases>元素用于为配置文件中的Java类型设置一个简短的名字,即设置别名。别名的设置与XML配置相关,其使用的意义在于减少全限定类名的冗余。
使用<typeAliases>元素配置别名的方法如下。
<! -- 定义别名 -->
<typeAliases>
<typeAlias alias="user" type="com.itheima.po.User"/>
</typeAliases>
上述示例中,<typeAliases>元素的子元素<typeAlias>中的type属性用于指定需要被定义别名的类的全限定名;alias属性的属性值user就是自定义的别名,它可以代替com.itheima. po.User使用在MyBatis文件的任何位置。如果省略alias属性,MyBatis会默认将类名首字母小写后的名称作为别名。
当POJO类过多时,还可以通过自动扫描包的形式自定义别名,具体示例如下。
<! -- 使用自动扫描包来定义别名 -->
<typeAliases>
<package name="com.itheima.po"/>
</typeAliases>
上述示例中,<typeAliases>元素的子元素<package>中的name属性用于指定要被定义别名的包,MyBatis会将所有com.itheima.po包中的POJO类以首字母小写的非限定类名来作为它的别名,比如com.itheima.po.User的别名为user, com.itheima.po.Customer的别名为customer等。
除了可以使用<typeAliases>元素自定义别名外,MyBatis框架还默认为许多常见的Java类型(如数值、字符串、日期和集合等)提供了相应的类型别名,如表所示。
typeHandler
MyBatis在预处理语句(PreparedStatement)中设置一个参数或者从结果集(ResultSet)中取出一个值时,都会用其框架内部注册了的typeHandler(类型处理器)进行相关处理。typeHandler的作用就是将预处理语句中传入的参数从javaType(Java类型)转换为jdbcType(JDBC类型),或者从数据库取出结果时将jdbcType转换为javaType。
为了方便转换,MyBatis框架提供了一些默认的类型处理器,其常用的类型处理器如表所示。
Mybatis 映射文件
如何返回Mysql主键ID
执行插入操作后,很多时候我们会需要返回插入成功的数据生成的主键值,此时就可以通过如下3个属性来实现。
如果使用的数据库支持主键自动增长(如MySQL),那么可以通过keyProperty属性指定PO类的某个属性接收主键返回值(通常会设置到id属性上),然后将useGeneratedKeys的属性值设置为true,其使用示例如下。
<insert id="addCustomer"
parameterType="com.itheima.po.Customer"
keyProperty="id" useGeneratedKeys="true" >
insert into t_customer(username, jobs, phone)
values(#{username}, #{jobs}, #{phone})
</insert>
使用上述配置执行插入后,会返回插入成功的行数,以及插入行的主键值。
注意:成功的行数通过返回值返回,主键ID通过PO类设置的字段返回。
为了验证此配置,可以通过如下代码测试。
@Test public void addCustomerTest(){
// 获取SqlSession
SqlSession sqlSession = MybatisUtils.getSession();
Customer customer = new Customer();
customer.setUsername("rose");
customer.setJobs("student");
customer.setPhone("13333533092");
int rows = sqlSession.insert("com.itheima.mapper."+"CustomerMapper.addCustomer", customer);
// 输出插入数据的主键id值
System.out.println(customer.getId());
if(rows > 0){
System.out.println("您成功插入了"+rows+"条数据!");
}else{
System.out.println("执行插入操作失败!! ! ");
}
sqlSession.commit();
sqlSession.close();
}
执行程序后,控制台的输出结果如图所示。