目录
六、sqlMapConfig.xml 配置文件的深入研究
SqlMapConfig.xml中配置的内容和顺序如下:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处 理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
以上为 sqlMapConfig.xml 文件中的配置内容,加粗的在前面曾经使用过,这里不再研究。
接下来会主要研究 properties、typeAliases 和 mappers 标签。
6.1 properties(属性)
由于在原来的写法中,数据源的相应配置信息是在xml文件中的<dataSource>下的<property>标签中进行配置,以及配置信息的不确定性,我们常常需要对相应信息进行更改,为避免频繁修改xml文件,这里可以使用 Java属性文件(jdbc.properties)进行配置信息的存储,并使用 <properties> 标签进行引入。
首先在 classpath 下定义 jdbc.properties 文件:
jdbc.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql:///test
username=root
password=1234
在 sqlMapConfig.xml 文件中进行配置:
sqlMapConfig.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:从当前项目加载(读取项目资源路径下的文件),使用${}读取属性文件中的内容
url:从外部的资源加载文件(需要指定外部资源的绝对路径)
指定外路径时,在路径前要加上 file:///
-->
<properties resource="jdbc.properties"></properties>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/cpz/dao/UserDao.xml"></mapper>
</mappers>
</configuration>
6.2 typeAliases(类型别名)
4.3.1 mybatis支持别名: 别名 | 映射的类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
map | Map |
从以往的代码中我们不难发现,每次使用实体类都需要写上完整的包路径(com.cpz.domain.User),这里我们可以使用<typeAliases>标签进行别名的使用。
首先进行 sqlMapConfig.xml 文件的配置:
sqlMapConfig.xml
<!--配置别名:不区分大小写
typeAlias:一次指定一个实体
package:指定包下的所有实体都可以使用别名,别名的名称就是当前实体的类名
-->
<typeAliases>
<!-- <typeAlias type="com.cpz.domain.User" alias="user"></typeAlias> -->
<package name="com.cpz.domain"></package>
</typeAliases>
这里我们可以使用别名在 UserDao.xml 中进行配置:
UserDao.xml
<mapper namespace="com.cpz.dao.UserDao">
<select id="findAll" resultType="user">
select * from user
</select>
</mapper>
6.3 mappers(映射器)
同理,我们也可以对 mappers 标签进行修改。
sqlMapConfig.xml
<!--2:加载映射文件
mapper resource:从资源文件中读取内容,指定映射文件
mapper class:从类文件中读取内容,指定类
(必须保证Dao的类和映射文件放置到同一个包下,而且名称要一致),
应用场景一般在注解的使用
package name="com.itheima.dao":指定com.itheima.dao包下的所有Dao类都会被加载映射
(必须保证Dao的类和映射文件放置到同一个包下,而且名称要一致),
应用场景一般在映射文件、注解的使用
-->
<mappers>
<!--<mapper resource="com/cpz/dao/UserDao.xml"></mapper>-->
<!--<mapper class="com.cpz.dao.UserDao"></mapper>-->
<package name="com.cpz.dao"></package>
</mappers>
七、Mybatis 连接池
7.1 连接池的特点
- 连接池就是用于存储连接的一个容器
- 连接池其实就是一个集合对象,该集合必须是线程安全的,不能两个线程拿到同一个连接。
- 连接池必须实现队列的特性,先进先出
7.2 连接池的分类
-
UNPOOLED 不使用连接池的数据源,采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的思想。
-
POOLED 使用连接池的数据源,采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现。
-
JNDI 使用JNDI实现的数据源,采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样。
7.3 总结
最后我们可以发现,真正连接打开的时间点,只是在我们执行SQL语句时,才会进行。其实这样做我们也可以进一步发现,数据库连接是我们最为宝贵的资源,只有在要用到的时候,才去获取并打开连接,当我们用完了就再立即将数据库连接归还到连接池中。 所以我们使用连接池的技术会节省连接资源。
八、Mybatis 中的事务
8.1 概念
8.2 事务的特性
8.3 不考虑隔离性会产生的问题
脏读
(针对未提交数据)如果一个事务中对数据进行了更新,但事务还没有提交,另一个事务可以“看到”该事务没有提交的更新结果,这样造成的问题就是,如果第一个事务回滚,那么,第二个事务在此之前所“看到”的数据就是一笔脏数据。
不可重复读
(针对其他提交前后,读取数据本身的对比)不可重复读取是指同一个事务在整个事务过程中对同一笔数据进行读取,每次读取结果都不同。如果事务1在事务2的更新操作之前读取一次数据,在事务2的更新操作之后再读取同一笔数据一次,两次结果是不同的
幻读
(针对其他提交前后,读取数据条数的对比) 幻读是指同样一笔查询在整个事务过程中多次执行后,查询所得的结果集是不一样的。幻读针对的是多笔记录。如果事务1在事务2的新增操作之前读取一次数据,在事务2的新增操作之后再读取同一笔数据,取得的结果集是不同的,幻读发生。
8.4 解决办法
- Serializable (串行化):最严格的级别,事务串行执行,资源消耗最大;
- REPEATABLE READ(重复读):保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读”和“不可重复读”的情况,但不能避免“幻读”,但是带来了更多的性能损失。(mysql的默认隔离级别)
- READ COMMITTED (读已提交):大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读”,但不能避免“幻读”和“不可重复读”。该级别适用于大多数系统。(oracle的默认隔离级别)
- Read Uncommitted(读未提交):事务中的修改即使没有提交,其他事务也可以看得到,会导致“脏读”、“幻读”和“不可重复读取”。