天天看点

详解Spring框架入门

目录

  • 一、什么是Spring 
  • 二、什么是IOC
  • 三、快速搭建框架环境
  • 四、spring之依赖注入
  • 五、详解Spring框架的IOC之注解方式
  • 七、Spring之JDBC
  • 八、Spring之事务
  • 九、Spring框架的事务管理之编程式的事务管理
  • 十、Spring框架的事务管理之声明式事务管理,即通过配置文件来完成事务管理(AOP思想)

一、什么是Spring 

Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。 

 ◆目的:解决企业应用开发的复杂性

 ◆功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能

 ◆范围:任何Java应用

二、什么是IOC

控制反转(Inversion of Control,英文缩写为IoC)把创建对象的权利交给框架,是框架的重要特征,并非面向对象编程的专用术语。它包括依赖注入和依赖查找。传统的业务层,当需要资源时就在该业务层new资源,这样耦合性(程序之间相互依赖关联)较高。现在将new的部分交给spring,做到高内聚低耦合。简而言之:原先是每当调用dao层或service层方法时,由app来new,现在是将new的权利交给spring,要什么资源从spring中获取!

三、快速搭建框架环境

1.下载框架所需的依赖jar包

 spring官网为:http://spring.io/

下载jar包:   http://repo.springsource.org/libs-release-local/org/springframework/spring

2.导入基本jar包

详解Spring框架入门

其实基本核心jar有beans;context;core;expression包,其他是依赖log4j日志。当然spring的jar不止这些,后期慢慢加上。

3.配置log4j配置文件

日志文件定义在src目录下

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

### direct log messages to stdout ###

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.Target=System.err

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###

log4j.appender.file=org.apache.log4j.FileAppender

log4j.appender.file.File=c\:mylog.log

log4j.appender.file.layout=org.apache.log4j.PatternLayout

log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=info, stdout

4.测试日志文件是否部署成功

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

package

com.clj.demo1;

import

org.apache.log4j.Logger;

import

org.junit.Test;

public

class

Demo1 {

//创建日志类

private

Logger log=Logger.getLogger(Demo1.

class

);

@Test

public

void

run1(){

//可以将log4j.rootLogger属性中的info改为off则不会再控制台显示

log.info(

"执行了"

);

}

}

5.定义一个接口和实现类

接口:

?

1

2

3

4

5

package

com.clj.demo2;

public

interface

UserService {

public

void

sayHello();

}

实现类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

package

com.clj.demo2;

public

class

UserServiceImpl

implements

UserService{

private

String name;

public

String getName() {

return

name;

}

public

void

setName(String name) {

this

.name = name;

}

public

void

init(){

System.out.println(

"初始化。。"

);

}

public

void

sayHello() {

System.out.println(

"Hello Spring"

+

"\t"

+name);

}

public

void

destory(){

System.out.println(

"销毁。。"

);

}

}

6.定义spring专属的配置文件

定义名为applicationContext.xml,位置为src下,与日志文件同目录,导入相对应的约束,并将实现类注入到配置文件中,刚开始入门,使用bean约束

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<?

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:p

=

"http://www.springframework.org/schema/p"

xsi:schemaLocation="

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

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

<!-- 使用bean标签

1.id值唯一(必写)

2.注意:class为实现类路径,不是接口(必写)

3.init-method核心方法执行之前初始化工作(选写)

4.destroy-method核心方法执行之后初始化工作(选写)-->

<

bean

id

=

"userService"

class

=

"com.clj.demo2.UserServiceImpl"

init-method

=

"init"

destroy-method

=

"destory"

>

<

property

name

=

"name"

value

=

"佳先森"

></

property

>

</

bean

>

</

beans

>

7.测试

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

public

class

Demo1 {

@Test

public

void

run(){

//创建实现类

UserServiceImpl s=

new

UserServiceImpl();

s.setName(

"佳先森"

);

s.sayHello();

}

@Test

public

void

run2(){

BeanFactory factory=

new

XmlBeanFactory(

new

ClassPathResource(

"applicationContext.xml"

));

UserService us=(UserService)factory.getBean(

"userService"

);

us.sayHello();

}

@Test

public

void

run3(){

//创建工厂,加载核心配置文件(ClassPathXmlApplicationContext从src下找)

ApplicationContext ac=

new

ClassPathXmlApplicationContext(

"applicationContext.xml"

);

//从工厂中获取到对象(配置文件中的id值,这里用了多态)

UserService usi=(UserService) ac.getBean(

"userService"

);

//调用对象的方法执行

usi.sayHello();

}

@Test

public

void

run4(){

//创建工厂,加载核心配置文件(ClassPathXmlApplicationContext从src下找)

ClassPathXmlApplicationContext ac=

new

ClassPathXmlApplicationContext(

"applicationContext.xml"

);

//从工厂中获取到对象(配置文件中的id值,这里用了多态)

UserService usi=(UserService) ac.getBean(

"userService"

);

//调用对象的方法执行

usi.sayHello();

//ApplicationContext实现类提供close方法,将工厂关闭就可执行destory-method方法

ac.close();

}

}

其中旧工厂与新工厂的区别

* BeanFactory和ApplicationContext的区别

* BeanFactory               -- BeanFactory采取延迟加载,第一次getBean时才会初始化Bean

* ApplicationContext      -- 在加载applicationContext.xml时候就会创建具体的Bean对象的实例,还提供了一些其他的功能

 * 事件传递

 * Bean自动装配

* 各种不同应用层的Context实现

总结:这是个最基本的demo,是将实现类配置到了spring配置文件中,每次启动服务器时,就会加载配置文件,从而实例化了实现类

四、spring之依赖注入

1、什么是依赖注入?

Spring 能有效地组织J2EE应用各层的对象。不管是控制层的Action对象,还是业务层的Service对象,还是持久层的DAO对象,都可在Spring的 管理下有机地协调、运行。Spring将各层的对象以松耦合的方式组织在一起,Action对象无须关心Service对象的具体实现,Service对 象无须关心持久层对象的具体实现,各层对象的调用完全面向接口。当系统需要重构时,代码的改写量将大大减少。依赖注入让bean与bean之间以配置文件组织在一起,而不是以硬编码的方式耦合在一起。理解依赖注入

依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念。具体含义是:当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在 传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者 实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。

不管是依赖注入,还是控制反转,都说明Spring采用动态、灵活的方式来管理各种对象。对象与对象之间的具体实现互相透明。  

2. IOC和DI的概念

* IOC -- Inverse of Control,控制反转,将对象的创建权反转给Spring!!

* DI -- Dependency Injection,依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件中!!

3.演示

对于类成员变量,常用的注入方式有两种

属性set方法注入和构造方法注入

先演示第一种:属性set方法注入

1)持久层

?

1

2

3

4

5

6

7

package

com.clj.demo3;

public

class

CustomerDaoImpl {

public

void

save(){

System.out.println(

"我是持久层的Dao"

);

}

}

2)业务层

注意:此时是想将持久层注入到业务层,将创建持久层实例权利交给框架,条件是业务层必须提供持久层的成员属性和set方法

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

package

com.clj.demo3;

public

class

CustomerServiceImpl{

//提供成员属相,提供set方法

private

CustomerDaoImpl customerDao;

public

void

setCustomerDao(CustomerDaoImpl customerDao) {

this

.customerDao = customerDao;

}

public

void

save(){

System.out.println(

"我是业务层的service..."

);

//1.原始方式

//new CustomerDaoImpl().save();

//2.spring 之IOC方式

customerDao.save();

}

}

 3)配置文件配置

?

1

2

3

4

5

6

<!-- 演示依赖注入 -->

<

bean

id

=

"customerDao"

class

=

"com.clj.demo3.CustomerDaoImpl"

/>

<

bean

id

=

"customerService"

class

=

"com.clj.demo3.CustomerServiceImpl"

>

<!-- 将Dao注入到service层 -->

<

property

name

=

"customerDao"

ref

=

"customerDao"

></

property

>

</

bean

>

4)测试

?

1

2

3

4

5

6

7

8

9

10

11

@Test

public

void

run2(){

//创建工厂,加载配置文件,customerService被创建,从而也创建了customerDao

ApplicationContext context=

new

ClassPathXmlApplicationContext(

"applicationContext.xml"

);

CustomerServiceImpl csi=(CustomerServiceImpl) context.getBean(

"customerService"

);

csi.save();

}

第二种:构造方法注入

1)pojo类并提供构造方法

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

package

com.clj.demo4;

public

class

Car1 {

private

String cname;

private

Double price;

public

Car1(String cname, Double price) {

super

();

this

.cname = cname;

this

.price = price;

}

@Override

public

String toString() {

return

"Car1 [cname="

+ cname +

", price="

+ price +

"]"

;

}

}

2)配置文件配置

?

1

2

3

4

5

6

7

8

<!-- 演示构造方法注入方式 -->

<

bean

id

=

"car1"

class

=

"com.clj.demo4.Car1"

>

<!-- 写法一<constructor-arg name="cname" value="宝马"/>

<constructor-arg name="price" value="400000"/> -->

<!--写法二 -->

<

constructor-arg

index

=

"0"

value

=

"宝马"

/>

<

constructor-arg

index

=

"1"

value

=

"400000"

/>

</

bean

>

3)测试

?

1

2

3

4

5

6

@Test

public

void

run1(){

ApplicationContext ac=

new

ClassPathXmlApplicationContext(

"applicationContext.xml"

);

Car1 car=(Car1) ac.getBean(

"car1"

);

System.out.println(car);

}

拓展:构造方法之将一个对象注入到另一个对象中

1)pojo类:目的:将上列中的车注入到人类,使之成为其中一个属性,则必须在此类中提供车的成员属性,并提供有参构造方法

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

package

com.clj.demo4;

public

class

Person {

private

String name;

private

Car1 car1;

public

Person(String name, Car1 car1) {

super

();

this

.name = name;

this

.car1 = car1;

}

@Override

public

String toString() {

return

"Person [name="

+ name +

", car1="

+ car1 +

"]"

;

}

}

2)配置文件

?

1

2

3

4

5

<!-- 构造方法之将一个对象注入到另一个对象-->

<

bean

id

=

"person"

class

=

"com.clj.demo4.Person"

>

<

constructor-arg

name

=

"name"

value

=

"佳先森"

/>

<

constructor-arg

name

=

"car1"

ref

=

"car1"

/>

</

bean

>

4.如何注入集合数组

1)定义pojo类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

package

com.clj.demo4;

import

java.util.Arrays;

import

java.util.List;

import

java.util.Map;

import

java.util.Properties;

import

java.util.Set;

public

class

User {

private

String[] arrs;

private

List<String> list;

private

Set<String> sets;

private

Map<String,String> map;

private

Properties pro;

public

void

setPro(Properties pro) {

this

.pro = pro;

}

public

void

setSets(Set<String> sets) {

this

.sets = sets;

}

public

void

setMap(Map<String, String> map) {

this

.map = map;

}

public

void

setList(List<String> list) {

this

.list = list;

}

public

void

setArrs(String[] arrs) {

this

.arrs = arrs;

}

@Override

public

String toString() {

return

"User [arrs="

+ Arrays.toString(arrs) +

", list="

+ list

+

", sets="

+ sets +

", map="

+ map +

", pro="

+ pro +

"]"

;

}

}

2)配置文件

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

<!-- 注入集合 -->

<

bean

id

=

"user"

class

=

"com.clj.demo4.User"

>

<!-- 数组 -->

<

property

name

=

"arrs"

>

<

list

>

<

value

>数字1</

value

>

<

value

>数字2</

value

>

<

value

>数字3</

value

>

</

list

>

</

property

>

<!-- list集合 -->

<

property

name

=

"list"

>

<

list

>

<

value

>金在中</

value

>

<

value

>王杰</

value

>

</

list

>

</

property

>

<!-- set集合 -->

<

property

name

=

"sets"

>

<

set

>

<

value

>哈哈</

value

>

<

value

>呵呵</

value

>

</

set

>

</

property

>

<!-- map集合 -->

<

property

name

=

"map"

>

<

map

>

<

entry

key

=

"aa"

value

=

"rainbow"

/>

<

entry

key

=

"bb"

value

=

"hellowvenus"

/>

</

map

>

</

property

>

<!-- 属性文件 -->

<

property

name

=

"pro"

>

<

props

>

<

prop

key

=

"username"

>root</

prop

>

<

prop

key

=

"password"

>123</

prop

>

</

props

>

</

property

>

</

bean

>

3)测试

?

1

2

3

4

5

6

7

8

9

@Test

public

void

run3(){

ApplicationContext ac=

new

ClassPathXmlApplicationContext(

"applicationContext.xml"

);

User user= (User) ac.getBean(

"user"

);

System.out.println(user);

}

5.怎么分模块开发

在主配置文件加入<import>标签(假如此时在com.clj.test包下定义了一个配置文件applicationContext2.xml)

?

1

2

<!-- 分模块开发之引入其他配置文件 -->

<

import

resource

=

"com/clj/test/applicationContext2.xml"

/>

五、详解Spring框架的IOC之注解方式

1、入门

1).导入jar包

除了先前6个包,玩注解还需一个spring-aop包

详解Spring框架入门

  

2).持久层和实现层(这里忽略接口)

持久层

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

package

com.clj.demo1;

import

org.springframework.context.annotation.Scope;

import

org.springframework.stereotype.Component;

import

org.springframework.stereotype.Repository;

public

class

UserDaoImpl

implements

UserDao{

@Override

public

void

save() {

System.out.println(

"保存客户。。"

);

}

}

业务层

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

package

com.clj.demo1;

import

javax.annotation.PostConstruct;

import

org.springframework.beans.factory.annotation.Autowired;

import

org.springframework.beans.factory.annotation.Qualifier;

import

org.springframework.beans.factory.annotation.Value;

import

org.springframework.stereotype.Component;

public

class

UserServiceImpl

implements

UserService{

@Override

public

void

sayHello() {

System.out.println(

"Hello spring"

);

}

}

3).定义配置文件

此时约束条件需添加context约束,并添加组件扫描

?

1

2

3

4

5

6

7

8

9

<?

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"

xsi:schemaLocation="

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

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

<!-- bean definitions here -->

<!-- 开启注解扫面 :base-package指定扫面对 包-->

<

context:component-scan

base-package

=

"com.clj.demo1"

/>

</

beans

>

4)在实现类中添加注解

?

1

2

3

4

5

6

7

8

9

@Component

(value=

"userService"

)

public

class

UserServiceImpl

implements

UserService{

//省略

}

5)编写测试

?

1

2

3

4

5

6

7

8

9

@Test

public

void

run2(){

ApplicationContext ac=

new

ClassPathXmlApplicationContext(

"applicationContext.xml"

);

UserService us=(UserService) ac.getBean(

"userService"

);

us.sayHello();

}

2.关于bean管理常用属性

1. @Component:组件.(作用在类上)  最原始的注解,所有需要注解的类都写这个没问题,他是通用的

2. Spring中提供@Component的三个衍生注解:(功能目前来讲是一致的)

    * @Controller       -- 作用在WEB层

    * @Service          -- 作用在业务层

    * @Repository       -- 作用在持久层

    * 说明:这三个注解是为了让标注类本身的用途清晰,Spring在后续版本会对其增强

3. 属性注入的注解(说明:使用注解注入的方式,可以不用提供set方法)

    * 如果是注入的普通类型,可以使用value注解

    * @Value             -- 用于注入普通类型

    * 如果注入的是对象类型,使用如下注解

        * @Autowired        -- 默认按类型进行自动装配   匹配的是类型,与注入类的类名无关

            * 如果想按名称注入

            * @Qualifier    -- 强制使用名称注入            必须与Autowired一起用,指定类名,与注入的类名有关

        * @Resource         -- 相当于@Autowired和@Qualifier一起使用

        * 强调:Java提供的注解

        * 属性使用name属性

4. Bean的作用范围注解

    * 注解为@Scope(value="prototype"),作用在类上。值如下:

        * singleton     -- 单例,默认值

        * prototype     -- 多例

5. Bean的生命周期的配置(了解)

    * 注解如下:

        * @PostConstruct    -- 相当于init-method

        * @PreDestroy       -- 相当于destroy-method

1.演示属性对象注解

条件:采用扫描的方式将属性(name)和对象(userDaoImpl)注入到业务层中

1)持久层开启注解扫描Repository

?

1

2

3

4

5

6

7

8

//@Component(value="userDao")通用类注解

@Repository

(value=

"ud"

)

public

class

UserDaoImpl

implements

UserDao{

@Override

public

void

save() {

System.out.println(

"保存客户。。"

); 

}

}

2)业务层针对属性和对象提供注解

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

package

com.clj.demo1;

import

javax.annotation.PostConstruct;

import

org.springframework.beans.factory.annotation.Autowired;

import

org.springframework.beans.factory.annotation.Qualifier;

import

org.springframework.beans.factory.annotation.Value;

import

org.springframework.stereotype.Component;

//@Scope(value="grototype")多列的(singletype为单列)

@Component

(value=

"userService"

)

public

class

UserServiceImpl

implements

UserService{

//属性注解:相当于给name属性注入指定的字符串,setName方法可以省略不写

@Value

(value=

"佳先森"

)

private

String name;

//Autowired()按类型自动装配注入(缺点:因为是按类型匹配,所以不是很准确)

@Autowired

()

@Qualifier

(value=

"ud"

)

//按名称注入,得与Autowired一起用,两者一起能指定类

private

UserDao userDao;

//注意Qualifier中的value是指定UserDaoImpl类名顶上的注解名,也可以指定配置文件中bean的id名

@Override

public

void

sayHello() {

System.out.println(

"Hello spring"

+name);

userDao.save();

}

//@PostConstruct标签用于action生命周期中初始化的注解

@PostConstruct

public

void

init(){

System.out.println(

"初始化..."

);

}

}

3)配置文件只需要开启全部扫描即可

?

1

2

3

4

5

6

7

8

9

<?

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"

xsi:schemaLocation="

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

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

<!-- bean definitions here -->

<!-- 开启注解扫面 :base-package指定扫面对 包-->

<

context:component-scan

base-package

=

"com.clj.demo1"

/>

</

beans

>

注意:至于集合还是推荐使用配置文件方式

2.Spring框架整合JUnit单元测试

1)添加单元测试所需依赖包spring-test.jar

详解Spring框架入门

  

注意:基于myeclipes自带Junit环境,但是有时因为版本问题,可能需要比较新的Junit环境,这里我在网上下了一个教新的 Junit-4.9的jar包,如果myeclipes较新的话无须考虑

2)编写测试类,添加相对应的注解

@RunWith与@ContextConfiguration(此是用于加载配置文件,因为默认从WebRoot路径为一级目录,加上此是认定src为一级目录)

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

package

com.clj.demo2;

import

javax.annotation.Resource;

import

org.junit.Test;

import

org.junit.runner.RunWith;

import

org.springframework.test.context.ContextConfiguration;

import

org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import

com.clj.demo1.UserService;

@RunWith

(SpringJUnit4ClassRunner.

class

)

@ContextConfiguration

(

"classpath:applicationContext.xml"

)

public

class

Demo2 {

@Resource

(name=

"userService"

)

private

UserService userService;

@Test

public

void

run1(){

userService.sayHello();

}

}

六.spring框架之AOP

1.什么是AOP

        * 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,功能模块化

        * AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构

        * AOP最早由AOP联盟的组织提出的,制定了一套规范.Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范

        * 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术

        * AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型

        * 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率

      AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)

2. 为什么要学习AOP

        * 可以在不修改源代码的前提下,对程序进行增强!!(为固定的方法生成一个代理,在访问该方法之前,先进入代理,在代理中,可以编写更多的功能,使之方法的功能更强,使得程序进行增        强)

Aop:面向切面编程,将一切事模块化,每个模块比较独立,模块可以共用(相同的),不同的格外自定义。用此替代传统的面向纵向编程,提高程序的可重用性

3.AOP的实现(实现原理)

Aop的实现包含两种代理方式<1>实现类接口:采用JDK动态代理<2>未实现类接口:采用CGLIB动态代理

   1.实现JDK动态代理

      1)定义持久层接口实现类

?

1

2

3

4

5

6

package

com.clj.demo3;

public

interface

UserDao {

public

void

save();

public

void

update();

}

?

1

2

3

4

5

6

7

8

9

10

11

12

13

package

com.clj.demo3;

public

class

UserDaoImpl

implements

UserDao {

@Override

public

void

save() {

System.out.println(

"保存用户"

);

}

@Override

public

void

update() {

System.out.println(

"修改用户"

);

}

}

   2)定义JDK动态代理工具类

此工具类是在执行持久层save方法时增加一些功能,在开发中做到在不更改源码情况下增强某方法

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

package

com.clj.demo3;

import

java.lang.reflect.InvocationHandler;

import

java.lang.reflect.Method;

import

java.lang.reflect.Proxy;

public

class

MyProxyUtils {

public

static

UserDao getProxy(

final

UserDao dao){

//使用Proxy类生成代理对象

UserDao proxy=(UserDao)Proxy.newProxyInstance(dao.getClass().getClassLoader() , dao.getClass().getInterfaces(),

new

InvocationHandler() {

//只要代理对象一执行,invoke方法就会执行一次

public

Object invoke(Object proxy, Method method, Object[] args)

throws

Throwable {

//proxy代表当前代理对象

//method当前对象执行的方法

//args封装的参数

//让到类的save或者update方法正常执行下去

if

(

"save"

.equals(method.getName())){

System.out.println(

"执行了保存"

);

//开启事务

}

return

method.invoke(dao, args);

}

});

return

proxy;

}

}

 3)测试

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

package

com.clj.demo3;

import

org.junit.Test;

public

class

Demo1 {

@Test

public

void

run1(){

//获取目标对象

UserDao dao=

new

UserDaoImpl();

dao.save();

dao.update();

System.out.println(

"==============="

);

//使用工具类,获取到代理对象

UserDao proxy=MyProxyUtils.getProxy(dao);

//调用代理对象的方法

proxy.save();

proxy.update();

}

}

 2.实现CGLIB技术

 1)定义持久层,此时没有接口

?

1

2

3

4

5

6

