- 回顾
- 使用工具类查询表
需求: 查询student表的所有数据,把数据封装到一个集合中
- 数据准备
#创建表 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,'男')
- 创建工程,导入jar包和工具类
连接池配置文件内容:
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(); } } } }
- 创建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); } }
- JDBC转账案例
- 需求:
完成转账功能
- 实现思路:
- 实现步骤
- 数据准备
创建数据表和数据
# 创建账号表 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);
- 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); } }
- 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(); } } }
- 测试类
创建一个测试类 ,书写main方法 实现转账
public class Demo02 { public static void main(String[] args) { //创建Service对象 AccountService as = new AccountService(); //张三 给 李四 转2块钱 as.transfer("张三", "李四", 2); } }
- 测试
执行前:
执行后:
- 遇到问题
如果转账的中间出现了bug,很容易导致A账户的钱减少了,但是B账户的钱没有增加。这会造成事故,不是我们期望看到的。
下面代码在Service层模拟转账过程出现问题。
效果如下:
转账前:
执行代码:
转账出错结果: