欢迎来到站圈网!

php远程媒体七牛node摇摇

投稿中心

Java

当前位置: 主页 > 编程语言 > Java

Spring数据库连接池实现原理深入刨析

时间:2022-11-22|作者:wei_shuo|点击:

目录

Spring事务管理

事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transactionend transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成

概念:

例如:在关系数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序

事务ACID原则:

  • 原子性(atomicity):一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做
  • 一致性(consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性密切相关
  • 隔离性(isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰
  • 持久性(durability):持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响

声明式事务:

通过AOP(面向切面)方式在方法前使用编程式事务的方法开启事务,通过注解或XML配置实现,在方法后提交或回滚。用配置文件的方法或注解方法(如:@Transactional)控制事务

编程式事务:代码中进行事务管理

手动开启、提交、回滚事务

环境搭建

User类

package com.wei.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int id;
    private String name;
    private String pwd;
}

UserMapper接口

package com.wei.Mapper;
import com.wei.pojo.User;
import java.util.List;
public interface UserMapper {
    //查询用户
    public List selectUser();
    //添加用户
    public int addUser(User user);
    //删除用户
    public int deleteUser(int id);
}

UserMapper.xml接口映射文件





    
    
    
        insert into mybatis.user (id, name, pwd) values (#{id}, #{name}, #{pwd});
    
    
        deletes from mybatis.user where id=#{id};
    

 mybatis-config.xml核心配置文件





    
    
    
        
        
    
    
        
    
    
    
        
            
            
            
                
                
                
                
            
        
    

Spring-dao.xml(配置、整合Mybatis)



    
    
        
        
        
        
    
    
    
        
        
        
        
        
    
    
    
    
        
        
    

applicationContext.xml(配置Spring框架所需的信息)

package com.wei.Mapper;
import com.wei.pojo.User;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{
    public List selectUser(){
        User user = new User(5, "haha", "123456");
        UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
        mapper.addUser(user);
        mapper.deleteUser(5);
        return mapper.selectUser();
    }
    @Override
    public int addUser(User user) {
        UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
        return mapper.addUser(user);
    }
    @Override
    public int deleteUser(int id) {
        UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
        return mapper.deleteUser(1);
    }
}

标准配置

要开启 Spring 的事务处理功能,在 Spring 的配置文件中创建一个 DataSourceTransactionManager 对象:




@Configuration
public class DataSourceConfig {
@Bean
public DataSourceTransactionManager transactionManager() {
 return new DataSourceTransactionManager(dataSource());
}
}

声明式事务

spring-dao.xml中配置事务



    
    
        
        
        
        
    
    
    
        
        
        
        
        
    
    
    
    
        
        
    
    
    
    
    
        
        
            
            
            
            
            
            
            
        
    
    
    
        
        
        
        
    

测试类

import com.wei.Mapper.UserMapper;
import com.wei.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class MyTest {
    @Test
    public void test(){
        //解析beans.xml文件,生成管理相应的Bean对象,创建 Spring 的 IOC 容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicicationContext.xml");
        //getBean:参数即为Spring配置文件中的bean的id
        //从IOC容器中获取 bean 的实例
        UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
        List userList = userMapper.selectUser();
        for (User user : userList) {
            System.out.println(user);
        }
    }
}

isolation:隔离级别

no-rollback-for:不回滚

propagation:传播行为

REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务(默认)

NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务

read-only:只读

rollback-for:回滚控制

timeout:过期时间

总结

配置事务原因:

  • 避免数据提交不一致
  • 事务涉及数据一致性和完整性问题

SqlSessionFactory

SqlSessionFactory是MyBatis的核心对象,用于初始化MyBatis,读取配置文件,创建SqlSession对象,SqlSessionFactory是全局对象,为保证其在应用中全局唯一,要使用static进行初始化

SqlSession是MyBatis操作数据库的核心对象,SqlSession使用JDBC方式与数据库交互,同时提供了数据表的CRUD(增删改查)对应的api方法

导入jar包

格式:


org.mybatis
mybatis
x.x.x



 org.mybatis
 mybatis
 3.5.2

XML中构建SqlSessionFactory

  • 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心
  • SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得
  • 而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例

获取sqlSessionFaction对象

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

获得SqlSession的实例

既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句

SqlSession sqlSession = sessionFactory.openSession(true);

代码实现

utils包下创建工具类MybatisUtils类

package com.wei.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
//sqlSessionFactory  构造  sqlSession
public class MybatisUtils {
	//提升作用域:定义SqlSessionFactory全局变量
    private static SqlSessionFactory sqlSessionFactory;
//静态代码块:执行优先级高于非静态的初始化块,它会在类初始化的时候执行一次,执行完成便销毁,它仅能初始化类变量,即static修饰的数据成员
    static {	
        try {
            //使用Mybatis第一步:获取sqlSessionFactory对象
            
            //定义核心配置文件
            String resource = "mybatis-config.xml";
            //通过IO流加载resource的mybatis-config.xml核心配置文件文件
            InputStream inputStream = Resources.getResourceAsStream(resource);
            //通过build加载inputStream
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
    //SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
    //你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession(true);		//此处设置参数为true时,表示开启自动提交事物功能
    }
}

作用域(Scope)和生命周期

Spring数据库连接池实现原理深入刨析

Spring数据库连接池实现原理深入刨析

所有代码中都遵循这种使用模式,可以保证所有数据库资源都能被正确地关闭

SqlSessionFactoryBuilder(构造器)

一旦创建了 SqlSessionFactory,就不再需要它了

局部变量

SqlSessionFactory(工厂)

  • SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例
  • 数据库连接池
  • SqlSessionFactory 的最佳作用域是应用作用域
  • 最简单的就是使用单例模式或者静态单例模式

SqlSession(会话)

  • 连接到SqlSessionFactory(连接池)的一个请求
  • SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
  • 使用完需要赶紧关闭,否则资源被占用 SqlSession.close()

到此这篇关于Spring数据库连接池实现原理深入刨析的文章就介绍到这了,更多相关Spring数据库连接池内容请搜索站圈网以前的文章或继续浏览下面的相关文章希望大家以后多多支持站圈网!

版权声明:本文内容由小编收集网络,均来自网络用户自发贡献,版权归原作者所有,Web前端、电脑编程学习类网站不拥有其著作权,亦不承担相应法律责任。具体规则请查看《Web前端、电脑编程学习类网站用户服务协议》和《Web前端、电脑编程学习类网站知识产权保护指引》。如果您发现本站中有涉嫌抄袭的内容,填写联系本站管理员,一经查实,管理员将立刻删除涉嫌侵权内容。

上一篇:微信小程序与webview H5交互的方法(内嵌H5跳转原生

下一篇:一文详解Java如何创建和销毁对象

本文标题:Spring数据库连接池实现原理深入刨析

本文地址:https://www.zhano.cn/Java/67925.html

AD300

广告投放 | 联系我们 | 版权申明 | SiteMap

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:15234109 | 邮箱:15234109#qq.com(#换成@)

Copyright © 2019-2022 豫ICP备19001789号