7

8

9

10

package

com.clj.demo4;

public

class

BookDaoImpl {

public

void

save(){

System.out.println(

"保存图书"

);

}

public

void

update(){

System.out.println(

"修改图书"

);

}

}

  2)编写工具类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

package

com.clj.demo4;

import

java.lang.reflect.Method;

import

org.springframework.cglib.proxy.Enhancer;

import

org.springframework.cglib.proxy.MethodInterceptor;

import

org.springframework.cglib.proxy.MethodProxy;

public

class

MyCglibUtils {

public

static

BookDaoImpl getProxy(){

Enhancer enhancer=

new

Enhancer();

//设置父类

enhancer.setSuperclass(BookDaoImpl.

class

);

//设置回调函数

enhancer.setCallback(

new

MethodInterceptor() {

@Override

public

Object intercept(Object obj, Method method, Object[] objs,

MethodProxy methodProxy)

throws

Throwable {

if

(method.getName().equals(

"save"

)){

System.out.println(

"我保存了"

);

System.out.println(

"代理对象执行了"

);

}

return

methodProxy.invokeSuper(obj, objs);

//是方法执行下去

}

});

//生成代理对象

BookDaoImpl proxy=(BookDaoImpl) enhancer.create();

return

proxy;

}

}

  3)编写测试类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

package

com.clj.demo4;

import

org.junit.Test;

public

class

Demo1 {

@Test

public

void

run1(){

//目标对象

BookDaoImpl dao=

new

BookDaoImpl();

dao.save();

dao.update();

System.out.println(

"=========="

);

BookDaoImpl proxy=MyCglibUtils.getProxy();

proxy.save();

proxy.update();

}

}

 3、Spring基于AspectJ的AOP的开发(配置文件方式)

详解Spring框架入门

  

  1)部署环境,导入相对应的jar包

详解Spring框架入门

  

 2)创建配置文件,并引入AOP约束

?

1

2

3

4

5

6

<

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">

 3)创建接口和实现类

?

1

2

3

4

5

6

package

com.clj.demo5;

public

interface

CustomerDao {

public

void

save();

public

void

update();

}

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

package

com.clj.demo5;

public

class

CustomerDaoImpl

implements

CustomerDao {

@Override

public

void

save() {

//模拟异常

//int a=10/0;

System.out.println(

"保存客户了啊"

);

}

@Override

public

void

update() {

// TODO Auto-generated method stub

System.out.println(

"更新客户了啊"

);

}

}

 4)定义切面类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

package

com.clj.demo5;

import

org.aspectj.lang.ProceedingJoinPoint;

public

class

MyAspectXml {

public

void

log(){

System.out.println(

"记录日志"

);

}

public

void

after(){

System.out.println(

"最终通知"

);

}

public

void

afterReturn(){

System.out.println(

"后置通知"

);

}

public

void

afterThrowing(){

System.out.println(

"异常通知"

);

}

public

void

around(ProceedingJoinPoint joinPoint){

System.out.println(

"环绕通知1"

);

//手动让目标对象的方法执行

try

{

joinPoint.proceed();

}

catch

(Throwable e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(

"环绕通知2"

);

}

}

 5)注入实现类和切面类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

<?

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">

<!-- bean definitions here -->

<!-- 配置客户的dao -->

<

bean

id

=

"customerDao"

class

=

"com.clj.demo5.CustomerDaoImpl"

/>

<!-- 编写切面类配置好 -->

<

bean

id

=

"myAspectXml"

class

=

"com.clj.demo5.MyAspectXml"

/>

<!-- 配置AOP -->

<

aop:config

>

<!-- 配置切面类:切入点+通知 (类型)-->

<

aop:aspect

ref

=

"myAspectXml"

>

<!-- 配置前置通知,save方法执行之前,增强方法会执行 -->

<!-- 切入点表达式:execution(public void com.clj.demo5.CustomerDaoImpl.save()) -->

<!-- 切入点表达式:

1.execution()固定的,必写

2.public可以省略不写

3.返回值   必写,严格根据切入点方法而定,否则增强方法不会执行,可以用*代替,表示任意的返回值

4.包名   必写,可以用*代替(如:*..*(默认所有包); com.clj.*)

5.类名   必写,可以部分用*(如*DaoImpl表示以'DaoImpl'结尾的持久层实现类),但不建议用*代替整个类名

6.方法   必写,可以部分用*(如save*表示以'save'开头的方法),但不建议用*代替整个类名

7.方法参数 根据实际方法而定,可以用'..'表示有0或者多个参数

-->

<!-- <aop:before method="log" pointcut="execution(public void com.clj.*.CustomerDaoImpl.save(..))"/> -->

<

aop:before

method

=

"log"

pointcut

=

"execution(* *..*.*DaoImpl.save*(..))"

/>

</

aop:aspect

>

</

aop:config

>

</

beans

>

 6)测试

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

package

com.clj.demo5;

import

javax.annotation.Resource;

import

org.junit.Test;

import

org.junit.runner.RunWith;

import

org.springframework.test.context.ContextConfiguration;

import

org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith

(SpringJUnit4ClassRunner.

class

)

@ContextConfiguration

(

"classpath:applicationContext.xml"

)

public

class

Demo1 {

@Resource

(name=

"customerDao"

)

private

CustomerDao customerDao;

@Test

public

void

run(){

customerDao.save();

customerDao.update();

}

}

扩展:切面类升级

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<?

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">

<!-- bean definitions here -->

<

bean

id

=

"myAspectXml"

class

=

"com.clj.demo5.MyAspectXml"

/>

<

aop:config

>

<

aop:aspect

ref

=

"myAspectXml"

>

<!-- 配置最终通知

<aop:after method="after" pointcut="execution(* *..*.*DaoImpl.save*(..))"/>-->

<!-- 配置后置通知

<aop:after-returning method="afterReturn" pointcut="execution(* *..*.*DaoImpl.save*(..))"/>-->

<!-- 配置异常通知

<aop:after-throwing method="afterThrowing" pointcut="execution(* *..*.*DaoImpl.save*(..))"/>-->

<

aop:around

method

=

"around"

pointcut

=

"execution(* *..*.*DaoImpl.update*(..))"

/>

</

aop:aspect

>

</

aop:config

>

</

beans

>

4、Spring框架AOP之注解方式

 1)创建接口和实现类

?

1

2

3

4

5

6

package

com.clj.demo1;

public

interface

CustomerDao {

public

void

save();

public

void

update();

}

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

package

com.clj.demo1;

public

class

CustomerDaoImpl

implements

CustomerDao{

@Override

public

void

save() {

// TODO Auto-generated method stub

System.out.println(

"保存客户.."

);

}

@Override

public

void

update() {

// TODO Auto-generated method stub

System.out.println(

"更新客户"

);

}

}

2)定义切面类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

package

com.clj.demo1;

import

org.aspectj.lang.ProceedingJoinPoint;

import

org.aspectj.lang.annotation.After;

import

org.aspectj.lang.annotation.Around;

import

org.aspectj.lang.annotation.Aspect;

import

org.aspectj.lang.annotation.Before;

import

org.aspectj.lang.annotation.Pointcut;

@Aspect

public

class

