JDBC学习笔记第九篇
2023-12-29 09:13:27
解决druid的线程同步机制,想同步curd的时候不用再传入connection连接,让它们得到相同的连接
package com.shayiheng.api.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.shayiheng.api.druid.DruidUsePart;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/**
* @Author Tom
* @Date 2023/12/22 21:42
* @Description:
*
* v1.0版本工具类
* 内部包含一个连接池对象,并且对外提供获取连接和回收连接的方法!
* 小建议:
* 工具类的方法,推荐写成静态的,外部调用会更加方便
* 实现:
* 属性 连接池对象[实例化一次]
* 单例模式
* static{
* 全局实例话调用一次
* }
* 方法
* 对外提供连接的方法
* 回收外部传入连接的方法
*
* TODO:
* 利用线程本地变量,存储连接信息!确保一个线程的多个方法可以获取同一个connection!
* 优势:事物操作的时候 service 和 dao 属于同一个线程,不用再传递参数了
* 可调用getConnection获取相同的连接
*
*/
public class JdbcUtilsV2 {
private static DataSource dataSource=null;//连接池对象
private static ThreadLocal<Connection> t1=new ThreadLocal<>();
static {
//初始化静态代码块
Properties properties=new Properties();
InputStream ips = DruidUsePart.class.getClassLoader().getResourceAsStream("druid.properties");
try {
properties.load(ips);
}catch (IOException e){
throw new RuntimeException(e);
}
try {
dataSource= DruidDataSourceFactory.createDataSource(properties);
}catch (Exception e){
throw new RuntimeException(e);
}
}
/**
* 对外提供连接的方法
* @return
*/
public static Connection getConnection() throws SQLException {
//线程是否存在
Connection connection=t1.get();
//压根没有创建
if (connection==null){
//获取连接
connection=dataSource.getConnection();
//往线程本地变量里存一份
t1.set(connection);
}
return connection;
}
public static void freeConnection() throws SQLException {
Connection connection=t1.get();
if (connection!=null) {
//情况线程本地变量
t1.remove();
connection.setAutoCommit(true);//回到默认
connection.close();//连接池的连接,调用close就是回收!
}
}
}
package transactionnew;
/**
* @Author Tom
* @Date 2023/12/22 13:44
* @Description: bank表的数据库操作方法存储类
*
* 事物的特性
* 1.原子性(Atomicity):指事物是一个不可分割的工作单位,事物中的操作要么都发生,要么一个都不发生
* 2.一致性(Consistency):事物必须使数据库从一个一直性变换到另一个一直性状态
* 3.隔离性(Isolation):事物的隔离性是指一个事物的执行不能被其他事物干扰
* 4.持久性(Durability):持久性是指一个事物一旦被提交,它对数据库中的数据的改变是永久性的
*
* 事物的类型
* 自动提交:每条语句自动存储一个事物中,执行成功自动提交,执行失败自动会滚。
* 手动提交:手动开启事物,添加语句,手动提交或者手动会滚即可!
*
*
* Sql开启事务的方式
* 针对自动提交:关闭自动提交即可,多条语句添加以后,最终手动提交或者回滚!(推荐)
* SET autocommit= off; //关闭当前连接自动事物提交方式
* # 只有当前连接有效
* # 编写SQL语句即可
* SQL
* SQL
* SQL
* #手动提交或者会滚[结束当前的事物]
* COMMIT / ROLLBACK;
* 手动开启事务:开启事物代码,添加SQL语句,事物提交或者事物回滚!(不推荐)
*/
import com.shayiheng.api.utils.JdbcUtilsV2;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
*
*/
public class BankDao {
/**
* 加钱的数据库操作方法(jdbc)
* @param account 加钱的账号
* @param account 价钱的金额
*/
public void add(String account,int money) throws ClassNotFoundException, SQLException {
//1 2 接收业务层传来的连接
Connection connection = JdbcUtilsV2.getConnection();
//3.编写SQL语句结果,动态的部分使用?代替
String sql= "update t_bank set money = money + ? where account= ? ;";
//4.创建预编译preparedStatement
PreparedStatement statement = connection.prepareStatement(sql);
//5.占位符赋值
statement.setObject(1,money);
statement.setObject(2,account);
//6.发送sql语句
statement.executeUpdate();
//7.关闭资源
statement.close();
System.out.println("加钱成功");
}
/**
* 加钱的数据库操作方法(jdbc)
* @param account 减钱的账号
* @param account 减钱的金额
*/
public void sub(String account,int money) throws ClassNotFoundException, SQLException {
//1 2 接收业务层传来的连接
Connection connection = JdbcUtilsV2.getConnection();
//3.编写SQL语句结果,动态的部分使用?代替
String sql= "update t_bank set money = money - ? where account= ? ;";
//4.创建预编译preparedStatement
PreparedStatement statement = connection.prepareStatement(sql);
//5.占位符赋值
statement.setObject(1,money);
statement.setObject(2,account);
//6.发送sql语句
statement.executeUpdate();
//7.关闭资源
statement.close();
System.out.println("减钱成功");
}
}
package transactionnew;
import com.shayiheng.api.utils.JdbcUtilsV2;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* @Author Tom
* @Date 2023/12/22 13:58
* @Description: 银行卡业务方法,调用dao方法
*/
public class BankServer {
@Test
public void start() throws SQLException, ClassNotFoundException {
//二狗子给lu蛋蛋转500
transfer("ergouzi","e",500);
}
//在业务开启事务
public void transfer(String addAccount,String subAccount,int money) throws SQLException, ClassNotFoundException {
BankDao bankDao = new BankDao();
Connection connection = JdbcUtilsV2.getConnection();
try{
//开启事务 MYSQL会自动事物提交,给它关闭就行
connection.setAutoCommit(false);
//执行数据库动作
//执行数据库动作
bankDao.add(addAccount,money);
System.out.println("----------");
bankDao.sub(subAccount,money);
//事物提交
connection.commit();
}catch (Exception e){
//事物回滚
connection.rollback();
//抛出异常
throw e;
}finally {
JdbcUtilsV2.freeConnection();
}
}
}
文章来源:https://blog.csdn.net/Sakura_syh/article/details/135166499
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!