1.mybatis中的连接池
1 什么是连接池
数据库连接是一项有限的昂贵资源,一个数据库连接对象均对应一个物理数据库连接,每次操作都打开一个物理连接,使用完都关闭连接,这样造成系统的性能低下。
数据库连接池的解决方案是在应用程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由应用程序动态地对池中的连接进行申请、使用和释放。
对于多于连接池中连接数的并发请求,应该在请求队列中排队等待。并且应用程序可以根据池中连接的使用率,动态增加或减少池中的连接数。
总结:
- 连接池是面向数据库连接的
- 连接池是为了优化数据库连接资源
在mybatis中数据库连接池可以分为以下三类
- UNPOOLED 不使用连接池的数据源
- POOLED 使用连接池的数据源
- JNDI 使用JNDI实现的数据库连接池
2.mybatis中的事务和隔离级别
事务的四要素
原子性 : 如果把一个事务可看作是一个程序,它要么完整的被执行,要么完全不执行。这种特性就叫原子性。
唯一性:
一致性代表了底层数据存储的完整性。它必须由事务系统和应用开发人员共同来保证。事务系统通过保证事务的原子性,隔离性和持久性来满足这一要求; 应用开发人员则需要保证数据库有适当的约束(主键,引用完整性等),并且工作单元中所实现的业务逻辑不会导致数据的不一致(即,数据预期所表达的现实业务情况不相一致)。例如,在一次转账过程中,从某一账户中扣除的金额必须与另一账户中存入的金额相等。
隔离性
隔离性意味着事务必须在不干扰其他进程或事务的前提下独立执行。换言之,在事务或工作单元执行完毕之前,其所访问的数据不能受系统其他部分的影响。
持久性
持久性表示在某个事务的执行过程中,对数据所作的所有改动都必须在事务成功结束前保存至某种物理存储设备。这样可以保证,所作的修改在任何系统瘫痪时不至于丢失。
2.3 事务的回滚
对于我们开发过程,也会遇到报错的情况,这个时候为了保证数据的一致性我们就需要进行事务的回滚,比如我们有一个操作需要同时更新用户表和地址表,这个时候更新用户表的时候成功了,但是更新地址表的时候出现了一个特别长的字段,导致更新失败,这个时候,我们需要将数据进行回滚。
//用于在测试方法执行之前执行
@BeforeEach
public void init()throws Exception{
// 设置为自动提交
sqlSession = MybatisUtils.openSession();
//获取dao的代理对象
userMapper = sqlSession.getMapper(IUserMapper.class);
}
// 在测试结束之后执行
@AfterEach
public void destroy()throws Exception{
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
@Test
public void testRollback(){
try{
User condition = new User();
condition.setId(1);
condition.setNickname("尚云科技111299");
int i = userMapper.update(condition);
assertEquals(i,1);
throw new Exception();
}catch (Exception e){
e.printStackTrace();
// 进行数据回滚操作
sqlSession.rollback();
}
}
2.4 事务的隔离级别
-
脏读
-
脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问 这个数据,然后使用了这个数据。
-
不可重复读
- 是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两 次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不 可重复读。例如,一个编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。如果 只有在作者全部完成编写后编辑人员才可以读取文档,则可以避免该问题
-
幻读
-
是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。 同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象 发生了幻觉一样。例如,一个编辑人员更改作者提交的文档,但当生产部门将其更改内容合并到该文档的主复本时,发现作者已将未编辑的新材料添加到该文档中。 如果在编辑人员和生产部门完成对原始文档的处理之前,任何人都不能将新材料添加到文档中,则可以避免该问题。
-
脏读
不可重复读
幻读
说明
Read uncommitted
√
√
√
直译就是"读未提交",意思就是即使一个更新语句没有提交,但是别 的事务可以读到这个改变.这是很不安全的。允许任务读取数据库中未提交的数据更改,也称为脏读。
Read committed 默认
×
√
√
直译就是"读提交",可防止脏读,意思就是语句提交以后即执行了COMMIT以后,别的事务才能读到这个改变. 只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别
Repeatable read
×
×
√
直译就是"可以重复读",这是说在同一个事务里面先后执行同一个查询语句的时候,得到的结果是一样的.在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读。
Serializable
×
×
×
直译就是"序列化",意思是说这个事务执行的时候不允许别的事务并发执行. 完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
实现分页功能
手动创建分页
公式 (页码-1)*每页的个数
第一步
.在接口处定义
List<User>getUsrYe(@Param("star")Integer star,@Param("yeShu")Integer yeShu);
第二步
在对应的xml文件中写SQL语句
<select id="getUsrYe" parameterType="int" resultType="User">
select *from t_user limit #{star},#{yeShu}
</select>
第三部
在测试中调用方法
@Test
public void Fenye(){
//
// int yeMian=3;
// int star = 1;
// int stars=(star-1)*yeMian;
// List<User> usrYe = session.getMapper(IUserMapper.class).getUsrYe(stars, 3);
// System.out.println(usrYe);
//页码
int pageNumber=1;
//每页的数据
int pageSize=3;
UsrPakg usrPaker1=new UsrPakg(pageNumber,pageSize);
Integer pagerNumber = usrPaker1.getPagerNumber();
Integer pagerSize = usrPaker1.getPagerSize();
int stars = usrPaker1.getStars();
//手动分页
List<User> userList = session.getMapper(IUserMapper.class).getUsrYe(stars, pagerSize);
//获取数据总条数
int touto = session.getMapper(IUserMapper.class).getallUser();
PagaUser pagaUser=new PagaUser(userList,touto);
System.out.println(pagaUser);
}
dto 前端传来得多数据存在这个包下]
VO向用户展示的包
Mapper 存放 接口和XML的包
自动分页
1. 引入依赖 在poom.xml
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
2. 配置拦截器
在mybatis的配置文件中增加插件
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
<property name="param1" value="value1"/>
</plugin>
</plugins>
3.调用
@Test
public void FenyeByPing(){
PageHelper.startPage(1,3);
List<User> usrYeByPlugins = session.getMapper(IUserMapper.class).getUsrYeByPlugins();
PageInfo<User> of = PageInfo.of(usrYeByPlugins);
System.out.println(of);
}