MyAspectAnno {

//通知类型:@Before前置通知(切入点的表达式)

@Before

(value=

"execution(public *   com.clj.demo1.CustomerDaoImpl.save())"

)

public

void

log(){

System.out.println(

"记录日志。。"

);

}

//引入切入点

@After

(value=

"MyAspectAnno.fun()"

)

public

void

after(){

System.out.println(

"执行之后"

);

}

@Around

(value=

"MyAspectAnno.fun()"

)

public

void

around(ProceedingJoinPoint joinPoint){

System.out.println(

"环绕通知1"

);

try

{

//让目标对象执行

joinPoint.proceed();

}

catch

(Throwable e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(

"环绕通知2"

);

}

//自定义切入点

@Pointcut

(value=

"execution(public *   com.clj.demo1.CustomerDaoImpl.save())"

)

public

void

fun(){

}

}

3)配置切面类和实现类,并开启自动代理

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

<?

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

=

"http://www.springframework.org/schema/aop"

xmlns:tx

=

"http://www.springframework.org/schema/tx"

xsi:schemaLocation="http://www.springframework.org/schema/beans

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

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

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

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

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

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

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

<!-- 开启自动注解代理-->

<

aop:aspectj-autoproxy

/>

<!-- 配置目标对象 -->

<

bean

id

=

"customerDao"

class

=

"com.clj.demo1.CustomerDaoImpl"

/>

<!-- 配置切面类 -->

<

bean

id

=

"myAspectAnno"

class

=

"com.clj.demo1.MyAspectAnno"

/>

</

beans

>

七、Spring之JDBC

spring提供了JDBC模板:JdbcTemplate类

1.快速搭建

 1)部署环境

这里在原有的jar包基础上,还要添加关乎jdbc的jar包,这里使用的是mysql驱动

详解Spring框架入门

  

 2)配置内置连接池,将连接数据库程序交给框架管理,并配置Jdbc模板类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

<?

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

=

"http://www.springframework.org/schema/aop"

xmlns:tx

=

"http://www.springframework.org/schema/tx"

xsi:schemaLocation="http://www.springframework.org/schema/beans

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

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

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

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

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

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

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

<!-- 先配置连接池(内置) -->

<

bean

id

=

"dataSource"

class

=

"org.springframework.jdbc.datasource.DriverManagerDataSource"

>

<

property

name

=

"driverClassName"

value

=

"com.mysql.jdbc.Driver"

/>

<

property

name

=

"url"

value

=

"jdbc:mysql://192.168.174.130:3306/SSH"

/>

<

property

name

=

"username"

value

=

"root"

/>

<

property

name

=

"password"

value

=

"root"

/>

</

bean

>

<!-- 配置JDBC的模板类-->

<

bean

id

=

"jdbcTemplate"

class

=

"org.springframework.jdbc.core.JdbcTemplate"

>

<

property

name

=

"dataSource"

ref

=

"dataSource"

/>

</

bean

>

</

beans

>

 3)测试

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

package

com.clj.demo2;

import

java.sql.ResultSet;

import

java.sql.SQLException;

import

java.util.List;

import

javax.annotation.Resource;

import

org.apache.commons.dbcp.BasicDataSource;

import

org.junit.Test;

import

org.junit.runner.RunWith;

import

org.springframework.cglib.beans.BeanMap;

import

org.springframework.jdbc.core.JdbcTemplate;

import

org.springframework.jdbc.core.RowMapper;

import

org.springframework.test.context.ContextConfiguration;

import

org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith

(SpringJUnit4ClassRunner.

class

)

@ContextConfiguration

(

"classpath:applicationContext.xml"

)

public

class

Demo2 {

@Resource

(name=

"jdbcTemplate"

)

private

JdbcTemplate jdbcTemplate;

@Test

public

void

run1(){

String sql=

"insert into t_account values(null,?,?)"

;

jdbcTemplate.update(sql,

"李钇林"

,

10000

);

}

@Test

public

void

run2(){

String sql=

"update t_account set name=? where id=?"

;

jdbcTemplate.update(sql,

"李钇林"

,

1

);

}

@Test

public

void

run3(){

String sql=

"delete from t_account where id=?"

;

jdbcTemplate.update(sql,

4

);

}

@Test

public

void

run4(){

String sql=

"select * from t_account where id=?"

;

Account ac=jdbcTemplate.queryForObject(sql,

new

BeanMapper(),

1

);

System.out.println(ac);

}

@Test

public

void

run5(){

String sql=

"select * from t_account"

;

List<Account> ac=jdbcTemplate.query(sql,

new

BeanMapper());

System.out.println(ac);

}

}

class

BeanMapper

implements

RowMapper<Account>{

@Override

public

Account mapRow(ResultSet rs,

int

rowNum)

throws

SQLException {

Account ac=

new

Account();

ac.setId(rs.getInt(

"id"

));

ac.setName(rs.getString(

"name"

));

ac.setMoney(rs.getDouble(

"money"

));

return

ac;

}

}

2、配置开源连接池

一般现在企业都是用一些主流的连接池,如c3p0和dbcp

首先配置dbcp

1)导入dbcp依赖jar包

详解Spring框架入门

  

2)编写配置文件

?

1

2

3

4

5

6

7

<!-- 配置DBCP开源连接池-->

<

bean

id

=

"dataSource"

class

=

"org.apache.commons.dbcp.BasicDataSource"

>

<

property

name

=

"driverClassName"

value

=

"com.mysql.jdbc.Driver"

/>

<

property

name

=

"url"

value

=

"jdbc:mysql://192.168.174.130:3306/SSH"

/>

<

property

name

=

"username"

value

=

"root"

/>

<

property

name

=

"password"

value

=

"root"

/>

</

bean

>

将模板类中引入的内置类datasource改为开源连接池的

3)编写测试类

配置c3p0

 1)导入c3p0依赖jar包

详解Spring框架入门

  

2)配置c3p0

?

1

2

3

4

5

6

7

<!-- 配置C3P0开源连接池 -->

<

bean

id

=

"dataSource"

class

=

"com.mchange.v2.c3p0.ComboPooledDataSource"

>

<

property

name

=

"driverClass"

value

=

"com.mysql.jdbc.Driver"

/>

<

property

name

=

"jdbcUrl"

value

=

"jdbc:mysql://192.168.174.130:3306/SSH"

/>

<

property

name

=

"user"

value

=

"root"

/>

<

property

name

=

"password"

value

=

"root"

/>

</

bean

>

将模板类中引入的内置类datasource改为开源连接池的

3)编写测试类

八、Spring之事务

1、什么是事务

数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。

2、怎么解决事务安全性问题

读问题解决,设置数据库隔离级别;写问题解决可以使用 悲观锁和乐观锁的方式解决

3、快速开发

方式一:调用模板类,将模板注入持久层

1)编写相对应的持久层和也外层,这里省略接口   

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

package

com.clj.demo3;

import

org.springframework.jdbc.core.JdbcTemplate;

import

org.springframework.jdbc.core.support.JdbcDaoSupport;

public

class

AccountDaoImpl

extends

JdbcDaoSupport

implements

AccountDao{

// 方式一:将jdbc模板类注入到配置文件中,直接在持久层写模板类

private

JdbcTemplate jdbcTemplate;

public

void

setJdbcTemplate(JdbcTemplate jdbcTemplate) {

this

.jdbcTemplate = jdbcTemplate;

}

public

void

outMoney(String out,

double

money) {

String sql=

"update t_account set money=money-? where name=?"

;

jdbcTemplate().update(sql,money,out);

}

public

void

inMoney(String in,

double

money) {

String sql=

"update t_account set money=money+? where name=?"

;

jdbcTemplate().update(sql,money,in);

}

}

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

package

com.clj.demo4;

import

org.springframework.transaction.TransactionStatus;

import

org.springframework.transaction.support.TransactionCallbackWithoutResult;

