在千锋“逆战”学习第44天
每日一句:一本好书,就像高级武功秘籍一样,哪怕只是从里面领悟到个一招半势,功力提升起来都是惊人的。
今天学习了连接池和业务。
明天继续努力。
转账案例
public class DBUtils {
private static final Properties PROPERTIES = new Properties();
//为当前线程绑定一个Connection连接。从头到尾
private static final ThreadLocal<Connection> THREAD_LOCAL = new ThreadLocal<Connection>();
static {
InputStream is = DBUtils.class.getResourceAsStream("/database.properties");
try {
PROPERTIES.load(is);
Class.forName(PROPERTIES.getProperty("driver"));
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() {
//在ThreadLocal里取
Connection connection = THREAD_LOCAL.get();
try {
//没有 ,新建
if (connection == null) {
connection = DriverManager.getConnection(PROPERTIES.getProperty("url"), PROPERTIES.getProperty("username"), PROPERTIES.getProperty("password"));
THREAD_LOCAL.set(connection);//存在ThreadLocal里
}
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
//释放资源
public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) {
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
THREAD_LOCAL.remove();//关闭连接后,移除线程中绑定的连接对象。
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public class T_Account {
private String cardId;
private String password;
private String username;
private double balance;
private String phone;
@Override
public String toString() {
return "T_Account{" +
"cardId='" + cardId + '\'' +
", password='" + password + '\'' +
", username='" + username + '\'' +
", balance=" + balance +
", phone='" + phone + '\'' +
'}';
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public T_Account() {
}
public T_Account(String cardId, String password, String username, double balance, String phone) {
this.cardId = cardId;
this.password = password;
this.username = username;
this.balance = balance;
this.phone = phone;
}
}
public class T_AccountDaoImpl {
private Connection connection = null;
private PreparedStatement preparedStatement = null;
private ResultSet resultSet = null;
public int insert(T_Account account) {
return 0;
}
public int delete(String cardId) {
return 0;
}
//修改操作!复用性更强
public int update(T_Account account) {
System.out.println(Thread.currentThread().getName());
connection = DBUtils.getConnection();
System.out.println("update:"+connection);
String sql = "update t_account set password=?,username=?,balance=?,phone = ? where cardid = ?";
try {
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,account.getPassword());
preparedStatement.setString(2,account.getUsername());
preparedStatement.setDouble(3,account.getBalance());
preparedStatement.setString(4,account.getPhone());
preparedStatement.setString(5,account.getCardId());
return preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
DBUtils.closeAll(null, preparedStatement,resultSet);
}
return 0;
}
public T_Account select(String cardId) {
System.out.println(Thread.currentThread().getName());
connection = DBUtils.getConnection();
System.out.println("select:"+connection);
String sql = "SELECT cardid,PASSWORD,username,balance,phone FROM t_account where cardId = ? ";
T_Account account = null;
try {
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,cardId);
resultSet = preparedStatement.executeQuery();
if(resultSet.next()){
account = new T_Account(resultSet.getString(1),resultSet.getString(2),resultSet.getString(3),resultSet.getDouble(4),resultSet.getString(5));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
DBUtils.closeAll(null,preparedStatement,resultSet);
}
return account;
}
}
public class T_AccountServiceImpl {
/**
* 转账业务
*
* @param fromNo 转账卡号
* @param pwd 转账卡号密码
* @param toNo 收钱卡号
* @param money 转账金额
*/
public String transfer(String fromNo, String pwd, String toNo, double money) {//收参
String result = "转账失败!";
System.out.println(Thread.currentThread().getName());
//2.组织业务功能
T_AccountDaoImpl accountDao = new T_AccountDaoImpl();
//拿一个连接
Connection connection = null;
try {
//建立了一个数据库连接
connection = DBUtils.getConnection();
System.out.println("service:"+connection);
//开启事务! 并且关闭事务的自动提交
connection.setAutoCommit(false);
//2.1验证fromNo是否存在
T_Account fromAcc = accountDao.select(fromNo);
if (fromAcc == null) {
throw new RuntimeException("----卡号不存在-----");
}
//2.2验证fromNo的密码是否正确
if (!fromAcc.getPassword().equals(pwd)) {
throw new RuntimeException("----密码错误----");
}
//2.3验证余额是否充足
if (fromAcc.getBalance() < money) {
throw new RuntimeException("----余额不足----");
}
//2.4验证toNo是否存在
T_Account toAcc = accountDao.select(toNo);
if (toAcc == null) {
throw new RuntimeException("----对方卡号不存在----");
}
//2.5减少fromNo的余额
//修改自己的金额,将余额-转账金额替换原有的属性
fromAcc.setBalance(fromAcc.getBalance() - money);
accountDao.update(fromAcc);
//出现异常!导致程序终止!
int i = 10 / 0;
//2.6增加toNo的余额
toAcc.setBalance(toAcc.getBalance() + money);
accountDao.update(toAcc);
result = "转账成功!";
//执行到这里,没有异常,则提交事务!
connection.commit();
} catch (Exception e) {
e.printStackTrace();
try {
//出现异常,回滚!
System.out.println("出现了异常!回滚整个事务!");
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
}finally {
DBUtils.closeAll(connection,null,null);
}
return result;
}
}
public class TestTransfer {
public static void main(String[] args) {
T_AccountServiceImpl t_accountService = new T_AccountServiceImpl();
System.out.println(Thread.currentThread().getName());
String result = t_accountService.transfer("202003302110","123456","202003302050",2000);
System.out.println(result);
}
}