Spring 框架(二)

1 AOP

1.1 AOP介紹

1.1.1 什麼是AOP

在軟件業,AOPAspect Oriented Programming的縮寫,意爲:面向切面編程,經過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。AOPOOP(面向對象編程)的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生範型。利用AOP能夠對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度下降,提升程序的可重用性,同時提升了開發的效率。java

l AOP採起橫向抽取機制,取代了傳統縱向繼承體系重複性代碼mysql

經典應用:事務管理、性能監視、安全檢查、緩存 、日誌等spring

l Spring AOP使用純Java實現,不須要專門的編譯過程和類加載器,在運行期經過代理方式向目標類織入加強代碼sql

l AspectJ是一個基於Java語言的AOP框架Spring2.0開始,Spring AOP引入對Aspect的支持,AspectJ擴展了Java語言,提供了一個專門的編譯器,在編譯時提供橫向代碼的織入express

 

 

1.1.2 AOP實現原理

l aop底層將採用代理機制進行實現。apache

接口 + 實現類 :spring採用 jdk 動態代理Proxy編程

實現類:spring 採用 cglib字節碼加強設計模式

 

 

1.1.3 AOP術語【掌握】

1.target:目標類,須要被代理的類。例如:UserServiceapi

2.Joinpoint(鏈接點):所謂鏈接點是指那些可能被攔截到的方法。例如:全部的方法緩存

3.PointCut 切入點:已經被加強的鏈接點。例如:addUser()

4.advice 通知/加強,加強代碼。例如:afterbefore

5. Weaving(織入):是指把加強advice應用到目標對象target來建立新的代理對象proxy的過程.

6.proxy 代理類

7. Aspect(切面): 是切入點pointcut和通知advice的結合

一個線是一個特殊的面。

一個切入點和一個通知,組成成一個特殊的面。

 

 

1.2 手動方式

12.1 JDK動態代理

l JDK動態代理 對「裝飾者」設計模式 簡化。使用前提:必須有接口

1.目標類:接口 + 實現類

2.切面類:用於存通知 MyAspect

3.工廠類:編寫工廠生成代理

4.測試

 

 

1.2.1.1 目標類

public interface UserService {

 

public void addUser();

public void updateUser();

public void deleteUser();

 

}

 

1.2.1.2 切面類

public class MyAspect {

 

public void before(){

System.out.println("雞首");

}

 

public void after(){

System.out.println("牛後");

}

 

}

 

 

1.2.1.3 工廠

public class MyBeanFactory {

 

public static UserService createService(){

//1 目標類

final UserService userService = new UserServiceImpl();

//2切面類

final MyAspect myAspect = new MyAspect();

/* 3 代理類:將目標類(切入點)和 切面類(通知) 結合 --> 切面

 * Proxy.newProxyInstance

 * 參數1loader ,類加載器,動態代理類 運行時建立,任何類都須要類加載器將其加載到內存。

 * 通常狀況:當前類.class.getClassLoader();

 * 目標類實例.getClass().get...

 * 參數2Class[] interfaces 代理類須要實現的全部接口

 * 方式1:目標類實例.getClass().getInterfaces()  ;注意:只能得到本身接口,不能得到父元素接口

 * 方式2new Class[]{UserService.class}   

 * 例如:jdbc 驅動  --> DriverManager  得到接口 Connection

 * 參數3InvocationHandler  處理類,接口,必須進行實現類,通常採用匿名內部

 * 提供 invoke 方法,代理類的每個方法執行時,都將調用一次invoke

 * 參數31Object proxy :代理對象

 * 參數32Method method : 代理對象當前執行的方法的描述對象(反射)

 * 執行方法名:method.getName()

 * 執行方法:method.invoke(對象,實際參數)

 * 參數33Object[] args :方法實際參數

 *

 */

UserService proxService = (UserService)Proxy.newProxyInstance(

MyBeanFactory.class.getClassLoader(),

userService.getClass().getInterfaces(),

new InvocationHandler() {

 

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

 

//前執行

myAspect.before();

 

//執行目標類的方法

Object obj = method.invoke(userService, args);

 

//後執行

myAspect.after();

 

return obj;

}

});

 

return proxService;

}

 

}

 

 

1.2.1.4 測試

@Test

public void demo01(){

UserService userService = MyBeanFactory.createService();

userService.addUser();

userService.updateUser();

userService.deleteUser();

}

 

 

1.2.2 CGLIB字節碼加強