import

org.springframework.transaction.support.TransactionTemplate;

public

class

AccountServiceImpl

implements

AccountService{

//采用的是配置文件注入方式,必须提供set方法

private

AccountDao accountDao;

public

void

setAccountDao(AccountDao accountDao) {

this

.accountDao = accountDao;

}

@Override

public

void

pay(String out, String in,

double

money) {

// TODO Auto-generated method stub

accountDao.outMoney(out, money);

int

a=

10

/

;

accountDao.inMoney(in, money);

}

}

2)配置相对应的配置文件

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

<?

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

=

"http://www.springframework.org/schema/aop"

xmlns:tx

=

"http://www.springframework.org/schema/tx"

xsi:schemaLocation="http://www.springframework.org/schema/beans

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

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

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

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

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

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

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

<!-- 配置C3P0开源连接池 -->

<

bean

id

=

"dataSource"

class

=

"com.mchange.v2.c3p0.ComboPooledDataSource"

>

<

property

name

=

"driverClass"

value

=

"com.mysql.jdbc.Driver"

/>

<

property

name

=

"jdbcUrl"

value

=

"jdbc:mysql://192.168.174.130:3306/SSH"

/>

<

property

name

=

"user"

value

=

"root"

/>

<

property

name

=

"password"

value

=

"root"

/>

</

bean

>

<!-- 配置JDBC的模板类 -->

<

bean

id

=

"jdbcTemplate"

class

=

"org.springframework.jdbc.core.JdbcTemplate"

>

<

property

name

=

"dataSource"

ref

=

"dataSource"

/>

</

bean

>

<!-- 配置业务层和持久层 -->

<

bean

id

=

"accountService"

class

=

"com.clj.demo3.AccountServiceImpl"

>

<

property

name

=

"accountDao"

ref

=

"accountDao"

/>

</

bean

>

<

bean

id

=

"accountDao"

class

=

"com.clj.demo3.AccountDaoImpl"

>

<!-- 注入模板类-->

<

property

name

=

"jdbcTemplate"

ref

=

"jdbcTemplate"

/>  

<

property

name

=

"dataSource"

ref

=

"dataSource"

/>

</

bean

>

</

beans

>

3)测试类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

package

com.clj.demo3;

import

javax.annotation.Resource;

import

org.junit.Test;

import

org.junit.runner.RunWith;

import

org.springframework.test.context.ContextConfiguration;

import

org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith

(SpringJUnit4ClassRunner.

class

)

@ContextConfiguration

(

"classpath:applicationContext.xml"

)

public

class

Demo1 {

@Resource

(name=

"accountService"

)

private

AccountService accountService;

@Test

public

void

Demo1(){

//调用支付的方法

accountService.pay(

"佳先森"

,

"李钇林"

,

100

);

}

}

方式二:持久层继承JdbcDaoSupport接口,此接口封装了模板类jdbcTemplate

详解Spring框架入门

1)编写配置文件

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

<?

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

=

"http://www.springframework.org/schema/aop"

xmlns:tx

=

"http://www.springframework.org/schema/tx"

xsi:schemaLocation="http://www.springframework.org/schema/beans

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

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

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

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

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

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

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

<!-- 配置C3P0开源连接池 -->

<

bean

id

=

"dataSource"

class

=

"com.mchange.v2.c3p0.ComboPooledDataSource"

>

<

property

name

=

"driverClass"

value

=

"com.mysql.jdbc.Driver"

/>

<

property

name

=

"jdbcUrl"

value

=

"jdbc:mysql://192.168.174.130:3306/SSH"

/>

<

property

name

=

"user"

value

=

"root"

/>

<

property

name

=

"password"

value

=

"root"

/>

</

bean

>

<!-- 配置业务层和持久层 -->

<

bean

id

=

"accountService"

class

=

"com.clj.demo3.AccountServiceImpl"

>

<

property

name

=

"accountDao"

ref

=

"accountDao"

/>

</

bean

>

<

bean

id

=

"accountDao"

class

=

"com.clj.demo3.AccountDaoImpl"

<

property

name

=

"dataSource"

ref

=

"dataSource"

/>

</

bean

>

</

beans

>

2)更改持久层

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

package

com.clj.demo3;

import

org.springframework.jdbc.core.JdbcTemplate;

import

org.springframework.jdbc.core.support.JdbcDaoSupport;

public

class

AccountDaoImpl

extends

JdbcDaoSupport

implements

AccountDao{

//方式一:将jdbc模板类注入到配置文件中,直接在持久层写模板类

//  private JdbcTemplate jdbcTemplate;

//  public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {

//    this.jdbcTemplate = jdbcTemplate;

//  }

//方式二:持久层继承JdbcDaoSupport,它里面封转了模板类,配置文件持久层无需注入模板类,也不需要配置模板类

public

void

outMoney(String out,

double

money) {

//jdbcTemplate.update(psc);

String sql=

"update t_account set money=money-? where name=?"

;

this

.getJdbcTemplate().update(sql,money,out);

}

public

void

inMoney(String in,

double

money) {

String sql=

"update t_account set money=money+? where name=?"

;

this

.getJdbcTemplate().update(sql,money,in);

}

}

3)更改业务层

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

package

com.clj.demo4;

import

org.springframework.transaction.TransactionStatus;

import

org.springframework.transaction.support.TransactionCallbackWithoutResult;

import

org.springframework.transaction.support.TransactionTemplate;

public

class

AccountServiceImpl

implements

AccountService{

//采用的是配置文件注入方式,必须提供set方法

private

AccountDao accountDao;

public

void

setAccountDao(AccountDao accountDao) {

this

.accountDao = accountDao;

}

@Override

public

void

pay(String out, String in,

double

money) {

// TODO Auto-generated method stub

accountDao.outMoney(out, money);

int

a=

10

/

;

accountDao.inMoney(in, money);

}

}

4)测试类和上述一样

4、spring事务管理

Spring为了简化事务管理的代码:提供了模板类 TransactionTemplate,手动编程的方式来管理事务,只需要使用该模板类即可!!

九、Spring框架的事务管理之编程式的事务管理

1、手动编程方式事务(了解原理)

1)快速部署,搭建配置文件,配置事务管理和事务管理模板,并在持久层注入事务管理模板

配置事务管理器

?

1

2

3

4

<!-- 配置平台事务管理器 -->

<

bean

id

=

"transactionManager"

class

=

"org.springframework.jdbc.datasource.DataSourceTransactionManager"

>

<

property

name

=

"dataSource"

ref

=

"dataSource"

/>

</

bean

>

配置事务管理模板

?

1

2

3

<

bean

id

=

"transactionTemplate"

class

=

"org.springframework.transaction.support.TransactionTemplate"

>

<

property

name

=

"transactionManager"

ref

=

"transactionManager"

/>

</

bean

>

将管理模板注入业务层

?

1

2

3

4

<

bean

id

=

"accountService"

class

=

"com.clj.demo3.AccountServiceImpl"

>

<

property

name

=

"accountDao"

ref

=

"accountDao"

/>

<

property

name

=

"transactionTemplate"

ref

=

"transactionTemplate"

/>

</

bean

>

全部代码:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

<?

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

=

"http://www.springframework.org/schema/aop"

xmlns:tx

=

"http://www.springframework.org/schema/tx"

xsi:schemaLocation="http://www.springframework.org/schema/beans

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

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

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

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

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

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

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

<!-- 配置C3P0开源连接池 -->

<

bean

id

=

"dataSource"

class

=

