【JDBC】转账案例(一)

简介: 【JDBC】转账案例
  1. 回顾
  1. 使用工具类查询表

需求: 查询student表的所有数据,把数据封装到一个集合中

  1. 数据准备
#创建表
CREATE  TABLE student(
sid INT,
name VARCHAR(100),
age INT,
sex VARCHAR(100)
)
#插入数据
INSERT INTO student VALUES(1,'张三',18,'女'),(2,'李四',19,'男'),(3,'王五',20,'女'),(4,'赵六',21,'男')
  1. 创建工程,导入jar包和工具类

110d38193d684542938da69ed1f26e7b.png

连接池配置文件内容:

driverClassName = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/day05pre
username = root
password = root
initialSize = 5
maxActive = 10
minIdle = 3
maxWait = 60000

德鲁伊连接池工具类

import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
public class DruidUtil {
//1.创建一个连接池对象
private static DataSource dataSource;
//静态代码创建,这样第一次使用这个类的时候就可以直接创建DataSource对象了
static{
try {
//读取Druid.properties文件中的数据 创建连接池对象
InputStream is = DruidUtil.class.getClassLoader().getResourceAsStream("Druid.properties");
//创建properties集合载入流中数据
Properties pro = new Properties();
pro.load(is);
//Druid工具载入pro集合中的数据 创建数据源对象
dataSource = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
}
//2.创建方法 返回一个连接
public static Connection getConn() throws SQLException{
return dataSource.getConnection();
}
//3.关闭所有资源
public static void closeAll(ResultSet rs, PreparedStatement pst, Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (pst != null) {
try {
pst.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
  1. 创建student类

这个类的字段与数据库字段对应

public class Student {
private int sid;
private String name;
private int age;
private String sex;
   构造
   set/get
   toString
}

创建测试类书写查询代码

/*
 * 查询student类中的所有的信息 展示到控制台上
 *
 * */
@Test
public  void selectAll() throws Exception{
//1.获取链接
Connection conn = DruidUtil.getConn();
System.out.println("Demo04 ======>selectAll() ======> 获取链接完毕 conn= "+conn);
//2.通过链接获取SQL的发射器
String sql = "select * from student";
PreparedStatement pst = conn.prepareStatement(sql);
//3.发射SQL语句 得到结果集
ResultSet rs = pst.executeQuery();
System.out.println("Demo04 ======>selectAll() ======> 发射完毕 rs= "+rs);
//创建一个集合
List<Student> list = new ArrayList<Student>();
//4.处理结果集
while(rs.next()){
Student s = new Student(rs.getInt("sid"), rs.getString("name"), rs.getInt("age"), rs.getString("sex"));
list.add(s);
}
//5.关闭资源
DruidUtil.closeAll(rs, pst, conn);
//遍历
for(Student stu: list){
System.out.println(stu);
}
}
  1. JDBC转账案例
  1. 需求:

完成转账功能

  1. 实现思路:

42d47d8f3d28490d8803edbd5bfcc636.png

  1. 实现步骤
  1. 数据准备

创建数据表和数据


# 创建账号表
CREATE TABLE account(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
money DOUBLE
);
# 初始化数据
INSERT INTO account VALUES (NULL,'张三',10);
INSERT INTO account VALUES (NULL,'李四',10);
  1. Dao层

创建两个方法分别实现取钱和存钱

import java.sql.Connection;
import java.sql.PreparedStatement;
import com.czxy.util.DruidUtil;
public class AccountDao {
/*
 * 从指定的账户中取钱(减钱)
 * */
public void outMoney(String name,int money) throws Exception{
//1.获取链接
Connection conn = DruidUtil.getConn();
//2.发射器
String sql = "UPDATE account SET money=money-? WHERE NAME=?";
PreparedStatement pst = conn.prepareStatement(sql);
pst.setInt(1, money);
pst.setString(2, name);
//3.发射
int num = pst.executeUpdate();
//4.处理结果
System.out.println("本次执行的影响的行数是: num="+num);
//5.关闭资源
DruidUtil.closeAll(null, pst, conn);
}
/*
 * 从指定的账户中存钱(加钱)
 * */
public void inMoney(String name,int money) throws Exception{
//1.获取链接
Connection conn = DruidUtil.getConn();
//2.发射器
String sql = "UPDATE account SET money=money+? WHERE NAME=?";
PreparedStatement pst = conn.prepareStatement(sql);
pst.setInt(1, money);
pst.setString(2, name);
//3.发射
int num = pst.executeUpdate();
//4.处理结果
System.out.println("本次执行的影响的行数是: num="+num);
//5.关闭资源
DruidUtil.closeAll(null, pst, conn);
}
}
  1. Service层

创建一个方法完成转账业务

import com.czxy.dao.AccountDao;
public class AccountService {
/**
 * 实现转账
 * @param srcName : 钱的来源
 * @param descName : 钱的去向
 * @param money : 钱数
 * */
public void transfer(String srcName,String descName,int money){
AccountDao ad = new AccountDao();
try {
// -钱
ad.outMoney(srcName, money);
// +钱
ad.inMoney(descName, money);
System.out.println("转账完毕 ");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
  1. 测试类

创建一个测试类 ,书写main方法 实现转账

public class Demo02 {
public static void main(String[] args) {
//创建Service对象
AccountService as = new AccountService();
//张三 给 李四 转2块钱
as.transfer("张三", "李四", 2);
}
}
  1. 测试

执行前:

22581718791640e8beee0e9be7c191bb.png


执行后:

41be9d3729774b8ba3cdec54bc7450c6.png


  1. 遇到问题

如果转账的中间出现了bug,很容易导致A账户的钱减少了,但是B账户的钱没有增加。这会造成事故,不是我们期望看到的。

下面代码在Service层模拟转账过程出现问题。


85608985e4154ac188747d83c05471db.png


效果如下:

转账前:

952d55a2c3e943c59eac6d198e45e07a.png


执行代码:


d754afec5ca24061a02705c47247f3d8.png

 

转账出错结果:

cdfa9866b4f64208a9b0b3259f3af310.png


相关文章
|
4月前
|
Java 数据库连接
登录页面JDBC案例
登录页面JDBC案例
54 0
|
3月前
|
SQL Java 关系型数据库
JDBC PreparedStatement 字段值为null导致TBase带宽飙升的案例分析
JDBC PreparedStatement 字段值为null导致TBase带宽飙升的案例分析
51 0
|
4月前
|
SQL Java 数据库连接
JDBC增删改查案例讲解
JDBC增删改查案例讲解
20 0
|
7月前
|
Oracle 关系型数据库 Java
分享一个 Oracle RAC 模式下客户端建立JDBC初始连接时因ONS造成应用启动时卡顿30秒问题的排查分析案例
分享一个 Oracle RAC 模式下客户端建立JDBC初始连接时因ONS造成应用启动时卡顿30秒问题的排查分析案例
|
12月前
|
监控 Java Spring
Spring JDBC-实施Spring AOP事务注意事项及案例分析
Spring JDBC-实施Spring AOP事务注意事项及案例分析
110 0
|
Java 关系型数据库 MySQL
Java Web实战 | JDBC案例:实现图书管理
在项目开发中,应用程序需要的数据基本都是存放在数据库中的。对数据的管理过程离不开数据库。本文将运用JDBC API编写一个实现基本数据库操作(添加、修改、删除、查询)的应用程序,实现对图书信息的管理。 完成此项目的具体步骤如下。
209 0
Java Web实战 | JDBC案例:实现图书管理
|
SQL 安全 Oracle
|
SQL Oracle Java
Jdbc连接Oracle数据库详细案例,占位符的使用
Jdbc连接Oracle数据库详细案例,占位符的使用
268 0
Jdbc连接Oracle数据库详细案例,占位符的使用
|
Java 数据库连接 数据库
原生JDBC连接数据库案例教学
前言: 我们在刚刚接触后端开发时,有没有思考过,怎么才能后java代码和数据库进行交互的呢?
100 2
|
4月前
|
SQL Java 关系型数据库
MySQL之JDBC(二)
MySQL之JDBC(二)
34 0