日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

9-分析事物问题并编写 Utils 文件

發(fā)布時(shí)間:2025/5/22 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 9-分析事物问题并编写 Utils 文件 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

  • 接下來安排
  • 一、創(chuàng)建新工程
    • 1. pom.xml
    • 2.結(jié)構(gòu)
    • 3.接口與實(shí)現(xiàn)類添加的操作
      • ⅠIAccountDao
      • Ⅱ AccountDaoImpl
      • Ⅲ IAccountService
      • 四 IAccountService
      • Ⅴ Test
      • Ⅵ 問題
  • 二、編寫 ConnectionUtils
    • 1. ConnectionUtils 類
    • 2. TransactionManager類
  • 三、編寫業(yè)務(wù)層和持久層事務(wù)控制代碼并配置 spring 的 ioc
    • 1.AccountServiceImpl
    • 2.AccountDaoImpl
    • 3.Test
    • 4.結(jié)果

接下來安排

  • 完善 account 案例
  • 分析案例中問題
  • 回顧之前講過的一個(gè)技術(shù):動態(tài)代理
  • 動態(tài)代理另一種實(shí)現(xiàn)方式
  • 解決案例中的問題
  • AOP 的概念
  • spring 中的 AOP 相關(guān)術(shù)語
  • spring 中基于 XML 和注解的 AOP
  • 一、創(chuàng)建新工程

    創(chuàng)建新的 maven 工程,命名為 spring07

    做一個(gè)轉(zhuǎn)賬的小操作

    1. pom.xml

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>spring07</groupId><artifactId>spring07</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><dependencies><!-- https://mvnrepository.com/artifact/org.springframework/spring-context --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.9.RELEASE</version></dependency><!-- https://mvnrepository.com/artifact/commons-dbutils/commons-dbutils --><dependency><groupId>commons-dbutils</groupId><artifactId>commons-dbutils</artifactId><version>1.7</version></dependency><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>6.0.6</version></dependency><!-- https://mvnrepository.com/artifact/com.mchange/c3p0 --><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.4</version></dependency><!-- https://mvnrepository.com/artifact/junit/junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-test --><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.1.9.RELEASE</version><scope>test</scope></dependency></dependencies> </project>

    2.結(jié)構(gòu)

    3.接口與實(shí)現(xiàn)類添加的操作

    ⅠIAccountDao

    /*** 根據(jù)名稱查詢賬戶* @param accountName 賬戶名稱* @return 如果有唯一結(jié)果就返回,沒有就返回 Null, 如果結(jié)果有多個(gè),這返回錯(cuò)誤*/Account findAccountByName(String accountName);

    Ⅱ AccountDaoImpl

    public void updateAccount(Account account) {try {runner.update("update account02 set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());}catch (SQLException e){e.printStackTrace();}}public Account findAccountByName(String accountName) {List<Account> accounts=null;try {accounts= runner.query("select *from account02 where name=?",new BeanListHandler<Account>(Account.class),accountName);if (accounts==null || accounts.size()==0){return null;}if(accounts.size()>1){throw new RuntimeException("結(jié)果集不唯一,數(shù)據(jù)有問題");}} catch (SQLException e) {e.printStackTrace();}return accounts.get(0);}

    Ⅲ IAccountService

    /*** 轉(zhuǎn)賬* @param sourceName 轉(zhuǎn)出賬戶名稱* @param targetName 轉(zhuǎn)入賬戶名稱* @param money 轉(zhuǎn)賬金額*/void transfer(String sourceName,String targetName,Float money);/*** 更新* @param account*/void updateAccount(Account account);

    四 IAccountService

    public void transfer(String sourceName, String targetName, Float money) {//1.根據(jù)名稱查詢轉(zhuǎn)出賬戶Account source=accountDao.findAccountByName(sourceName);//2.根據(jù)名稱查詢轉(zhuǎn)入賬戶Account target=accountDao.findAccountByName(targetName);//3.轉(zhuǎn)出賬戶減錢source.setMoney(source.getMoney()-money);//4.轉(zhuǎn)入賬戶加錢target.setMoney(target.getMoney()+money);//5.更新轉(zhuǎn)出賬戶accountDao.updateAccount(source);//6.更新轉(zhuǎn)入賬戶accountDao.updateAccount(target);}

    Ⅴ Test

    @Testpublic void testTransfer(){as.transfer("aaa","bbb",10f);}

    測試結(jié)果沒有問題

    Ⅵ 問題

    假如 我們在AccountServiceImpl 這樣操作一波,多加了個(gè) int i=1/0;

    public void transfer(String sourceName, String targetName, Float money) {//1.根據(jù)名稱查詢轉(zhuǎn)出賬戶Account source=accountDao.findAccountByName(sourceName);//2.根據(jù)名稱查詢轉(zhuǎn)入賬戶Account target=accountDao.findAccountByName(targetName);//3.轉(zhuǎn)出賬戶減錢source.setMoney(source.getMoney()-money);//4.轉(zhuǎn)入賬戶加錢target.setMoney(target.getMoney()+money);//5.更新轉(zhuǎn)出賬戶accountDao.updateAccount(source);int i=1/0;//6.更新轉(zhuǎn)入賬戶accountDao.updateAccount(target);}

    運(yùn)行,你會看到 source 的賬戶減錢了,而 target 的賬戶卻沒有價(jià)錢,這怎么辦?

    原因:

    這是一個(gè)多例對象

    解決:

    要讓四個(gè)操作全為同一個(gè) connection 來實(shí)現(xiàn)

    需要使用 ThreadLocal 對象把 Connection 和當(dāng)前線程綁定,從而使一個(gè)線程中只有一能控制事務(wù)的對象

    二、編寫 ConnectionUtils

    創(chuàng)建 utiles 文件夾

    創(chuàng)建 ConnectionUtils 類

    創(chuàng)建 TransactionManager類

    1. ConnectionUtils 類

    package com.utils;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;import javax.sql.DataSource; import java.sql.Connection;/*** 描述:* 〈連接的工具類,它用于從數(shù)據(jù)源中獲取一個(gè)連接,并且實(shí)現(xiàn)和線程的綁定〉** @author zuiren* @create 2019/8/30* @since 1.0.0*/ @Component("connectionUtils") public class ConnectionUtils {private ThreadLocal<Connection> tl=new ThreadLocal<Connection>();@Autowiredprivate DataSource dataSource;public Connection getThreadConnection(){//1.先從 ThreadLocal 上獲取Connection conn=tl.get();try {//2.判斷當(dāng)前線程是否有連接if (conn==null){//3.從數(shù)據(jù)源中獲取一個(gè)鏈接,并且存入 ThreadLocal 中conn=dataSource.getConnection();tl.set(conn);}//4.返回當(dāng)前線程上的連接return conn;}catch (Exception e){throw new RuntimeException(e);}}/*** 把連接和線程解綁*/public void removeConnection(){tl.remove();} }

    2. TransactionManager類

    package com.utils;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;import java.sql.SQLException;/*** 描述:* 〈和事務(wù)相關(guān)的工具類,它包含了,開啟事務(wù),提交事務(wù),回滾事務(wù)和釋放連接〉** @author zuiren* @create 2019/8/30* @since 1.0.0*/ @Component(value = "txManager") public class TransactionManager {@Autowiredprivate ConnectionUtils connectionUtils;/*** 開啟事務(wù)*/public void beginTransaction() {try {connectionUtils.getThreadConnection().setAutoCommit(false);} catch (SQLException e) {e.printStackTrace();}}/*** 開啟事務(wù)*/public void commit(){try {connectionUtils.getThreadConnection().commit();} catch (SQLException e) {e.printStackTrace();}}/*** 回滾事務(wù)*/public void rollback(){try {connectionUtils.getThreadConnection().rollback();} catch (SQLException e) {e.printStackTrace();}}/*** 釋放連接*/public void release(){try {//還回池中connectionUtils.getThreadConnection().close();connectionUtils.removeConnection();} catch (SQLException e) {e.printStackTrace();}} }

    細(xì)節(jié)

    連接使用了連接池,

    連接池的好處:把消耗時(shí)間連接獲取連接的這部分放到應(yīng)用加載一開始。

    在 web 工程中,當(dāng)我們啟動tomcat加載應(yīng)用時(shí),我們創(chuàng)建一些連接,從而在后續(xù)項(xiàng)目運(yùn)行階段不在跟數(shù)據(jù)庫獲取鏈接保證了我們使用 connection 時(shí)的使用效率。

    我們使用服務(wù)器,服務(wù)器也會有一個(gè)池的技術(shù)叫做線程池,它的特點(diǎn)是當(dāng) connection 啟動時(shí),會啟動一大堆的線程放到一個(gè)容器中,接下來我們每次訪問,它都是從線程池中拿出一個(gè)線程給我們使用。

    這樣的話線程池中的線程也跟我們連接池中的一樣,所以我們最后調(diào)用

    connectionUtils.getThreadConnection().close();

    的方法并不是將其關(guān)閉,而是將他放回線程池中。

    造理推斷,線程用完了,也不是真正的關(guān)了,而是把線程還回線程池中。

    所以這個(gè)線程中是綁著一個(gè)連接的,當(dāng)我們把連接關(guān)閉,線程還回池中時(shí),線程上是有連接的,只不過這個(gè)連接已經(jīng)被關(guān)閉了,當(dāng)我們下次再獲取這個(gè)線程判斷上面有沒有連接時(shí),你得到的結(jié)果一定是有,但是這個(gè)連接已經(jīng)不能用了,因?yàn)樗呀?jīng)被 close 過了,被加載過池子里去了。

    所以從這點(diǎn)上來說:我們應(yīng)該在整個(gè)這個(gè)線程用完了之后,把這個(gè)線程和這個(gè)連接進(jìn)行解綁。

    在 ConnectionUtils 類中添加一方法

    /*** 把連接和線程解綁*/public void removeConnection(){tl.remove();}

    在 TransactionManager 類

    /*** 釋放連接*/public void release(){try {//還回池中connectionUtils.getThreadConnection().close();connectionUtils.removeConnection();} catch (SQLException e) {e.printStackTrace();}}

    三、編寫業(yè)務(wù)層和持久層事務(wù)控制代碼并配置 spring 的 ioc

    1.AccountServiceImpl

    package com.service.Impl;import com.dao.IAccountDao; import com.domain.Account; import com.service.IAccountService; import com.utils.TransactionManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.util.List; import java.util.TreeMap;/*** 描述:* 〈〉** @author zuiren* @create 2019/8/29* @since 1.0.0*/ @Service("accountService") public class AccountServiceImpl implements IAccountService {@Autowiredprivate IAccountDao accountDao;@Autowiredprivate TransactionManager txManager;public List<Account> findAllAccount() {List<Account> accounts=null;try {//1.開啟事務(wù)txManager.beginTransaction();//2.執(zhí)行操作accounts=accountDao.findAllAccount();//3.提交事務(wù)txManager.commit();//4.返回結(jié)果return accounts;}catch (Exception e){//5.回滾操作txManager.rollback();}finally {//6.釋放資源txManager.release();}return accounts;}public Account findAccountById(Integer accountId) {Account account=null;try {//1.開啟事務(wù)txManager.beginTransaction();//2.執(zhí)行操作account=accountDao.findAccountById(accountId);//3.提交事務(wù)txManager.commit();//4.返回結(jié)果return account;}catch (Exception e){//5.回滾操作txManager.rollback();}finally {//6.釋放資源txManager.release();}return account;}public void saveAccount(Account account) {try {//1.開啟事務(wù)txManager.beginTransaction();//2.執(zhí)行操作accountDao.saveAccount(account);//3.提交事務(wù)txManager.commit();//4.返回結(jié)果}catch (Exception e){//5.回滾操作txManager.rollback();}finally {//6.釋放資源txManager.release();}}public void updateAccount(Account account) {try {//1.開啟事務(wù)txManager.beginTransaction();//2.執(zhí)行操作accountDao.updateAccount(account);//3.提交事務(wù)txManager.commit();//4.返回結(jié)果}catch (Exception e){//5.回滾操作txManager.rollback();}finally {//6.釋放資源txManager.release();}}public void deleteAccount(Integer accountId) {try {//1.開啟事務(wù)txManager.beginTransaction();//2.執(zhí)行操作accountDao.deleteAccount(accountId);//3.提交事務(wù)txManager.commit();//4.返回結(jié)果}catch (Exception e){//5.回滾操作txManager.rollback();}finally {//6.釋放資源txManager.release();}}public void transfer(String sourceName, String targetName, Float money) {try {txManager.beginTransaction();//1.根據(jù)名稱查詢轉(zhuǎn)出賬戶Account source=accountDao.findAccountByName(sourceName);//2.根據(jù)名稱查詢轉(zhuǎn)入賬戶Account target=accountDao.findAccountByName(targetName);//3.轉(zhuǎn)出賬戶減錢source.setMoney(source.getMoney()-money);//4.轉(zhuǎn)入賬戶加錢target.setMoney(target.getMoney()+money);//5.更新轉(zhuǎn)出賬戶accountDao.updateAccount(source);int i=1/0;//6.更新轉(zhuǎn)入賬戶accountDao.updateAccount(target);txManager.commit();}catch (Exception e){txManager.rollback();}finally {txManager.release();}} }

    2.AccountDaoImpl

    這里只是在 runner 執(zhí)行操作時(shí),給它配置連接

    package com.dao.Impl;import com.dao.IAccountDao; import com.domain.Account; import com.utils.ConnectionUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service;import java.sql.SQLException; import java.util.List;/*** 描述:* 〈〉** @author zuiren* @create 2019/8/29* @since 1.0.0*/ @Repository("accountDao") public class AccountDaoImpl implements IAccountDao {@Autowiredprivate QueryRunner runner;@Autowiredprivate ConnectionUtils connectionUtils;public List<Account> findAllAccount() {try {return runner.query(connectionUtils.getThreadConnection(),"select *from account02",new BeanListHandler<Account>(Account.class));}catch (Exception e){throw new RuntimeException(e);}}public Account findAccountById(Integer accountId) {try {return runner.query(connectionUtils.getThreadConnection(),"select *from account02 where id = ?",new BeanHandler<Account>(Account.class),accountId);}catch (Exception e){throw new RuntimeException(e);}}public void saveAccount(Account account) {try {runner.update(connectionUtils.getThreadConnection(),"insert into account02(name,money) values(?,?)",account.getName(),account.getMoney());}catch (SQLException e){e.printStackTrace();}}public void updateAccount(Account account) {try {runner.update(connectionUtils.getThreadConnection(),"update account02 set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());}catch (SQLException e){e.printStackTrace();}}public void deleteAccount(Integer accountId) {try {runner.update(connectionUtils.getThreadConnection(),"delete from account02 where id=?",accountId);}catch (SQLException e){e.printStackTrace();}}public Account findAccountByName(String accountName) {List<Account> accounts=null;try {accounts= runner.query(connectionUtils.getThreadConnection(),"select *from account02 where name=?",new BeanListHandler<Account>(Account.class),accountName);if (accounts==null || accounts.size()==0){return null;}if(accounts.size()>1){throw new RuntimeException("結(jié)果集不唯一,數(shù)據(jù)有問題");}} catch (SQLException e) {e.printStackTrace();}return accounts.get(0);} }

    3.Test

    @Testpublic void testTransfer(){as.transfer("aaa","bbb",10f);}

    4.結(jié)果

    你會發(fā)現(xiàn)報(bào)錯(cuò),事務(wù)回滾,aaa 的 money 沒有變化,轉(zhuǎn)賬正常執(zhí)行。

    問題是現(xiàn)在依賴特別混亂,以后會解決

    轉(zhuǎn)載于:https://www.cnblogs.com/zuiren/p/11437528.html

    總結(jié)

    以上是生活随笔為你收集整理的9-分析事物问题并编写 Utils 文件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。