"com.mchange.v2.c3p0.ComboPooledDataSource"

>

<

property

name

=

"driverClass"

value

=

"com.mysql.jdbc.Driver"

/>

<

property

name

=

"jdbcUrl"

value

=

"jdbc:mysql://192.168.174.130:3306/SSH"

/>

<

property

name

=

"user"

value

=

"root"

/>

<

property

name

=

"password"

value

=

"root"

/>

</

bean

>

<!-- 配置业务层和持久层 -->

<

bean

id

=

"accountService"

class

=

"com.clj.demo3.AccountServiceImpl"

>

<

property

name

=

"accountDao"

ref

=

"accountDao"

/>

<

property

name

=

"transactionTemplate"

ref

=

"transactionTemplate"

/>

</

bean

>

<

bean

id

=

"accountDao"

class

=

"com.clj.demo3.AccountDaoImpl"

<

property

name

=

"dataSource"

ref

=

"dataSource"

/>

</

bean

>

<!-- 配置平台事务管理器 -->

<

bean

id

=

"transactionManager"

class

=

"org.springframework.jdbc.datasource.DataSourceTransactionManager"

>

<

property

name

=

"dataSource"

ref

=

"dataSource"

/>

</

bean

>

<!-- 手动编码方式,提供了模板类,使用该类管理事务比较简单-->

<

bean

id

=

"transactionTemplate"

class

=

"org.springframework.transaction.support.TransactionTemplate"

>

<

property

name

=

"transactionManager"

ref

=

"transactionManager"

/>

</

bean

>

</

beans

>

2)在业务层使用模板事务管理

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

package

com.clj.demo3;

import

org.springframework.transaction.TransactionStatus;

import

org.springframework.transaction.support.TransactionCallbackWithoutResult;

import

org.springframework.transaction.support.TransactionTemplate;

public

class

AccountServiceImpl

implements

AccountService{

//采用的是配置文件注入方式,必须提供set方法

private

AccountDao accountDao;

//注入事务模板类

private

TransactionTemplate transactionTemplate;

public

void

setAccountDao(AccountDao accountDao) {

this

.accountDao = accountDao;

}

public

void

setTransactionTemplate(TransactionTemplate transactionTemplate) {

this

.transactionTemplate = transactionTemplate;

}

public

void

pay(

final

String out,

final

String in,

final

double

money) {

transactionTemplate.execute(

new

TransactionCallbackWithoutResult() {

//事务的执行,如果没有问题,提交,如果楚翔异常,回滚

protected

void

doInTransactionWithoutResult(TransactionStatus arg0) {

// TODO Auto-generated method stub

accountDao.outMoney(out, money);

int

a=

10

/

;

accountDao.inMoney(in, money);

}

});

}

}

3)测试类和上一致

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

package

com.clj.demo4;

import

javax.annotation.Resource;

import

org.junit.Test;

import

org.junit.runner.RunWith;

import

org.springframework.test.context.ContextConfiguration;

import

org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith

(SpringJUnit4ClassRunner.

class

)

@ContextConfiguration

(

"classpath:applicationContext2.xml"

)

public

class

Demo2 {

@Resource

(name=

"accountService"

)

private

AccountService accountService;

@Test

public

void

Demo1(){

//调用支付的方法

accountService.pay(

"佳先森"

,

"李钇林"

,

100

);

}

}

十、Spring框架的事务管理之声明式事务管理,即通过配置文件来完成事务管理(AOP思想)

申明式事务有两种方式:基于AspectJ的XML方式;基于AspectJ的注解方式

1、XML方式

1)配置配置文件

需要配置平台事务管理

?

1

2

3

4

5

6

7

8

9

10

11

<!-- 配置C3P0开源连接池 -->

<

bean

id

=

"dataSource"

class

=

"com.mchange.v2.c3p0.ComboPooledDataSource"

>

<

property

name

=

"driverClass"

value

=

"com.mysql.jdbc.Driver"

/>

<

property

name

=

"jdbcUrl"

value

=

"jdbc:mysql://192.168.174.130:3306/SSH"

/>

<

property

name

=

"user"

value

=

"root"

/>

<

property

name

=

"password"

value

=

"root"

/>

</

bean

>

<!-- 配置平台事务管理器 -->

<

bean

id

=

"transactionManager"

class

=

"org.springframework.jdbc.datasource.DataSourceTransactionManager"

>

<

property

name

=

"dataSource"

ref

=

"dataSource"

/>

</

bean

>

配置事务增强

?

1

2

3

4

5

6

7

<

tx:advice

id

=

"myAdvice"

transaction-manager

=

"transactionManager"

>

<

tx:attributes

>

<!-- 给方法设置数据库属性(隔离级别,传播行为) -->

<!--propagation事务隔离级别:一般采用默认形式:tx:method可以设置多个 -->

<

tx:method

name

=

"pay"

propagation

=

"REQUIRED"

/>

</

tx:attributes

>

</

tx:advice

>

aop切面类

?

1

2

3

4

<

aop:config

>

<!-- aop:advisor,是spring框架提供的通知-->

<

aop:advisor

advice-ref

=

"myAdvice"

pointcut

=

"execution(public * com.clj.demo4.AccountServiceImpl.pay(..))"

/>

</

aop:config

>

全部代码

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

<?

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

=

"http://www.springframework.org/schema/aop"

xmlns:tx

=

"http://www.springframework.org/schema/tx"

xsi:schemaLocation="http://www.springframework.org/schema/beans

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

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

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

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

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

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

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

<!-- 配置C3P0开源连接池 -->

<

bean

id

=

"dataSource"

class

=

"com.mchange.v2.c3p0.ComboPooledDataSource"

>

<

property

name

=

"driverClass"

value

=

"com.mysql.jdbc.Driver"

/>

<

property

name

=

"jdbcUrl"

value

=

"jdbc:mysql://192.168.174.130:3306/SSH"

/>

<

property

name

=

"user"

value

=

"root"

/>

<

property

name

=

"password"

value

=

"root"

/>

</

bean

>

<!-- 配置平台事务管理器 -->

<

bean

id

=

"transactionManager"

class

=

"org.springframework.jdbc.datasource.DataSourceTransactionManager"

>

<

property

name

=

"dataSource"

ref

=

"dataSource"

/>

</

bean

>

<!-- 申明式事务(采用XML文件的方式) -->

<!-- 先配置通知 -->

<

tx:advice

id

=

"myAdvice"

transaction-manager

=

"transactionManager"

>

<

tx:attributes

>

<!-- 给方法设置数据库属性(隔离级别,传播行为) -->

<!--propagation事务隔离级别:一般采用默认形式:tx:method可以设置多个 -->

<

tx:method

name

=

"pay"

propagation

=

"REQUIRED"

/>

</

tx:attributes

>

</

tx:advice

>

<!-- 配置AOP:如果是自己编写的AOP,使用aop:aspect配置,使用的是Spring框架提供的通知 -->

<

aop:config

>

<!-- aop:advisor,是spring框架提供的通知-->

<

aop:advisor

advice-ref

=

"myAdvice"

pointcut

=

"execution(public * com.clj.demo4.AccountServiceImpl.pay(..))"

/>

</

aop:config

>

<!-- 配置业务层和持久层 -->

<

bean

id

=

"accountService"

class

=

"com.clj.demo4.AccountServiceImpl"

>

<

property

name

=

"accountDao"

ref

=

"accountDao"

/>

</

bean

>

<

bean

id

=

"accountDao"

class

=

"com.clj.demo4.AccountDaoImpl"

