连接池
UNPOOLED连接
初始化驱动: 判断driver驱动是否已经加载到内存中,如果还没有加载,则会动态地加载driver类,并实例化一个Driver对象,使用DriverManager.registerDriver()方法将其注册到内存中
创建Connection对象: 使用DriverManager.getConnection()方法创建连接。
配置Connection对象: 设置是否自动提交autoCommit和隔离级别isolationLevel。
返回Connection对象
事务回滚
为了保证数据的一致性我们就需要进行事务的回滚,使用rollback
事务隔离
脏读:A事务执行过程中,B事务读取了A事务的修改。但是由于某些原因,A事务可能没有完成提
交,则B事务所读取的数据就会是不正确的。
不可重复读:B事务读取了两次数据,在这两次的读取过程中A事务修改了数据,B事务的这两次读
取出来的数据不一样。
幻读:B事务读取了两次数据,在这两次的读取过程中A事务添加了数据,B事务的这两次读取出来
的集合不一样
脏读 | 不可重复读 | 幻读 | 说明 | |
Read uncommitted | √ | √ | √ | 直译就是"读未提交",意思就是即使一个更新语句没有提交,但是别 的事务可以读到这个改变.这是很不安全的。允许任务读取数据库中未提交的数据更改,也称为脏读。 |
Read committed | × | √ | √ | 直译就是"读提交",可防止脏读,意思就是语句提交以后即执行了COMMIT以后,别的事务才能读到这个改变. 只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 |
Repeatable read | × | × | √ | 直译就是"可以重复读",这是说在同一个事务里面先后执行同一个查询语句的时候,得到的结果是一样的.在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读。 |
Serializable | × | × | × | 直译就是"序列化",意思是说这个事务执行的时候不允许别的事务并发执行. 完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞 |
延迟加载策略
延迟加载
就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载.
我们之前未实现延迟加载的时候,每次操作,都会直接查询出我们需要的数据
开启延迟加载
通过lazyLoadingEnabled、aggressiveLazyLoading可以对延迟加载进行配置
<settings>
<setting name="logImpl" value="LOG4J"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
配置每个关联字段的加载方式
在关联字段上也可以通过设置fetchType来指定加载方式。对于当个关联属性指定fetchType优先级是高于全局配置
<resultMap id="addressResultMap" type="Address">
<association property="user" column="user_id" javaType="User"
select="com.tledu.erp.mapper.IUserMapper.selectById" fetchType="lazy"/>
</resultMap>
使用注解进行开发
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@ResultMap:实现引用@Results 定义的封装
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
实现基本的CRUD
public interface IAddressDao {
@Insert("insert into t_address (addr, phone, postcode, user_id) VALUES (#{addr},#{phone},#{postcode},#{userId})")
int insert(Address address);
@Delete("delete from t_address where id = #{id}")
int delete(int id);
@Update("update t_address set addr = #{addr} where id = #{id}")
int update(Address address);
@Select("select * from t_address where id = #{id}")
Address selectById(int id);
}
使用result进行映射
@Select("select * from t_address where id = #{id}")
@Results(id = "addressRes", value = {
//id = true 标志这个字段是主键
@Result(id = true, column = "id", property = "id"),
@Result(column = "addr", property = "addr"),
@Result(column = "phone", property = "mobile"),
})
Address selectById(int id);
关联查询
1对1:one=@one
1对多:many=@many
缓存
一级缓存
一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit(),close()
等方法时,就会清空一级缓存。
二级缓存
二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,
多个SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。
开启二级缓存
<setting name="cacheEnabled" value="true"/>
在映射文件中开启缓存支持
<mapper namespace="com.tledu.erp.mapper.IAddressMapper">
<!-- 开启缓存支持-->
<cache />
</mapper>
查询语句中需要指定useCache="true"
只有当sqlSession close之后,二级缓存才能生效
当执行增删改操作的时候,必须执行commit()才能持久化到数据库中,同时二级缓存清空
session.clearCache()无法清除二级缓存,如果需要清除二级缓存,可以通过
sqlSessionFactory.getConfiguration().getCache("缓存id").clear();
当我们查询语句中,执行commit() 或者是close()关闭session,都不会清空二级缓存
分页插件
引入依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
配置拦截器
在mybatis的配置文件中增加插件
<!-- plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下: properties?, settings?, typeAliases?, typeHandlers?, objectFactory?,objectWrapperFactory?, plugins?, environments?, databaseIdProvider?, mappers? --> <plugins> <!-- com.github.pagehelper为PageHelper类所在包名 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 --> <property name="param1" value="value1"/> </plugin> </plugins>
使用插件
@Test
public void testList() throws IOException {
SqlSession session = MybatisUtils.openSession();
User condition = new User();
// 插件里提供的分页工具,在要查询之前,执行一下PageHelper.startPage(当前页数,每页的容量), 当使用工具时候,会导致懒加载失败
// 加了这个操作,插件就会在sql语句中拼接limit限制,并且还会统计总个数
PageHelper.startPage(1,5);
List<User> users = session.getMapper(IUserMapper.class).list(condition);
// 拿到结果之后通过PageInfo.of() 的方法,获得pageInfo
com.github.pagehelper.PageInfo<User> list = com.github.pagehelper.PageInfo.of(users);
System.out.println(users);
}