Spring
学习笔记
【Spring
官网】https://spring.io/
【Github
链接】https://github.com/spring-projects/spring-framework
【Spring
官方文档】https://docs.spring.io/spring-framework/reference/
【Spring
官方API
文档】https://docs.spring.io/spring-framework/docs/current/javadoc-api/
【中文文档】https://springdoc.cn/spring/index.html
一、Spring
简介
1.1、优点
Spring
的优点:
- 开源免费
- 轻量级、非侵入式的框架
- 控制反转
loC
,面向切面Aop
- 对事务的支持,对框架的支持
1.2、核心组成
Spring
的七大模块。
1.3、控制反转IoC
IoC
(Inversion of Control
,控制反转) 是一种设计思想,而不是一个具体的技术实现。IoC
的思想就是将原本在程序中手动创建对象的控制权,交由 Spring
框架来管理。不过, IoC
并非 Spring
特有,在其他语言中也有应用。
为什么叫控制反转?
- 控制:指的是对象创建(实例化、管理)的权力。传统应用程序的对象是由程序本身控制创建的,使用
Spring
后,对象是由Spring
来创建的。 - 反转:控制权交给外部环境(
Spring
框架、IoC
容器)。程序本身不创建对象,而变成被动的接收对象。
控制反转是一种通过描述(XML
或注解)并通过第三方去生产或获取特定对象的方式。在Spring
中实现控制反转的是loC
容器,其实现方法是依赖注入(Dependency Injection,DI
)。
依赖注入:就是利用set
方法来进行注入的。
一句话概括
IoC
:对象由Spring
来创建,管理,装配!
二、第一个Spring
程序
2.1、依赖导入
maven
依赖导入。
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>6.1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<!--
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>6.1.4</version>
</dependency>
-->
2.2、pojo
实体类
放在src/main/java
路径下。
package com.wzq.pojo;
public class Hello {
private String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
@Override
public String toString() {
return "Hello{" +
"str='" + str + '\'' +
'}';
}
}
2.3、配置文件
放在src/main/resources/beans.xml
路径下。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 在 Spring 中,使用 Bean 代指被 IoC 容器所管理的对象 -->
<bean id="hello" class="com.wzq.pojo.Hello">
<property name="str" value="Spring"/>
</bean>
</beans>
2.4、测试类
放在src/test/java
路径下。
import com.wzq.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
// 获取 Spring 的上下文对象(此时容器中管理的所有对象被创建出来)
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
// 对象现在都在 Spring 中管理了,使用时直接取出来即可
Hello hello = (Hello) context.getBean("hello");
System.out.println(hello.toString()); // Hello{str='Spring'}
}
}
OK
,到了现在,我们就不用再在程序中改动了,要实现不同的操作,只需要在xml
配置文件中进行修改。
例如,想要输出
Hello{str='Little'}
,只需要将xml
中修改为<property name="str" value="Spring"/>
。
三、Spring
配置
3.1、别名
使用以下语法配置别名(和<bean>
标签同级)。
<!-- 别名(如果添加了别名,我们也可以使用别名获取到这个对象) -->
<alias name="user" a1ias="userNew" />
3.2、bean
的配置
<!--
id: bean 的唯一标识符,相当于对象名
class: bean 对象所对应的全限定名: 包名 + 类名
name: 也是别名,而且 name 可以同时取多个别名
-->
<bean id="userT" class="com.wzq.pojo.userT" name="user2 u2 u3 u4">
<property name="name" value="Little"/>
</bean>
3.3、import
一般用于团队开发使用,可以将多个配置文件,导入合并为一个。
假设项目中有多个人进行开发,他们负责不同的类的开发,并注册在不同的bean
配置文件中。可以利用import
将所有人的beans.xml
合并为一个总的。
<!-- applicationContext.xml -->
<import resource="beans.xm1" />
<import resource="beans2.xml" />
<import resource="beans3.xm1" />
使用的时候,直接使用总的配置文件即可。
四、依赖注入DI
(重点)
对于依赖注入的理解:
- 依赖:
bean
对象的创建依赖于容器! - 注入:
bean
对象中的所有属性,由容器来注入!
4.1、基于构造器的依赖注入
IoC
默认使用无参构造函数创建对象。
也可以配置使用有参构造函数创建对象 官网文档链接。
<!-- 方式一 使用下标 -->
<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg index="0" value="7500000"/>
<constructor-arg index="1" value="42"/>
</bean>
<!-- 方式二 使用参数类型 -->
<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg type="int" value="7500000"/>
<constructor-arg type="java.lang.String" value="42"/>
</bean>
<!-- 方式三 使用参数名(常用!) -->
<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg name="years" value="7500000"/>
<constructor-arg name="ultimateAnswer" value="42"/>
</bean>
如果参数是引用的对象,如下情况。
package x.y;
public class ThingOne {
public ThingOne(ThingTwo thingTwo, ThingThree thingThree) {
// ...
}
}
可以使用下面的方式来实现。
<beans>
<bean id="beanOne" class="x.y.ThingOne">
<constructor-arg ref="beanTwo"/>
<constructor-arg ref="beanThree"/>
</bean>
<bean id="beanTwo" class="x.y.ThingTwo"/>
<bean id="beanThree" class="x.y.ThingThree"/>
</beans>
4.2、基于Setter
的依赖注入【重要!】
以下给出了各种类型的属性的注入方式。
<bean id="address" class="com.wzq.pojo.Address">
<property name="address" value="西安" />
</bean>
<bean id="student" class="com.wzq.pojo.Student">
<!-- common value DI: value -->
<property name="name" value="WZQ"/>
<!-- Bean DI: ref -->
<property name="address" ref="address"/>
<!-- array DI: array -->
<property name="books">
<array>
<value>红楼梦</value>
<value>西游记</value>
<value>水浒传</value>
<value>三国演义</value>
</array>
</property>
<!-- List -->
<property name="hobbys">
<list>
<value>听歌</value>
<value>敲代码</value>
<value>看电影</value>
</list>
</property>
<!-- Map -->
<property name="card">
<map>
<entry key="身份证" value="1112223333"/>
<entry key="银行卡" value="1232323232"/>
</map>
</property>
<!-- Set -->
<property name="games">
<set>
<value>LOL</value>
<value>COC</value>
<value>BOB</value>
</set>
</property>
<!-- null -->
<property name="wife">
<null/>
</property>
<!-- Properties -->
<property name="info">
<props>
<prop key="driver">0918</prop>
<prop key="url">男</prop>
<prop key="username">小明</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
4.3、P
命名空间和C
命名空间
这两者都是XML
的快捷方式,使用举例如下。
<?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"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- p (property) namespace DI, can directly DI properties' value -->
<bean id="user" class="com.wzq.pojo.User" p:name="WZQ" p:age="24"/>
<!-- c (constructor) namespace DI, can DI by constructor -->
<bean id="user2" class="com.wzq.pojo.User" c:name="QZW" c:age="23"/>
</beans>
五、Bean
的作用域
六、Bean
的自动装配
自动装配是Spring
满足bean
依赖一种方式。Spring
会在上下文中自动寻找,并自动给bean
装配属性。
<bean id="cat" class="wzq.dao.pojo.Cat"/>
<bean id="dog" class="wzq.dao.pojo.Dog"/>
<!--
byName: could automatically find within the container (beans.xml), which has the same Name as Set function.
byType: could automatically find within the container (beans.xml), which has the same Type as Attribute type.
-->
<bean id="people" class="wzq.dao.pojo.People" autowire="byName">
<property name="name" value="WZQ"/>
</bean>
注意:
- 使用
byName
时:需要保证所有bean
的id
唯一,并且需要和自动注入的属性的set
方法一致。 - 使用
byType
的:需要保证所有bean
的class
唯一,并且需要和自动注入的属性的类型一致。
七、使用注解
使用注解前,需要在xml
文件中配置context
的支持。
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解支持 -->
<context:annotation-config/>
<context:component-scan base-package="com.wzq"/>
</beans>
【注】上述的
component-scan
标签。配置这个标签后,spring
就会去自动扫描base-package
对应的路径或者该路径的子包下面的java
文件,如果扫描到文件中带有@Service, @Component ,@Repository, @Controller
等这些注解的类,则把这些类注册为bean
。
7.1、配置bean
的注解
@Component
注解:组件,用在类上,说明这个类被Spring
管理了,就是bean
。有几个衍生的注解(功能相同):
@Repository
注解:用在dao
层的类上。@Service
注解:用在service
层的类上。@Controller
注解:用在controller
层的类上。
@Value
注解:用在属性或相应的setter
方法上,用于注入值。
@Scope
注解:用在类上,标识作用域。
package com.wzq.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
// @Component 等价于 <bean id="user" class="com.wzq.pojo.User" />
@Component
@Scope("singleton")
public class User {
@Value("wzq")
public String name;
}
7.2、自动装配的注解
@Autowired
注解:实现自动装配。可以在属性上使用,也可以在相应的setter
方法上使用。
【注】使用@Autowired
注解在属性上后,甚至可以不需要写setter
方法。
package wzq.dao.pojo;
import org.springframework.beans.factory.annotation.Autowired;
public class People {
private String name;
@Autowired
private Cat cat;
@Autowired
private Dog dog;
......
}
【注】采用注解实现自动装配时,先采取
byType
的策略(@Autowired
),如果找到多个再通过byName
的方式最终确定其中一个(@Qualifier
)。
7.3、配置相关注解
package com.wzq.config;
import com.wzq.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration // 配置
@ComponentScan("com.wzq.pojo") // 扫描包
@Import(WzqConfig2.class) // 导入其他配置类
public class WzqConfig {
@Bean
public User user(){
return new User();
}
}
测试类代码如下:
import com.wzq.config.WzqConfig;
import com.wzq.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest {
public static void main(String[] args) {
// 使用 AnnotationConfigApplicationContext 进行加载s
ApplicationContext context = new AnnotationConfigApplicationContext(WzqConfig.class);
User getUser = (User) context.getBean("user");
System.out.println(getUser.getName());
}
}
八、AOP
8.1、动态代理模式(重点)
接口方法。
package com.wzq.demo03;
public interface Rent {
public void rent();
}
需要被代理的类。
package com.wzq.demo03;
public class Host implements Rent {
public void rent() {
System.out.println("房东要出租房子!");
}
}
代理调用处理程序。
package com.wzq.demo03;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 这个类用于自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
// 被代理的接口
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
// 生成得到代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
rent.getClass().getInterfaces(), this);
}
// 处理代理实例,并返回结果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seeHouse();
// 动态代理的本质,就是使用反射机制实现
Object result = method.invoke(rent, args);
fee();
return result;
}
public void seeHouse(){
System.out.println("中介带你看房子");
}
public void fee(){
System.out.println("收中介费");
}
}
调用代理的类。
package com.wzq.demo03;
public class Client {
public static void main(String[] args) {
// 真实角色
Host host = new Host();
// 代理角色,通过处理类生成
ProxyInvocationHandler pih = new ProxyInvocationHandler();
// 通过调用程序处理角色来处理我们要调用的接口对象
pih.setRent(host);
// proxy 是动态生成的代理
Rent proxy = (Rent) pih.getProxy();
proxy.rent();
}
}
8.2、AOP
概述
AOP
(Aspect Oriented Programming
,面向切面编程),通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
AOP
是OOP
的延续,是软件开发中的一个热点,也是Spring
框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP
可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
8.3、AOP
在Spring
中的作用
提供声明式事务;允许用户自定义切面。
- 横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志,安全,缓存,事务等等....
- 切面(
ASPECT
):横切关注点被模块化的特殊对象。即,它是一个类。 - 通知(
Advice
):切面必须要完成的工作。即,它是类中的一个方法。 - 目标(
Target
):被通知对象。 - 代理(
Proxy
):向目标对象应用通知之后创建的对象。 - 切入点(
PointCut
):切面通知执行的“地点"的定义。 - 连接点(
JointPoint
):与切入点匹配的执行点。
SpringAOP
中,通过Advice
定义横切逻辑,Spring
中支持5
种类型的Advice
:
即AOP
在不改变原有代码的情况下,去增加新的功能。
8.4、使用Spring
实现AOP
首先需要导入一个织入包。
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
8.4.1、环境搭建
配置文件。
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- register bean -->
<bean id="userService" class="com.wzq.service.UserServiceImpl"/>
<!-- Method_01 : Use Origin Spring API Interface -->
<bean id="log" class="com.wzq.log.Log"/>
<bean id="afterLog" class="com.wzq.log.AfterLog"/>
<!-- config aop -->
<aop:config>
<!-- PointCut expression execution(the position you want to execute) -->
<aop:pointcut id="pointcut" expression="execution(* com.wzq.service.UserServiceImpl.*(..))"/>
<!-- Execute advisor add -->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>-->
<!-- Method_02 : Use DIY Class -->
<bean id="diy" class="com.wzq.diy.DiyPointCut"/>
<aop:config>
<!-- diy aspect, ref: the class needs to be used -->
<aop:aspect ref="diy">
<!-- pointcut -->
<aop:pointcut id="point" expression="execution(* com.wzq.service.UserServiceImpl.*(..))"/>
<!-- advice -->
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
<!-- Method_03 : Use DIY Class -->
<bean id="annotationPointCut" class="com.wzq.diy.AnnotationPointCut"/>
<!-- open annotation support -->
<aop:aspectj-autoproxy/>
</beans>
测试类。
import com.wzq.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 动态代理代理的是接口
UserService userService = (UserService) context.getBean("userService");
userService.delete();
}
}
8.4.1、通过Spring API
实现
Log
类,用于在方法执行前输出日志。
package com.wzq.log;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class Log implements MethodBeforeAdvice {
// method: 要执行的目标对象的方法
// args: 参数
// target: 目标对象
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName() + "的" + method.getName() + "被执行了");
}
}
AfterLog
类,用于在方法执行后输出日志。
package com.wzq.log;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class AfterLog implements AfterReturningAdvice {
// returnValue: 返回值
public void afterReturning(Object returnValue, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println("执行了" + method.getName() + "方法,返回结果为: " + returnValue);
}
}
8.4.2、自定义类实现AOP
自定义类,在方法执行前和执行后输出日志。
package com.wzq.diy;
public class DiyPointCut {
public void before(){
System.out.println("=================方法执行前================");
}
public void after(){
System.out.println("=================方法执行后================");
}
}
8.4.3、注解实现AOP
使用注解标注。
package com.wzq.diy;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect // 标注这个类是一个切面
public class AnnotationPointCut {
@Before("execution(* com.wzq.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("=============方法执行前============");
}
@After("execution(* com.wzq.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("=============方法执行后============");
}
@Around("execution(* com.wzq.service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("环绕前");
Signature signature = jp.getSignature();
System.out.println("signature: " + signature);
Object proceed = jp.proceed();
System.out.println("环绕后");
System.out.println(proceed);
}
}
九、整合Mybatis
(重点)
【Mybatis-Spring
Github
链接】https://github.com/mybatis/spring
9.1、导入相关依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!-- use Spring to connect database, need Spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
9.2、配置文件
mybatis
配置文件(mybatis-config.xml
)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.wzq.pojo"/>
</typeAliases>
</configuration>
spring
用于连接mybatis
的配置文件(spring-dao.xml
)。
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- DataSource: using Spring's datasource to replace Mybatis's Configuration c3p0 dbcp druid
Here we use JDBC which is supplied by Spring -->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="132402"/>
</bean>
<!-- sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="datasource"/>
<!-- bound Mybatis configuration file -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/wzq/mapper/*.xml"/>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!-- can only use constructor to DI, because it has no Set Method -->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
</beans>
spring
总体配置文件(applicationContext.xml
)。
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<import resource="spring-dao.xml"/>
<bean id="userMapper" class="com.wzq.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
<bean id="userMapper2" class="com.wzq.mapper.UserMapperImpl2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
</beans>
9.3、实现类
实现类(UserMapperImpl.java
)。
package com.wzq.mapper;
import com.wzq.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;
public class UserMapperImpl implements UserMapper{
// 原来所有操作都通过 sqlSession 来执行,现在都使用 sqlSessionTemplate
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
public List<User> selectUser() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUser();
}
}
// 【注】也可以简化为如下版本
package com.wzq.mapper;
import com.wzq.pojo.User;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper {
public List<User> selectUser() {
return getSqlSession().getMapper(UserMapper.class).selectUser();
}
}
9.4、测试类
测试类。
import com.wzq.mapper.UserMapper;
import com.wzq.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
public class MyTest {
@Test
public void test() throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
for (User user : userMapper.selectUser()) {
System.out.println(user);
}
}
}
十、声明式事务
在spring-dao.xml
文件中,新增事务的配置(利用AOP
的特性)。
<!-- http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd
-->
<!-- Config announced Transaction -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- <constructor-arg ref="dataSource" />-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- Combine AOP to realize Transaction's import -->
<!-- Config Transaction's advice -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- config transactions for which method -->
<!-- config transactions' propagation feature -->
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="delete"/>
<tx:method name="update"/>
<tx:method name="query" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- Config transactions' pointCut -->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.wzq.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
评论区