>

<

property

name

=

"dataSource"

ref

=

"dataSource"

/>

</

bean

>

</

beans

>

2)编写持久层和业务层(省略接口)

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

package

com.clj.demo5;

import

org.springframework.jdbc.core.JdbcTemplate;

import

org.springframework.jdbc.core.support.JdbcDaoSupport;

public

class

AccountDaoImpl

extends

JdbcDaoSupport

implements

AccountDao{

//方式一:将jdbc模板类注入到配置文件中,直接在持久层写模板类

//  private JdbcTemplate jdbcTemplate;

//  public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {

//    this.jdbcTemplate = jdbcTemplate;

//  }

//方式二:持久层继承JdbcDaoSupport,它里面封转了模板类,配置文件持久层无需注入模板类,也不需要配置模板类

public

void

outMoney(String out,

double

money) {

//jdbcTemplate.update(psc);

String sql=

"update t_account set money=money-? where name=?"

;

this

.getJdbcTemplate().update(sql,money,out);

}

public

void

inMoney(String in,

double

money) {

String sql=

"update t_account set money=money+? where name=?"

;

this

.getJdbcTemplate().update(sql,money,in);

}

}

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

package

com.clj.demo5;

import

org.springframework.transaction.TransactionStatus;

import

org.springframework.transaction.annotation.Transactional;

import

org.springframework.transaction.support.TransactionCallbackWithoutResult;

import

org.springframework.transaction.support.TransactionTemplate;

public

class

AccountServiceImpl

implements

AccountService{

//采用的是配置文件注入方式,必须提供set方法

private

AccountDao accountDao;

public

void

setAccountDao(AccountDao accountDao) {

this

.accountDao = accountDao;

}

@Override

public

void

pay(String out, String in,

double

money) {

// TODO Auto-generated method stub

accountDao.outMoney(out, money);

int

a=

10

/

;

accountDao.inMoney(in, money);

}

}

3)测试类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

package

com.clj.demo4;

import

javax.annotation.Resource;

import

org.junit.Test;

import

org.junit.runner.RunWith;

import

org.springframework.test.context.ContextConfiguration;

import

org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith

(SpringJUnit4ClassRunner.

class

)

@ContextConfiguration

(

"classpath:applicationContext2.xml"

)

public

class

Demo2 {

@Resource

(name=

"accountService"

)

private

AccountService accountService;

@Test

public

void

Demo1(){

//调用支付的方法

accountService.pay(

"佳先森"

,

"李钇林"

,

100

);

}

}

2、注解方式

1)配置配置文件

配置事务管理

?

1

2

3

4

5

6

7

8

9

<

bean

id

=

"dataSource"

class

=

"com.mchange.v2.c3p0.ComboPooledDataSource"

>

<

property

name

=

"driverClass"

value

=

"com.mysql.jdbc.Driver"

/>

<

property

name

=

"jdbcUrl"

value

=

"jdbc:mysql://192.168.174.130:3306/SSH"

/>

<

property

name

=

"user"

value

=

"root"

/>

<

property

name

=

"password"

value

=

"root"

/>

</

bean

>

<

bean

id

=

"transactionManager"

class

=

"org.springframework.jdbc.datasource.DataSourceTransactionManager"

>

<

property

name

=

"dataSource"

ref

=

"dataSource"

/>

</

bean

>

开启注释事务

?

1

2

<!-- 开启事务的注解 -->

<

tx:annotation-driven

transaction-manager

=

"transactionManager"

/>

全部代码

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

<?

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

=

"http://www.springframework.org/schema/aop"

xmlns:tx

=

"http://www.springframework.org/schema/tx"

xsi:schemaLocation="http://www.springframework.org/schema/beans

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

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

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

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

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

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

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

<!-- 配置C3P0开源连接池 -->

<

bean

id

=

"dataSource"

class

=

"com.mchange.v2.c3p0.ComboPooledDataSource"

>

<

property

name

=

"driverClass"

value

=

"com.mysql.jdbc.Driver"

/>

<

property

name

=

"jdbcUrl"

value

=

"jdbc:mysql://192.168.174.130:3306/SSH"

/>

<

property

name

=

"user"

value

=

"root"

/>

<

property

name

=

"password"

value

=

"root"

/>

</

bean

>

<!-- 配置平台事务管理器 -->

<

bean

id

=

"transactionManager"

class

=

"org.springframework.jdbc.datasource.DataSourceTransactionManager"

>

<

property

name

=

"dataSource"

ref

=

"dataSource"

/>

</

bean

>

<!-- 开启事务的注解 -->

<

tx:annotation-driven

transaction-manager

=

"transactionManager"

/>

<!-- 配置业务层和持久层 -->

<

bean

id

=

"accountService"

class

=

"com.clj.demo5.AccountServiceImpl"

>

<

property

name

=

"accountDao"

ref

=

"accountDao"

/>

</

bean

>

<

bean

id

=

"accountDao"

class

=

"com.clj.demo5.AccountDaoImpl"

>

<

property

name

=

"dataSource"

ref

=

"dataSource"

/>

</

bean

>

</

beans

>

2)业务层增加@Transactional

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

package

com.clj.demo5;

import

org.springframework.transaction.TransactionStatus;

import

org.springframework.transaction.annotation.Transactional;

import

org.springframework.transaction.support.TransactionCallbackWithoutResult;

import

org.springframework.transaction.support.TransactionTemplate;

//在当前类加此注解表示当前类所有的全部都有事务

@Transactional

public

class

AccountServiceImpl

implements

AccountService{

//采用的是配置文件注入方式,必须提供set方法

private

AccountDao accountDao;

public

void

setAccountDao(AccountDao accountDao) {

this

.accountDao = accountDao;

}

@Override

public

void

pay(String out, String in,

double

money) {

// TODO Auto-generated method stub

accountDao.outMoney(out, money);

int

a=

10

/

;

accountDao.inMoney(in, money);

}

}

3)持久层不变

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

package

com.clj.demo5;

import

org.springframework.jdbc.core.JdbcTemplate;

import

org.springframework.jdbc.core.support.JdbcDaoSupport;

public

class

AccountDaoImpl

extends

JdbcDaoSupport

implements

AccountDao{

//方式一:将jdbc模板类注入到配置文件中,直接在持久层写模板类

//  private JdbcTemplate jdbcTemplate;

//  public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {

//    this.jdbcTemplate = jdbcTemplate;

//  }

//方式二:持久层继承JdbcDaoSupport,它里面封转了模板类,配置文件持久层无需注入模板类,也不需要配置模板类

public

void

outMoney(String out,

double

money) {

//jdbcTemplate.update(psc);

String sql=

"update t_account set money=money-? where name=?"

;

this

.getJdbcTemplate().update(sql,money,out);

}

public

void

inMoney(String in,

double

money) {

String sql=

"update t_account set money=money+? where name=?"

;

this

.getJdbcTemplate().update(sql,money,in);

}

}

4)测试类

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

package

com.clj.demo5;

import

javax.annotation.Resource;

import

org.junit.Test;

import

org.junit.runner.RunWith;

import

org.springframework.test.context.ContextConfiguration;

import

org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith

(SpringJUnit4ClassRunner.

class

)

@ContextConfiguration

(

"classpath:applicationContext3.xml"

)

public

class

Demo3 {

@Resource

(name=

"accountService"

)

private

AccountService accountService;

@Test

public

void

Demo1(){

//调用支付的方法

accountService.pay(

"佳先森"

,

"李钇林"

,

100

);

}

}

继续阅读