沒有接口,只有實現類。

採用字節碼加強框架 cglib,在運行時 建立目標類的子類,從而對目標類進行加強。

導入jar包:

本身導包(瞭解):

核心:hibernate-distribution-3.6.10.Final\lib\bytecode\cglib\cglib-2.2.jar

依賴:struts-2.3.15.3\apps\struts2-blank\WEB-INF\lib\asm-3.3.jar

spring-core..jar 已經整合以上兩個內容

 

 

 

1.2.2.1 工廠類

public class MyBeanFactory {

 

public static UserServiceImpl createService(){

//1 目標類

final UserServiceImpl userService = new UserServiceImpl();

//2切面類

final MyAspect myAspect = new MyAspect();

// 3.代理類 ,採用cglib,底層建立目標類的子類

//3.1 核心類

Enhancer enhancer = new Enhancer();

//3.2 肯定父類

enhancer.setSuperclass(userService.getClass());

/* 3.3 設置回調函數 , MethodInterceptor接口 等效 jdk InvocationHandler接口

 * intercept() 等效 jdk  invoke()

 * 參數1、參數2、參數3:以invoke同樣

 * 參數4methodProxy 方法的代理

 *

 *

 */

enhancer.setCallback(new MethodInterceptor(){

 

@Override

public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

 

//

myAspect.before();

 

//執行目標類的方法

Object obj = method.invoke(userService, args);

// * 執行代理類的父類 ,執行目標類 (目標類和代理類 父子關係)

methodProxy.invokeSuper(proxy, args);

 

//

myAspect.after();

 

return obj;

}

});

//3.4 建立代理

UserServiceImpl proxService = (UserServiceImpl) enhancer.create();

 

return proxService;

}

 

}

 

 

1.3 AOP聯盟通知類型

l AOP聯盟爲通知Advice定義了org.aopalliance.aop.Advice

l Spring按照通知Advice在目標類方法的鏈接點位置,能夠分爲5

  • 前置通知 org.springframework.aop.MethodBeforeAdvice
    • 在目標方法執行前實施加強
  • 後置通知 org.springframework.aop.AfterReturningAdvice
    • 在目標方法執行後實施加強
  • 環繞通知 org.aopalliance.intercept.MethodInterceptor
    • 在目標方法執行先後實施加強
  • 異常拋出通知 org.springframework.aop.ThrowsAdvice
    • 在方法拋出異常後實施加強
  • 引介通知 org.springframework.aop.IntroductionInterceptor
    • 在目標類中添加一些新的方法和屬性

 

環繞通知,必須手動執行目標方法

try{

   //前置通知

   //執行目標方法

   //後置通知

} catch(){

   //拋出異常通知

}

 

1.4 spring編寫代理:半自動

spring 建立代理對象,從spring容器中手動的獲取代理對象。

導入jar包:

核心:4+1

AOPAOP聯盟(規範)、spring-aop (實現)

 

 

1.4.1 目標類

public interface UserService {

 

public void addUser();

public void updateUser();

public void deleteUser();

 

}

 

1.4.2 切面類

/**

 * 切面類中肯定通知,須要實現不一樣接口,接口就是規範,從而就肯定方法名稱。

 * * 採用環繞通知」 MethodInterceptor

 *

 */

public class MyAspect implements MethodInterceptor {

 

@Override

public Object invoke(MethodInvocation mi) throws Throwable {

 

System.out.println("3");

 

//手動執行目標方法

Object obj = mi.proceed();

 

System.out.println("3");

return obj;

}

}

 

 

1.4.3 spring配置

<!-- 1 建立目標類 -->

<bean id="userServiceId" class="com.itheima.b_factory_bean.UserServiceImpl"></bean>

<!-- 2 建立切面類 -->

<bean id="myAspectId" class="com.itheima.b_factory_bean.MyAspect"></bean>

 

<!-- 3 建立代理類

* 使用工廠bean FactoryBean ,底層調用 getObject() 返回特殊bean

* ProxyFactoryBean 用於建立代理工廠bean,生成特殊代理對象

interfaces : 肯定接口們

經過<array>能夠設置多個值

只有一個值時,value=""

target : 肯定目標類

interceptorNames : 通知 切面類的名稱,類型String[],若是設置一個值 value=""

optimize :強制使用cglib

<property name="optimize" value="true"></property>

底層機制

若是目標類有接口,採用jdk動態代理

若是沒有接口,採用cglib 字節碼加強

