三层思想的案例:
dao层:数据访问层,对数据库进行操作
package com.itheima.dao;
import org.apache.commons.dbutils.QueryRunner;
import java.sql.Connection;
import java.sql.SQLException;
/*
创建转账案例的Dao层:用于对account表进行增删改查 对数据库进行操作
注意:
一张表-->一个dao
定义两个方法:
一个减钱,一个加钱
*/
public class AccountDao {
/*
定义减钱方法
参数:
Connection conn:两个方法使用同一个Connection,从而保证使用同一个事务
String fromName:付款人姓名
double money:转账金额
返回值:
int:影响数据库的有效行数
*/
public int fromAccount(Connection conn,String fromName,double money) throws SQLException {
//创建QueryRunner对象
QueryRunner qr = new QueryRunner();
//调用update方法执行sql语句,接收结果
int row = qr.update(conn,"update account set money=money-? where name=?;",money,fromName);
//返回结果
return row;
}
/*
定义加钱方法
参数:
Connection conn:两个方法使用同一个Connection,从而保证使用同一个事务
String toName:收款人姓名
double money:转账金额
返回值:
int:影响数据库的有效行数
*/
public int toAccount(Connection conn,String toName,double money) throws SQLException {
//创建QueryRunner对象
QueryRunner qr = new QueryRunner();
//调用update方法执行sql语句,接收结果
int row = qr.update(conn,"update account set money=money+? where name= ?;",money,toName);
//返回结果
return row;
}
}
对account表进行操作,加钱或者减钱
service层:业务层,转账等操作
package com.itheima.service;
import com.itheima.dao.AccountDao;
import com.itheima.utils.C3P0UtilsXML;
import org.apache.commons.dbutils.DbUtils;
import java.sql.Connection;
import java.sql.SQLException;
/*
业务逻辑
转账案例的Service层:接收web的传递的数据,调用dao层的方法,接收结果;把结果返回给web层
定义一个转账方法:
参数接收web传递的数据(付款人姓名,收款人姓名,转账金额)
使用C3P0连接池获取Connection
开启事务
创建AccountDao对象
调用减钱和加钱方法,接收结果
对结果进行判断
都执行成功,提交事务
有异常,回滚事务
把结果返回给web层
释放资源
*/
public class AccountService {
//定义一个转账方法
public boolean transferAccount(String fromName,String toName,double momey){
//使用C3P0连接池获取Connection
Connection conn = C3P0UtilsXML.getConnection(); // 连接池
//定义返回的结果
boolean flag = false;
try {
//开启事务
conn.setAutoCommit(false);
//创建AccountDao对象
AccountDao dao = new AccountDao(); // 对数据层操作的对象
//调用减钱和加钱方法,接收结果
int row1 = dao.fromAccount(conn, fromName, momey); //减钱
// System.out.println(0/0);
int row2 = dao.toAccount(conn, toName, momey); // 加钱
//对结果进行判断
if(row1>0 && row2>0){
flag = true;
//都执行成功,提交事务
conn.commit();
}
} catch (Exception e) {
e.printStackTrace();
//有异常,回滚事务
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
//释放资源
DbUtils.closeQuietly(conn);
}
//把结果返回给web层
return flag; //转账是否成功
}
}
转账成功返回true。
视图层:用户输入数据,展示效果
package com.itheima.web;
import com.itheima.service.AccountService;
import java.util.Scanner;
/*
创建转账案例的web层
使用Scanner获取用户输入的数据(付款人姓名,收款人姓名,转账金额)
创建AccountSerivce对象
调用转账方法,接收转账结果
对结果进行判断,给用户展示结果
*/
public class AccountWeb {
public static void main(String[] args) {
//使用Scanner获取用户输入的数据(付款人姓名,收款人姓名,转账金额)
Scanner sc = new Scanner(System.in);
System.out.print("请输入付款人姓名:");
String fromName = sc.next();
System.out.print("请输入收款人姓名:");
String toName = sc.next();
System.out.print("请输入转账金额:");
double money = sc.nextDouble();
//创建AccountSerivce对象
AccountService service = new AccountService(); //业务
//调用转账方法,接收转账结果
boolean b = service.transferAccount(fromName, toName, money); // 数据库操作 转账成功返回true
//对结果进行判断,给用户展示结果
if (b){
System.out.println("转账成功!");
}else{
System.out.println("转账失败!");
}
}
}
C3P0连接池的工具类XML版本:使用C3P0连接池获取数据库连接对象Connection并返回
package com.itheima.utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/*
C3P0连接池的工具类XML版本:使用C3P0连接池获取数据库连接对象Connection并返回
连接池有一个规范接口
javax.sql.DataSource接口
定义了一个从连接池中获取连接的方法
Connection getConnection() 尝试建立与此 DataSource 对象所表示的数据源的连接。
C3P0实现了连接池的规范接口DataSource
com.mchange.v2.c3p0.ComboPooledDataSource类 implements DataSource接口
重写了getConnection方法
使用步骤:
1.在成员位置创建一个静态的ComboPooledDataSource对象
2.把c3p0-config.xml复制到当前模块的src下;
C3P0就会自动的解析xml,获取数据库连接信息给ComboPooledDataSource对象赋值
3.定义一个静态方法,从ComboPooledDataSource对象中获取数据库连接对象Connection并返回
4.定义一个释放资源的方法
*/
public class C3P0UtilsXML {
//1.在成员位置创建一个静态的ComboPooledDataSource对象
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
//3.定义一个静态方法,从ComboPooledDataSource对象中获取数据库连接对象Connection并返回
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException e) {
/*
获取数据库连接对失败,让程序停止下来
把编译异常,转换为运行时异常
*/
throw new RuntimeException("获取数据库连接对象失败"+e);
}
}
//定义一个方法,返回连接池对象,给QueryRunner使用
public static DataSource getDataSource(){
return dataSource;
}
//4.定义一个释放资源的方法
public static void close(ResultSet rs, Statement stat, Connection conn){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stat!=null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();//把连接在归还给连接池
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}