Java框架-Spring的jdbc、連線池及事務管理
1. Spring的AOP程式設計
1.1 純xml程式設計
<!--通知配置型別-->
<aop:config>
<!--設定切面-->
<aop:aspect ref="logger">
<!--設定切入點表示式-->
<aop:pointcut id="pt" expression="execution(* com.azure..*ServiceImpl.*(..))"></aop:pointcut>
<!--設定通知-->
<!--前置通知-->
<aop:before method="beforeLog" pointcut-ref="pt"></aop:before>
<!--後置通知-->
<aop:after-returning method="afterReturningLog" pointcut-ref="pt"></aop:after-returning>
<!--異常通知-->
<aop:after-throwing method ="afterThrowing" pointcut-ref="pt"></aop:after-throwing>
<!--最終通知-->
<aop:after method="after" pointcut-ref="pt"></aop:after>
</aop:aspect>
</aop:config>
或
<!--通知配置型別-->
<aop:config>
<!--設定切面-->
<aop:aspect ref= "logger">
<!--設定切入點表示式-->
<aop:pointcut id="pt" expression="execution(* com.azure..*ServiceImpl.*(..))"></aop:pointcut>
<!--設定通知-->
<!--環繞通知-->
<aop:around method="around" pointcut-ref="pt"></aop:around>
</aop:aspect>
</aop:config>
1.2 結合xml和註解程式設計
- 需求:service層實現事務管理,包括事務執行、事務提交,事務回滾。建議使用環繞通知
1.2.1 建立專案、新增依賴
<?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>com.azure</groupId>
<artifactId>day54projects_spring_AOP</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
</project>
1.2.2 service
1.2.2.1 介面
public interface IAccountService {
/*模擬儲存賬戶功能*/
void save();
String update(int id);
}
1.2.2.2 實現類
public class AccountServiceImpl implements IAccountService {
@Override
public void save() {
System.out.println("執行儲存方法!");
}
@Override
public String update(int id) {
System.out.println("方法引數:"+id);
return "Service本身方法返回值";
}
}
1.2.4 事務切面類
/**
* 事務切面類
*/
@Aspect //指定當前類為切面類
@Component //建立切面類物件
public class TransactionManager {
//定義切點表示式
@Pointcut("execution(* com.azure.service.*.*(..))")
public void pt(){}
/*
// 【前置通知】
@Before("pt()")
public void beginTransaction(){
System.out.println("【前置通知】 在執行目標方法之前執行");
}
//【後置通知(返回後通知)】
@AfterReturning("pt()")
public void afterReturning(){
System.out.println("【後置通知】執行目標方法正常結束執行");
}
//【異常通知】
@AfterThrowing("pt()")
public void afterThrowing(){
System.out.println("【異常通知】 執行目標方法出現異常時候執行");
}
//【最終通知】
@After("pt()")
public void after() {
System.out.println("【最終通知】在呼叫目標物件方法後始終執行");
}
*/
// 環繞目標物件方法執行
@Around("pt()")
public Object around(ProceedingJoinPoint pjp) {
try {
System.out.println("[環繞通知] 環繞前");
//獲取引數
Object[] args = pjp.getArgs();
//修改引數
args[0] = 898;
//執行方法
Object retV = pjp.proceed(args);
System.out.println("[環繞通知] 環繞後");
//返回方法執行結果,還能修改結果
return retV + "~~~想不到吧";
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println("[環繞通知] 環繞異常");
return null;
} finally {
System.out.println("[環繞通知] 環繞最終");
}
}
}
1.2.5 測試類
public class TestApp {
public static void main(String[] args) {
//建立物件
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//因為service實現介面,故採用jdk動態代理。必須用介面接收。如果用實現類接收會報錯!
IAccountService service = (IAccountService) ac.getBean("accountServiceImpl");
//class com.sun.proxy.$Proxy18
System.out.println(service.getClass());
String result = service.update(999);
System.out.println(result);
}
}
1.3 純註解程式設計
- 需求:改造上述案例程式碼,使用純註解實現
1.3.1 配置管理類
/**
* 配置管理類
* [email protected] 指定該類為配置管理類,建立容器時候只要載入當前類位元組碼就可以?
* [email protected] 開啟註解掃描,可指定多個@ComponentScan,實現掃描多個包
* 註解多個包的時候,要把所有包放在{}中,每個包之間用逗號分隔
* [email protected] 開啟註解掃描,掃描一個包(子包)
* [email protected] 開啟AOP自動代理
*/
@Configuration
@ComponentScans({
@ComponentScan(basePackages = "com.azure.service"),
@ComponentScan(basePackages = "com.azure.utils")
})
@EnableAspectJAutoProxy
public class SpringConfiguration {
}
1.3.2 測試類
@RunWith(SpringJUnit4ClassRunner.class)//使用spring的junit
@ContextConfiguration(classes = SpringConfiguration.class) //載入配置類
public class TestApp2 {
//從容器中獲取物件
@Autowired
private IAccountService service;
@Test
public void test() {
System.out.println(service.getClass());
String result = service.update(999);
System.out.println(result);
}
}
2. 事務回顧
2.1 事務概念
- 事務指一組執行單元,該單元的各個組成部分要不同時執行成功,要不同時執行失敗。
2.2 事務特性ACID
- A-原子性(Automicity):事務是不可再分割的最小工作單位;
- C-一致性(Consistency):事務必須是資料庫狀態從一個一致性狀態,轉變成另外一個一致性狀態。類似能量守恆定律
- I-隔離性(Isolation):一個事務的執行不能受到其它事務的影響。事務間相互獨立。
- D-永續性(Durability):一個事務一旦提交,則它對資料庫中的資料的改變將會永久儲存
3. Spring宣告式事務管理
- 宣告式事務管理式作用於業務層的事務處理
- Spring的事務管理控制是基於AOP的,可以使用程式設計方式也可使用配置方式。
3.1 String事務控制的API
- PlatformTransactionManager介面是Spring的事務管理器,提供獲取事務狀態資訊、提交事務、回滾事務的方法。
- 實際開發中使用其實現類
-
使用 SpringJDBC 或 iBatis 進行持久化資料時使用:
org.springframework.jdbc.datasource.DataSourceTransactionManager -
Hibernate 版本進行持久化資料時使用org.springframework.orm.hibernate5.HibernateTransactionManager
3.1.1 TransactionDefinition
-
事務的定義資訊物件
-
包含以下方法:
- String getName() 獲取事務物件名稱 - int getIsolationLevel() 獲取事務隔離級 - int getPropagationBehavior() 獲取事務傳播行為 - int getTimeout() 獲取事務超時時間 - boolean isReadOnly() 獲取事務是否只讀
-
事務的傳播行為有7種,常用的有以下三種
REQUIRED 1. 預設值 2. 表示當前執行方法必須有事務環境 3. 如果當前執行方法沒有事務環境,則建立新的事務;如果當前執行方法有事務環境,則加入當前事務,就不建立新的事務。 4. 應用:新增、修改、刪除需要指定事務的傳播行為是REQUIRED SUPPORTS 1. 支援事務 2. 當前執行方法有事務環境則支援,沒有事務環境也可以執行。事務可有可無。 3. 應用:查詢 REQUERS_NEW 1. 表示當前執行方法必須有事務環境 2. 不管當前方法有沒有事務環境,都會建立一個新的事務。
-
超時時間
預設值是-1,沒有超時限制。如果有,以秒為單位進行設定。
-
是否是隻讀事務
增刪改是讀寫事務,查詢設定為只讀
3.1.2 TransactionStatus
- 事務具體的執行狀態,提交事務和回滾事務的方法需要傳入此引數
3.2 xml配置方式實現事務管理(重要)
- 作用於service層
- 實現事務程式碼與業務程式碼完全解耦,或者說完全分離
下面以service層呼叫dao層方法儲存使用者為例,如果儲存兩個使用者的方法之間存在錯誤程式碼,而應用事務之後資料庫沒有變化,說明事務有生效
3.2.0 建立表格
- 此處省略
3.2.1建立專案,新增依賴
<?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>com.azure</groupId>
<artifactId>day55projects_spring_tx_xml</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--spring核心包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--aop支援包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<!--事務支援包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--mysql驅動包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<!--資料庫連線池c3p0-->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!--jdbctemplate-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--junit支援包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
3.2.2 實體類
public class Account {
private int accountId;
private int uid;
private double money;
/*省略*/
}
3.2.3 dao層
3.2.3.1 dao介面
public interface IAccountDao {
/*儲存賬戶*/
void save(Account account);
}
3.2.3.2 dao介面
@Repository
public class AccountDaoImpl implements IAccountDao {
/*使用註解獲取物件*/
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void save(Account account) {
jdbcTemplate.update("insert into account values (null,?,?)",account.getUid(),account.getMoney());
}
}
3.2.4 service層
3.2.4.1 service介面
public interface IAccountService {
/*儲存賬戶*/
void save(Account account);
}
3.2.4.2 service實現類
@Service
public class AccountServiceImpl implements IAccountService {
/*使用註解獲取dao物件*/
@Autowired
private IAccountDao accountDao;
@Override
public void save(Account account) {
/*模擬事務*/
accountDao.save(account);
int i = 1/0;
accountDao.save(account);
}
}
如果註釋掉int i = 1/0;
,資料庫插入兩條資料,而不註釋該行程式碼資料庫無變動,說明事務控制已生效
3.2.5 bean.xml配置
思路:
-
需要進行資料庫操作,所以要載入資料庫連線池,而載入資料庫連線池又要先載入資料庫配置檔案;
-
需要進行資料庫操作,所以要載入jdbcTemplate;
-
因為使用到註解配置,所以要開啟註解掃描;
-
使用事務管理,首先要配置事務管理類(切面類),並注入連線池
然後配置事務通知規則,攔截哪些方法,對這些方法進行什麼管理(讀寫?只讀?)
因為事務的原理是AOP,所以要配置AOP,裡面包含切入點表示式,還有重要的一點,將事務通知規則與切入點表示式建立起關係
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--0.載入資料庫配置檔案,context標籤-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--0.開啟註解掃描-->
<context:component-scan base-package="com.azure"></context:component-scan>
<!--1.配置資料庫連線池-->
<bean
相關推薦
Java框架-Spring的jdbc、連線池及事務管理
1. Spring的AOP程式設計
1.1 純xml程式設計
<!--通知配置型別-->
<aop:config>
<!--設定切面-->
<aop:aspect ref="logger">
<!-
JDBC(資料庫的驅動、連線、java程式操作資料庫、事務、隔離級別、連線池等)
java操作資料庫的思想:連上資料庫,傳送sql語句。在連上資料庫之前,要先用程式啟動資料庫,因此,可以通過反射載入類驅動(com.jdbc.mysql.Driver)。通過驅動管理類的靜態方法傳遞資料庫的url來獲取一個連線物件(connection)。有三個過載的方法,第一個user和p
java 偏向鎖、輕量級鎖及重量級鎖synchronized原理
bubuko 固定 使用情況 防止 不能 image 過程 記錄 原因
Java對象頭與Monitor
java對象頭是實現synchronized的鎖對象的基礎,synchronized使用的鎖對象是存儲在Java對象頭裏的。
對象頭包含兩部分:Mark Word 和
spring-data-mono java註解方式mongo連線池帶認證配置
import com.mongodb.MongoClient; import com.mongodb.MongoClientOptions; import com.mongodb.MongoCredential; import com.mongodb.ServerAddress; import or
JVM (二)--Java程式編譯、類載入及執行
Java程式的編譯
Java程式的編譯是由Java原始碼編譯器來完成,流程圖如下:
Java程式的執行
Java程式的編譯是由Java執行引擎來完成,流程圖如下:
Java程式碼編譯和執行的整個過程包含了以下三個重要的機制:
Java原始
java----day30(DBUtils和連線池)
DBUtils
概述
DBUtils是java程式設計中的資料庫操作實用工具,小巧簡單實用。
DBUtils封裝了對JDBC的操作,簡化了JDBC操作,可以少寫程式碼。
Dbutils三個核心功能介紹
QueryRunner中提供對sql語句操作的API.
java專案使用redis / 連線池配置
1. pom
<dependency>
<groupId>
Mysql密碼更改、連線MySQL及常用命令
12月5日任務
13.1 設定更改root密碼
13.2 連線mysql
13.3 mysql常用命令
設定更改root密碼
要進行mysql資料庫操作,需要啟動mysql服務,執行ps aux進行檢視
[[email protected]
hibernate框架之DBCP連線池配置
hibernate配置資料庫連線池的三種方法https://blog.csdn.net/super712/article/details/52823192
以下是hibernate配置檔案裡面配置dbcp的demo;
<?xml version="1.0" encodi
Java框架Mybatis的工作流程及原理
Mybatis簡介:
MyBatis 是一款優秀的持久層框架,它支援定製化 SQL、儲存過程以及高階對映。MyBatis 避免了幾乎所有的 JDBC 程式碼和手動設定引數以及獲取結果集。MyBatis 可以使用簡單的 XML 或註解來配置
Java中DriverManager跟DataSource獲取getConnection有什麼不同(Java中資料來源和連線池的區別)
一、理解什麼是資料來源和連線池
資料來源:資料的源頭,需要設定資料庫url,使用者名稱和密碼,此時就相當於一個代理資料庫;它包含連線池和連線池管理兩個部分;
Java中的資料來源就是javax.
關於“池”機制的思考(執行緒池、程序池、連線池等)
“池”機制的兩大核心
重用
緩衝
統一管理“池”裡的物件 (這個不能作為核心) 。。。。。
【1】“池”機制有個定長的容器。
【2】初始化時容器中儲存有定量的“池”物件(在此用“池”物件統稱“池”中的執行緒、程序或者連結等,下文同)。 【3
Java——Lambda表示式、方法引用及內建函式式介面
1.Lambda表示式
面向物件的基礎上支援函數語言程式設計
1.1 約束:
介面有且僅有一個抽象方法,如果存在兩個抽象方法,則無法使用函數語言程式設計。
介面有且僅有一個抽象方法,且想要轉化為lambda表示式,加註解 @FunctionalInterface
關於 PHP MySQL 長連線、連線池的一些探索
hp連線mysql的方式,用的多的是mysql擴充套件、mysqli擴充套件、pdo_mysql擴充套件,是官方提供的。php的執行機制是頁面執行完會釋放所有該php程序中的所有資源的,如果有多個併發訪問本地的測試頁面 http://127.0.0.1/1.ph
OkHttp3的連線池及連線建立過程分析
如我們前面在 OkHttp3 HTTP請求執行流程分析 中的分析,OkHttp3通過Interceptor鏈來執行HTTP請求,整體的執行過程大體如下:
OkHttp Flow
這些Interceptor中每一個的職責,這裡不再贅述。
在OkHttp3中,Str
Spring boot2.0以上整合Druid連線池及監控資訊配置
1. Springboot 2.0選擇HikariCP作為預設資料庫連線池
理由參考:
2. 資料庫連線池效能比對(hikari druid c3p0 dbcp jdbc)
本文是整合Druid連線池,資料庫為mysql
pom檔案新增druid的依
JAVA基礎26-資料庫連線池
資料庫連線池
資料庫連線池負責分配,管理,釋放資料庫連線,它允許應用程式重複使用一個現有的資料庫連線,而不是重新建立一個。
編寫資料庫連線池
編寫資料庫連線池必須實現java.sql.DataSource介面
在Da
springboot2配置使用Druid連線池及使用的時候出現的連線問題
最近在springboot2專案中使用了Druid連線池,在此記錄一下,整合過程
首先:引入Maven配置項
<dependency>
<groupId>com.alibaba</groupId>
<artifac
Spring框架中獲取連線池的方式
1、連線池概述 資料庫連線是一種關鍵的有限的昂貴的資源,這一點在多使用者的網頁應用程式中體現得尤為突出。對資料庫連線的管理能顯著影響到整個應用程式的伸縮性和健壯性,影響到程式的效能指標。資料庫連線池正是針對這個問題提出來的。 資料庫連線池負責分配、管理和釋放資料庫
java操作mongodb(連線池)
Mongo的例項其實就是一個數據庫連線池,這個連線池裡預設有10個連結。我們沒有必要重新實現這個連結池,但是我們可以更改這個連線池的配置。因為Mongo的例項就是一個連線池,所以,專案中最好只存在一個Mongo的例項。
常見的配置引數:
connectionsPerHost