若是聲明 optimize = true ,不管是否有接口,都採用cglib

 

-->

<bean id="proxyServiceId" class="org.springframework.aop.framework.ProxyFactoryBean">

<property name="interfaces" value="com.itheima.b_factory_bean.UserService"></property>

<property name="target" ref="userServiceId"></property>

<property name="interceptorNames" value="myAspectId"></property>

</bean>

 

1.4.4 測試

 

 

@Test

public void demo01(){

String xmlPath = "com/itheima/b_factory_bean/beans.xml";

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);

 

//得到代理類

UserService userService = (UserService) applicationContext.getBean("proxyServiceId");

userService.addUser();

userService.updateUser();

userService.deleteUser();

}

 

 

 

 

 

1.5 spring aop編程:全自動【掌握】

spring容器得到目標類,若是配置aopspring將自動生成代理。

要肯定目標類,aspectj 切入點表達式,導入jar

spring-framework-3.0.2.RELEASE-dependencies\org.aspectj\com.springsource.org.aspectj.weaver\1.6.8.RELEASE

 

 

1.5.1 spring配置

 

 

<?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: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/aop

          http://www.springframework.org/schema/aop/spring-aop.xsd">

<!-- 1 建立目標類 -->

<bean id="userServiceId" class="com.itheima.c_spring_aop.UserServiceImpl"></bean>

<!-- 2 建立切面類(通知) -->

<bean id="myAspectId" class="com.itheima.c_spring_aop.MyAspect"></bean>

<!-- 3 aop編程

3.1 導入命名空間

3.2 使用 <aop:config>進行配置

proxy-target-class="true" 聲明時使用cglib代理

<aop:pointcut> 切入點 ,從目標對象得到具體方法

<aop:advisor> 特殊的切面,只有一個通知 和 一個切入點

advice-ref 通知引用

pointcut-ref 切入點引用

3.3 切入點表達式

execution(* com.itheima.c_spring_aop.*.*(..))

選擇方法         返回值任意   包             類名任意   方法名任意   參數任意

 

-->

<aop:config proxy-target-class="true">

<aop:pointcut expression="execution(* com.itheima.c_spring_aop.*.*(..))" id="myPointCut"/>

<aop:advisor advice-ref="myAspectId" pointcut-ref="myPointCut"/>

</aop:config>

</beans>

 

1.5.2 測試

@Test

public void demo01(){

String xmlPath = "com/itheima/c_spring_aop/beans.xml";

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);

 

//得到目標類

UserService userService = (UserService) applicationContext.getBean("userServiceId");

userService.addUser();

userService.updateUser();

userService.deleteUser();

}

 

2 AspectJ

2.1 介紹

l AspectJ是一個基於Java語言的AOP框架

l Spring2.0之後新增了對AspectJ切點表達式支持

l @AspectJ AspectJ1.5新增功能,經過JDK5註解技術,容許直接在Bean類中定義切面

新版本Spring框架,建議使用AspectJ方式來開發AOP

主要用途:自定義開發

 

2.2 切入點表達式【掌握】

1.execution()  用於描述方法 【掌握】

語法:execution(修飾符  返回值  包..方法名(參數) throws異常)

修飾符,通常省略

public 公共方法

* 任意

返回值,不能省略

void 返回沒有值

String 返回值字符串

* 任意

包,[省略]

com.itheima.crm 固定包

com.itheima.crm.*.service crm包下面子包任意 (例如:com.itheima.crm.staff.service

com.itheima.crm.. crm包下面的全部子包(含本身)

com.itheima.crm.*.service.. crm包下面任意子包,固定目錄serviceservice目錄任意包

類,[省略]

UserServiceImpl 指定類

*Impl Impl結尾

User* User開頭

* 任意

方法名,不能省略

addUser 固定方法

add* add開頭

*Do Do結尾

* 任意

(參數)

() 無參

(int) 一個整型

(int ,int) 兩個

(..) 參數任意

throws ,可省略,通常不寫。

 

綜合1

execution(* com.itheima.crm.*.service..*.*(..))

綜合2

<aop:pointcut expression="execution(* com.itheima.*WithCommit.*(..)) ||

                          execution(* com.itheima.*Service.*(..))" id="myPointCut"/>

2.within:匹配包或子包中的方法(瞭解)

within(com.itheima.aop..*)

3.this:匹配實現接口的代理對象中的方法(瞭解)

this(com.itheima.aop.user.UserDAO)

4.target:匹配實現接口的目標對象中的方法(瞭解)

target(com.itheima.aop.user.UserDAO)

5.args:匹配參數格式符合標準的方法(瞭解)

args(int,int)

6.bean(id)  對指定的bean全部的方法(瞭解)

bean('userServiceId')

 

2.3 AspectJ 通知類型

l aop聯盟定義通知類型,具備特性接口,必須實現,從而肯定方法名稱。

l aspectj 通知類型,只定義類型名稱。已經方法格式。

個數:6種,知道5種,掌握1中。

before:前置通知(應用:各類校驗)

在方法執行前執行,若是通知拋出異常,阻止方法運行

afterReturning:後置通知(應用:常規數據處理)

方法正常返回後執行,若是方法中拋出異常,通知沒法執行

必須在方法執行後才執行,因此能夠得到方法的返回值。

around:環繞通知(應用:十分強大,能夠作任何事情)

方法執行先後分別執行,能夠阻止方法的執行

必須手動執行目標方法

afterThrowing:拋出異常通知(應用:包裝異常信息)

方法拋出異常後執行,若是方法沒有拋出異常,沒法執行

after:最終通知(應用:清理現場)

方法執行完畢後執行,不管方法中是否出現異常

環繞

 

try{

     //前置:before

    //手動執行目標方法

    //後置:afterRetruning

} catch(){

    //拋出異常 afterThrowing

} finally{

    //最終 after

}

 

 

2.4 導入jar

l 4個:

aop聯盟規範

spring aop 實現

aspect 規範

spring aspect 實現

 

 

2.5 基於xml

1.目標類:接口 + 實現

2.切面類:編寫多個通知,採用aspectj 通知名稱任意(方法名任意)

3.aop編程,將通知應用到目標類

4.測試

 

2.5.1 切面類

/**

 * 切面類,含有多個通知

 */

public class MyAspect {

 

public void myBefore(JoinPoint joinPoint){

System.out.println("前置通知 : " + joinPoint.getSignature().getName());

}

 

public void myAfterReturning(JoinPoint joinPoint,Object ret){

System.out.println("後置通知 : " + joinPoint.getSignature().getName() + " , -->" + ret);

}

 

public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{

System.out.println("");

//手動執行目標方法

Object obj = joinPoint.proceed();

 

System.out.println("");

return obj;

}

 

public void myAfterThrowing(JoinPoint joinPoint,Throwable e){

System.out.println("拋出異常通知 : " + e.getMessage());

}

 

public void myAfter(JoinPoint joinPoint){

System.out.println("最終通知");

}

 

}

 

2.5.2 spring配置

<!-- 1 建立目標類 -->

<bean id="userServiceId" class="com.itheima.d_aspect.a_xml.UserServiceImpl"></bean>

<!-- 2 建立切面類(通知) -->

<bean id="myAspectId" class="com.itheima.d_aspect.a_xml.MyAspect"></bean>

<!-- 3 aop編程

<aop:aspect> 將切面類 聲明切面,從而得到通知(方法)

ref 切面類引用

<aop:pointcut> 聲明一個切入點,全部的通知均可以使用。

expression 切入點表達式

id 名稱,用於其它通知引用

-->

<aop:config>

<aop:aspect ref="myAspectId">

<aop:pointcut expression="execution(* com.itheima.d_aspect.a_xml.UserServiceImpl.*(..))" id="myPointCut"/>

 

<!-- 3.1 前置通知

<aop:before method="" pointcut="" pointcut-ref=""/>

method : 通知,及方法名

pointcut :切入點表達式,此表達式只能當前通知使用。

pointcut-ref : 切入點引用,能夠與其餘通知共享切入點。

通知方法格式:public void myBefore(JoinPoint joinPoint){

參數1org.aspectj.lang.JoinPoint  用於描述鏈接點(目標方法),得到目標方法名等

例如:

<aop:before method="myBefore" pointcut-ref="myPointCut"/>

-->

 

<!-- 3.2後置通知  ,目標方法後執行,得到返回值

<aop:after-returning method="" pointcut-ref="" returning=""/>

returning 通知方法第二個參數的名稱

通知方法格式:public void myAfterReturning(JoinPoint joinPoint,Object ret){

參數1:鏈接點描述

參數2:類型Object,參數名 returning="ret" 配置的

例如:

<aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="ret" />

-->

 

<!-- 3.3 環繞通知

<aop:around method="" pointcut-ref=""/>

通知方法格式:public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{

返回值類型:Object

方法名:任意

參數:org.aspectj.lang.ProceedingJoinPoint

拋出異常

執行目標方法:Object obj = joinPoint.proceed();

例如:

<aop:around method="myAround" pointcut-ref="myPointCut"/>

-->

<!-- 3.4 拋出異常

<aop:after-throwing method="" pointcut-ref="" throwing=""/>

throwing :通知方法的第二個參數名稱

通知方法格式:public void myAfterThrowing(JoinPoint joinPoint,Throwable e){

參數1:鏈接點描述對象

參數2:得到異常信息,類型Throwable ,參數名由throwing="e" 配置

例如:

<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="e"/>

-->

<!-- 3.5 最終通知 -->

<aop:after method="myAfter" pointcut-ref="myPointCut"/>

 

 

 

</aop:aspect>

</aop:config>

 

 

2.6 基於註解

2.6.1 替換bean

<!-- 1 建立目標類 -->

<bean id="userServiceId" class="com.itheima.d_aspect.b_anno.UserServiceImpl"></bean>

<!-- 2 建立切面類(通知) -->

<bean id="myAspectId" class="com.itheima.d_aspect.b_anno.MyAspect"></bean>

 

 

 

注意:掃描

 

<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: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/aop

          http://www.springframework.org/schema/aop/spring-aop.xsd

          http://www.springframework.org/schema/context

          http://www.springframework.org/schema/context/spring-context.xsd">

<!-- 1.掃描 註解類 -->

<context:component-scan base-package="com.itheima.d_aspect.b_anno"></context:component-scan>

 

2.6.2 替換aop

必須進行aspectj 自動代理

<!-- 2.肯定 aop註解生效 -->

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

 

 

聲明切面

 <aop:aspect ref="myAspectId">

 

 

替換前置通知

<aop:before method="myBefore" pointcut="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))"/>

 

//切入點當前有效

@Before("execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))")

public void myBefore(JoinPoint joinPoint){

System.out.println("前置通知 : " + joinPoint.getSignature().getName());

}

 

替換 公共切入點

<aop:pointcut expression="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))" id="myPointCut"/>

 

//聲明公共切入點

@Pointcut("execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))")

private void myPointCut(){

}

 

替換後置

<aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="ret" />

 

@AfterReturning(value="myPointCut()" ,returning="ret")

public void myAfterReturning(JoinPoint joinPoint,Object ret){

System.out.println("後置通知 : " + joinPoint.getSignature().getName() + " , -->" + ret);

}

 

 

替換環繞

<aop:around method="myAround" pointcut-ref="myPointCut"/>

 

@Around(value = "myPointCut()")

public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{

System.out.println("");

//手動執行目標方法

Object obj = joinPoint.proceed();

 

System.out.println("");

return obj;

}

 

替換拋出異常

<aop:after-throwing method="myAfterThrowing" pointcut="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))" throwing="e"/>

 

@AfterThrowing(value="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))" ,throwing="e")

public void myAfterThrowing(JoinPoint joinPoint,Throwable e){

System.out.println("拋出異常通知 : " + e.getMessage());

}

 

2.6.3 切面類

/**

 * 切面類,含有多個通知

 */

@Component

@Aspect

public class MyAspect {

 

//切入點當前有效

// @Before("execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))")

public void myBefore(JoinPoint joinPoint){

System.out.println("前置通知 : " + joinPoint.getSignature().getName());

}

 

//聲明公共切入點

@Pointcut("execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))")

private void myPointCut(){

}

 

// @AfterReturning(value="myPointCut()" ,returning="ret")

public void myAfterReturning(JoinPoint joinPoint,Object ret){

System.out.println("後置通知 : " + joinPoint.getSignature().getName() + " , -->" + ret);

}

 

// @Around(value = "myPointCut()")

public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{

System.out.println("");

//手動執行目標方法

Object obj = joinPoint.proceed();

 

System.out.println("");

return obj;

}

 

// @AfterThrowing(value="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))" ,throwing="e")

public void myAfterThrowing(JoinPoint joinPoint,Throwable e){

System.out.println("拋出異常通知 : " + e.getMessage());

}

 

@After("myPointCut()")

public void myAfter(JoinPoint joinPoint){

System.out.println("最終通知");

}

 

}

 

 

2.6.4 spring配置

<!-- 1.掃描 註解類 -->

<context:component-scan base-package="com.itheima.d_aspect.b_anno"></context:component-scan>

 

<!-- 2.肯定 aop註解生效 -->

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

 

 

2.6.5 aop註解總結

@Aspect  聲明切面,修飾切面類,從而得到 通知。

通知

@Before 前置

@AfterReturning 後置

@Around 環繞

@AfterThrowing 拋出異常

@After 最終

切入點

@PointCut ,修飾方法 private void xxx(){}  以後經過「方法名」得到切入點引用

 

 

 

3 JdbcTemplate

l spring 提供用於操做JDBC工具類,相似:DBUtils

依賴 鏈接池DataSource (數據源)

 

3.1 環境搭建

3.1.1 建立表

create database ee19_spring_day02;

use ee19_spring_day02;

create table t_user(

  id int primary key auto_increment,

  username varchar(50),

  password varchar(32)

);

 

insert into t_user(username,password) values('jack','1234');

insert into t_user(username,password) values('rose','5678');

 

3.1.2 導入jar

 

 

3.1.3 javabean

package com.itheima.domain;

 

public class User {

 

private Integer id;

private String username;

private String password;

 

3.2 使用api(瞭解)

public static void main(String[] args) {

 

//1 建立數據源(鏈接池) dbcp

BasicDataSource dataSource = new BasicDataSource();

// * 基本4

dataSource.setDriverClassName("com.mysql.jdbc.Driver");

dataSource.setUrl("jdbc:mysql://localhost:3306/ee19_spring_day02");

dataSource.setUsername("root");

dataSource.setPassword("1234");

 

 

//2  建立模板

JdbcTemplate jdbcTemplate = new JdbcTemplate();

jdbcTemplate.setDataSource(dataSource);

 

 

//3 經過api操做

jdbcTemplate.update("insert into t_user(username,password) values(?,?);", "tom","998");

 

}

 

 

3.3 配置DBCP

<!-- 建立數據源 -->

<bean id="dataSourceId" class="org.apache.commons.dbcp.BasicDataSource">

<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>

<property name="url" value="jdbc:mysql://localhost:3306/ee19_spring_day02"></property>

<property name="username" value="root"></property>

<property name="password" value="1234"></property>

</bean>

<!-- 建立模板 ,須要注入數據源-->

<bean id="jdbcTemplateId" class="org.springframework.jdbc.core.JdbcTemplate">

<property name="dataSource" ref="dataSourceId"></property>

</bean>

 

<!-- 配置dao -->

<bean id="userDaoId" class="com.itheima.c_dbcp.UserDao">

<property name="jdbcTemplate" ref="jdbcTemplateId"></property>

</bean>

 

3.4 配置C3P0

<!-- 建立數據源 c3p0-->

<bean id="dataSourceId" class="com.mchange.v2.c3p0.ComboPooledDataSource">

<property name="driverClass" value="com.mysql.jdbc.Driver"></property>

<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ee19_spring_day02"></property>

<property name="user" value="root"></property>

<property name="password" value="1234"></property>

</bean>

 

 

 

3.5 使用JdbcDaoSupport

3.5.1 dao

 

 

 

3.5.2 spring配置文件

<!-- 配置dao 

* dao 繼承 JdbcDaoSupport,以後只須要注入數據源,底層將自動建立模板

-->

<bean id="userDaoId" class="com.itheima.e_jdbcdaosupport.UserDao">

<property name="dataSource" ref="dataSourceId"></property>

</bean>

 

3.5.3 源碼分析

 

 

3.6 配置properties

3.6.1 properties文件

jdbc.driverClass=com.mysql.jdbc.Driver

jdbc.jdbcUrl=jdbc:mysql://localhost:3306/ee19_spring_day02

jdbc.user=root

jdbc.password=1234

 

3.6.2 spring配置

<!-- 加載配置文件

"classpath:"前綴表示 src

在配置文件以後經過  ${key} 得到內容

-->

<context:property-placeholder location="classpath:com/itheima/f_properties/jdbcInfo.properties"/>

 

<!-- 建立數據源 c3p0-->

<bean id="dataSourceId" class="com.mchange.v2.c3p0.ComboPooledDataSource">

<property name="driverClass" value="${jdbc.driverClass}"></property>

<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>

<property name="user" value="${jdbc.user}"></property>

<property name="password"  value="${jdbc.password}"></property>

</bean>

相關文章
相關標籤/搜索