Spring
Spring介绍
1.简介
Spring是一个开源框架,简化企业级开发
2.优点
- 基于POJO的轻量级框架以及无侵入性
- 通过IOC控制反转、DI依赖注入和面向接口解耦
- 基于AOP进行声明式编程
- 通过切面和模版减少样式代码
3.组成

IOC
降低程序间的耦合,将对象的创建和维护以及之间的依赖关系交给Spring提供的IOC容器管理,通过DI进行依赖注入,避免硬编码造成的过度程序耦合
程序耦合:
类与类之间的依赖关系,会造成独立性很差
方法之间的依赖关系
解耦:
降低程序间的依赖关系
实际开发中:
想做到完全不依赖是不可能的,所以实际开发中做到编译时不依赖,运行时才依赖
思路:
1.通过反射对象的全限定类名来来创建对象,不使用new关键字
2.通过读取配置文件拿要创建到对象的全限定类名,避免多次使用该类,以后替换麻烦
xml中将对象注入到IOC
创建一个xml.名字不是中文即可
<!--xml基本元数据的基本结构-->
<beans xmlns="http://www.springframework.org/schema/beans"
<!--xsi前缀-->
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<!--spring约束地址-->
xsi:schemaLocation="http://www.springframework.org/schema/beans
<!--spring约束-->
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--1.将对象交给Spring管理的三种方式
第二种和第三种方式只有在我们修改不了源码的情况下才会使用,比如调用写好的jar包
-->
1.常用方式:
<bean id="对象唯一标识" class="对象全限定类名"></bean>
2.通过工厂类的普通方法来创建对象,然后交给Spring
<bean id="工厂类对象唯一标识" class="工厂类对象的全限定类名"></bean>
<bean id="要创建的对象唯一标识" factory-bean="工厂类对象唯一标识" factory-method="创建对象的方法">
3.通过工厂类的静态方法来创建对象,然后交给Spring
<bean id="对象唯一标识" factory="工厂类的全限定类名" factory-method="创建对象的静态方法">
</beans>
IOC创建对象
ApplicaitonContext的三个实现类:
ClassPathXmlApplicationContext:加载类路径下的文件,不在就加载不了
FileSystemApplicationContext:加载磁盘任意路径下的文件
AnnotationApplicationContext:读取注解
//加载xml文件创建spring容器对象
ApplicationContext context = new ClassPathXmlApplicationContext("xml文件");
//根据对象的标识也就是id获取对象,然后强转
Object object = context.getBean("唯一标识");
依赖注入
bean对象的作用域
scope:
singleton:单例
生命周期跟随容器,容器创建对象就创建,容器销毁对象就销毁
prototype:多例
当调用对象时才创建,当对象长时间不使用并且没有对象引用,由GC回收
1.构造器注入
代码中创建有参构造方法,xml中使用constructor-arg标签
优点:
- 创建对象时必须注入数据,否则无法创建成功
缺点:
- 如果我们用不到这些数据,也必须赋值
属性:
- type: 通过构造参数的类型来找到赋值
- index: 通过构造参数的索引来找到赋值
- name: 通过构造参数的名字来找到赋值 常用!
- value:给基本类型和String类型赋值
- ref:给其他bean类型赋值 指的是存在Spring容器中的bean对象
<bean id="accountService" class="com.djn.springioc.service.impl.AccountServiceImpl">
<constructor-arg name="name" value="丁江楠"></constructor-arg>
<constructor-arg name="age" value="22"></constructor-arg>
<!--引用其他bean类型-->
<constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
<!--向Spring容器添加Date对象-->
<bean id="now" class="java.util.Date"></bean>
2.set方法注入:更常用
代码中对属性创建set方法,在xml中使用property关键字
优点:
- 可以直接使用默认的构造函数创建对象
缺点:
- 获取对象时,如果没有注入,会没有值,不严谨
属性:
- name:用于指定set方法名称
- value:给基本类型和String类型赋值
- ref:给其他bean类型赋值 指的是存在Spring容器中的bean对象
<bean id="accountService2" class="com.djn.springioc.service.impl.AccountServiceImpl2">
<property name="userName" value="张贤伟"></property>
<property name="age" value="22"></property>
</bean>
3.集合注入
<!--
集合注入
array,list,set,map,properties
-->
<bean id="accountService3" class="com.djn.springioc.service.impl.AccountServiceImpl3">
<property name="args">
<array>
<value>array</value>
<value>array</value>
<value>array</value>
</array>
</property>
<property name="list">
<list>
<value>123</value>
<value>123</value>
<value>123</value>
</list>
</property>
<property name="set">
<set>
<value>456</value>
<value>456</value>
<value>456</value>
</set>
</property>
<property name="map">
<map>
<entry key="123" value="456"></entry>
<entry key="1234" value="456"></entry>
<entry key="12345" value="456"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="driver">driveer</prop>
</props>
</property>
</bean>
基于注解的IOC
1.用于将对象注入到IOC
1.@Component
作用:将当前类对象存入到Spring对象中
属性:
value:用于指定bean对象的id,也就是唯一标识,如果不写那id默认为当前类名且首字母小写,大小写必须一致
2.@Controller:一般用于表现层
3.@Service:一般用于业务层
4.@Repository:一般用于持久层
⚠️:@Controller、@Service、@Repository作用与@Component一模一样,主要是为了我们的类职责看起来更加的清晰
还需要在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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--告知spring创建时要扫描的包,扫描注解-->
<context:component-scan base-package="com.djn.springioc"></context:component-scan>
</beans>
2.用于依赖注入的注解
1.@Autowired
作用:将spring容器的bean对象自动注入,自动按照类型注入,只要Spring容器中有一个唯一的bean类型和要注入的bean类型匹配,就可以注入成功,
如果没有,就报错
如果有多个bean类型匹配,那就可以使用:@Qualifier或者@Resource
@Autowired
IAccountDao accountDao;
会根据类型为IAccountDao去容器中找,而不是accountDao找
2.@Qualifier
作用:可以在类型注入的基础上在按照名称注入,当Spring容器中有多个bean类型,可以根据它的属性value进行匹配注入
属性:
value:用于指定要注入bean的id
注意:需要和Autowired一起使用,它只负责匹配名称,不负责注入
@Autowired
@Qualifier(value = "accountDao1")
IAccountDao accountDao;
会根据id为accountDao1去容器中找,而不是IAccountDao去找
3.@Resource
作用:直接按照bean的id进行注入,可以独立使用
属性:
name:用于指定要注入对象的id
@Resource(name = "accountDao1")
IAccountDao accountDao;
会根据id为accountDao1去容器中找
⚠️:以上三种只能注入其他bean类型,不能注入基本数据和String类型
4.@Value
作用:用于注入基本数据和String类型,它可以使用SpEl(spring的el表达式 ${})
@Value("500")
int count;
给count赋值为500
3.用于作用域和生命周期
1.@Scope
作用:声明对象的作用域
属性:
value:singleton单例、prototype多例
2.@PostConstruct
作用:用于指定初始化方法,在方法上声明
@PreDestory
作用:用于指定销毁方法,在方法上声明
4.用于替换xml配置
1.@Configuration
作用:它的作用和beans.xml是一模一样的,指定当前类是配置类
⚠️:它也不一定需要写,当使用AnnontationApplicationContext获取spring容器对象指定配置
类时这个注解就可以不写,可以指定多个(但是不建议指定多个),采取父子配置类的方式更清晰
2.@ComponentScan
作用:告知spring创建时要扫描的包,扫描注解并且创建对象,
与<context:component-scan base-package="com.djn.springioc"></context:component-scan>作用是一样的
属性:
value:用于指定要扫描的包,如果有多个包,可以@ComponentScan({"",""})这样指定
3.@Bean
作用:用于将方法的返回对象存入spring容器中
属性:
name:指定bean的id,当不写时,默认是方法名
4.@Import:
作用:用于指定配置的类,当其他的子配置类不写@Configuration时,可以在父配置类中通过它指定子配置类
//代表当前类是一个注解类
@Configuration
//扫描com.djn.ioccase包下的注解并注入到Spring容器
@ComponentScan("com.djn.ioccase")
//导入JDBCConfiguration配置类
@Import(JDBCConfiguration.class)
public class SpringConfiguration {
//将JdbcTemplate注入到Spring容器中
@Bean("jdbcTemplate")
public JdbcTemplate createJdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
//将DataSource注入到Spring容器中
@Bean
public DataSource createDatasource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/localtest");
dataSource.setUsername("root");
dataSource.setPassword("mysql04141015");
return dataSource;
}
}
5.用于加载配置文件
@PropertySource("classpath:配置文件")
配合@Value使用
@PropertySource("classpath:druid.properties")
public class JDBCConfiguration {
@Value("${driverClassName}")
String driverClassName;
@Value("${url}")
String url;
@Value("${username}")
String username;
@Value("${password}")
String password;
//将JdbcTemplate注入到Spring容器中
@Bean("jdbcTemplate")
public JdbcTemplate createJdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
//将DataSource注入到Spring容器中
@Bean
public DataSource createDatasource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
6.用于和Juit整合
1.@RunWith(SpringJunit4ClassRunner.class)
作用:JUnit默认是提供了一个main方法,然后去找@Test注解,不会加载Spring文件,使用它可以替换掉main方法,使用Spring提供的
2.@ContextConfiguration
作用:告诉spring运行器,spring创建是基于xml还是注解,并且指定文件位置
属性:
locations:指定xml文件的地址,需要加上classpath,表示在类路径下
classes:指定注解类所在的位置
⚠️:SpringJUnit4ClassRunner requires JUnit 4.12 or higher.Spring5.x版本需要Junit在4.12及以上版本
========================= =========================
⚠️:注解和xml选用原则:对于自己写的类使用注解更方便,对于别人写好的类还是使用xml,因为使用注解很麻烦,需要各种配置
AOP
AOP即“面向切面编程”,基于动态代理实现的,对程序的功能进行统一的维护,降低各部分业务逻辑之间的耦合,提高程序复用性和维护性
动态代理:
通过代理真实对象,在客户端对象与真实对象之间起到中介作用,在不改变真实对象的源码情况下,来增强真实对象的功能
分类:
JDK提供的基于接口的动态代理
Proxy.newInstance(目标对象类加载器、目标对象的接口、方法)
Cglib提供的基于子类的动态代理
AOP会根据目标对象有没有实现接口来决定采用哪种代理方式
1.导入jar包:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
xml中配置AOP
1.配置步骤:
1.将切面类存入到Spring容器中
2.开始配置AOP
3.配置切面
4.配置通知类型 并且 将通知方法与切入点方法关联
<!--配置切面类-->
<bean id="logger" class="com.djn.springaop.Logger"></bean>
<!--配置AOP-->
<aop:config>
<!--通用切入点表达式:
id是表达式的表示标示
expression是表达式
必须配置在上面,使用pointcut-ref引用
* com.djn.springaop.*.*(..)
表示com.djn.springaop包下的所有类的所有方法;(..)表示所有的方法不管有没有参数都会执行,如果需要指定需要指定参数类型
-->
<aop:pointcut id="pt1" expression="execution(* com.djn.springaop.*.*(..))"></aop:pointcut>
<!--配置切面-->
<aop:aspect id="logAdvice" ref="logger">
<!--配置通知类型 以及将通知方法和切入点方法关联-->
<!--前置通知 切入点方法之前执行-->
<aop:before method="beforePrint" pointcut-ref="pt1"></aop:before>
<!--后置通知 切入点方法正常执行后执行,和异常通知只有一个会被执行-->
<aop:after-returning method="afterReturningPrint" pointcut-ref="pt1"></aop:after-returning>
<!--异常通知 切入点方法正常执行抛异常后执行,和后置通知只有一个会被执行-->
<aop:after-throwing method="afterThrowingPrint" pointcut-ref="pt1"></aop:after-throwing>
<!--最终通知 切入点方法无执行结束后执行 一定会被执行-->
<aop:after method="afterPrint" pointcut="execution(* com.djn.springaop.*.*(..))"></aop:after>
<!--环绕通知 需要明确指出切入点-->
<aop:around method="aroundPrint" pointcut-ref="pt1"></aop:around>
</aop:aspect>
</aop:config>
2.环绕通知
/**
* 环绕通知
* 问题:当配置了环绕通知后,切入点方法不执行,而只有通知方法执行了
* 原因:环绕通知需要配置明确的切入点
* 解决:Spring框架提供了ProceedingJoinPoint,该接口又一个方法proceed,就是指定明确的切入点
* 其实环绕通知就是让我们可以手动指定通知方法何时执行
*/
public static Object aroundPrint(ProceedingJoinPoint pdj) {
Object value = null;
try {
System.out.println("前置通知Logger的afterPrint开始记录日志了...");
Object[] args = pdj.getArgs();
value = pdj.proceed(args);
System.out.println("后置通知Logger的afterPrint开始记录日志了...");
return value;
} catch (Throwable throwable) {
System.out.println("异常通知Logger的afterPrint开始记录日志了...");
throw new RuntimeException(throwable);
} finally {
System.out.println("最终通知Logger的afterPrint开始记录日志了...");
}
}
⚠️:除了环绕通知其他四个通知顺序可能会打乱,所以建议还是使用环绕通知!!!!!!!!!
基于注解AOP
1.配置步骤
1.@Component
作用:将切面类存入Spring容器
2.@Aspect
作用:配置AOP
3.@EnableAspectJAutoProxy
作用:开启AOP
等同于在xml中 <aop:aspectj-autoproxy/>
3.@Before @AfterReturning @AfterThrowing @After @Around
作用:通知类型
属性:
value:切入点表达式
4.@Pointcut
作用:通用切入点表达式
5.在xml中扫描包 <context:component-scan/>
@Component("logger")
@Aspect
@EnableAspectJAutoProxy
public class LoggerAnnotation {
@Pointcut("execution(* com.djn.springaop.*.*(..))")
private void pt(){}
@Before("pt()")
public static void beforePrint() {
System.out.println("前置通知Logger的beforePrint开始记录日志了...");
}
@AfterReturning("pt()")
public static void afterReturningPrint() {
System.out.println("后置通知Logger的afterPrint开始记录日志了...");
}
@AfterThrowing("pt()")
public static void afterThrowingPrint() {
System.out.println("异常通知Logger的afterReturningPrint开始记录日志了...");
}
@After("pt()")
public static void afterPrint() {
System.out.println("最终通知Logger的afterPrint开始记录日志了...");
}
/**
* 环绕通知
* 问题:当配置了环绕通知后,切入点方法不执行,而只有通知方法执行了
* 原因:环绕通知需要配置明确的切入点
* 解决:Spring框架提供了ProceedingJoinPoint,该接口又一个方法proceed,就是指定明确的切入点
*/
@Around("pt()")
public static Object aroundPrint(ProceedingJoinPoint pdj) {
Object value = null;
try {
System.out.println("前置通知开始记录日志了...");
Object[] args = pdj.getArgs();
value = pdj.proceed(args);
System.out.println("后置通知开始记录日志了...");
return value;
} catch (Throwable throwable) {
System.out.println("异常通知开始记录日志了...");
throw new RuntimeException(throwable);
} finally {
System.out.println("最终通知开始记录日志了...");
}
}
}
声明式事务
基于XML的事务
1.配置事务管理器
2.配置事务通知
3.配置AOP
4.配置通用表达式
5.将通知方法与切入点方法关联
6.配置事务的属性
<?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/tx
http://www.springframework.org/schema/tx/spring-tx.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">
<!--配置Spring创建容器时要扫描的包 注解扫描-->
<context:component-scan base-package="com.djn.transaction"></context:component-scan>
<!--开启AOP-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!--配置JDBC-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/localtest"></property>
<property name="username" value="root"></property>
<property name="password" value="mysql04141015"></property>
</bean>
<!--配置事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置事务的通知-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!--配置事务的属性
isolation:用于指定事务的隔离级别,默认是DEFAULT,表示使用数据库默认的隔离级别
propagation:用于指定事务的传播行为
默认是REQUIRED,表示一定会有事务,增删改选择它
SUPPORTS,表示有事务就用,没有就拉到,查找选择它
read-only:表示是否只读,只有查询方法才能设置为true,默认是false,表示读写
timeout:事务的超时时间,默认-1,表示永不超时,以秒为单位
roback-for:指定一个异常,只有出现该异常事务才回滚,其他异常不回滚
noroback-for:与roback-for相反,指定一个异常,只有出现该异常不回滚,其他异常才回滚
-->
<tx:attributes>
<tx:method name="transfer" propagation="REQUIRED" isolation="REPEATABLE_READ" read-only="false"/>
<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
<!--配置AOP-->
<aop:config>
<!--通用表达式-->
<aop:pointcut id="pt1" expression="execution(* com.djn.transaction.*.*(..))"></aop:pointcut>
<!--建立事务通知和切入点的关联-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"></aop:advisor>
</aop:config>
</beans>
基于注解的事务
1.配置事务管理器
2.开启Spring对事务注解的支持
3.在需要开启事务的类上或者方法上添加@Transactionl注解
<?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/tx
http://www.springframework.org/schema/tx/spring-tx.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">
<!--配置Spring创建容器时要扫描的包 注解扫描-->
<context:component-scan base-package="com.djn.transaction"></context:component-scan>
<!--开启AOP-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!--配置JDBC-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/localtest"></property>
<property name="username" value="root"></property>
<property name="password" value="mysql04141015"></property>
</bean>
<!--配置事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--开启spring对事务注解的支持-->
<tx:annotation-driven transaction-manager="txManager"></tx:annotation-driven>
</beans>
整合Mybatis
Mybatis-spring 可以将mybatis代码无缝的整合到spring中,它将允许 MyBatis 参与到 Spring 的事务管理之中,创建映射器 mapper 和
SqlSession并注入到 bean 中
第一种方式
对于Mapper需要有一个实现类,然后注入SqlSession操作,并且将实现类注入到Spring容器中
1.导入jar包
<!--spring核心-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<!--数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!--测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--aopzhi ru织入-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<!--spring和mybatis整合 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<!--2.0+版本需要mybatis在3.5+ spring在5.0+-->
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
</dependency>
2.配置dataSource和SqlsessionFactory
<!--dataSource 使用Spring的数据源替换Mybatis的配置-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/localtest"></property>
<property name="username" value="root"></property>
<property name="password" value="mysql04141015"></property>
</bean>
<!--SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--mybatis的配置文件 虽然也可以在spring配置中实现-->
<property name="configLocation" value="mybatis-config.xml"></property>
</bean>
3.创建sqlsession
不需要再直接使用sqlSessionFactory来创建sqlsession了,SqlSessionTemplate是sqlsession的一个实现类,他可以无缝代替sqlsession,它是线程安全的,可以被多个DAO和映射器使用
<!--创建sqlSession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg>
</bean>
4.在实现类中注入sqlsession,并且将实现类注入到Spring容器
public class StudentMapperImpl implements StudentMapper {
private SqlSession sqlSession;
public void setSqlSession(SqlSession sqlSession) {
this.sqlSession = sqlSession;
}
public List<Student> findAll() {
return sqlSession.getMapper(StudentMapper.class).findAll();
}
}
<bean id="studentMapper" class="com.djn.springmybatis.mapper.StudentMapperImpl">
<property name="sqlSession" ref="sqlSession"></property>
</bean>
5.开始调用
public class UserMapperTest {
@Test
public void findAll() throws IOException {
//读取配置文件 创建spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("spring-beans.xml");
//获取实现类
StudentMapper studentMapper = (StudentMapper) context.getBean("studentMapper");
List<Student> studentList = studentMapper.findAll();
for (Student student : studentList) {
System.out.println(student);
}
}
}
第二种方式
不需要在spring.xml注入sqlSession,而是通过继承SqlSessionDaoSupport,直接getSession()获取Sqlsession,同样需要将实现类注入到Spring容器中
public class StudentMapperImpl extends SqlSessionDaoSupport implements StudentMapper {
public List<Student> findAll() {
return getSqlSession().getMapper(StudentMapper.class).findAll();
}
}
2.在spring.xml配置 需要注入sqlSessionFactory
<bean id="studentMapper" class="com.djn.springmybatis.mapper.StudentMapperImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
第三种方式(常用)
不需要一个Mapper的实现类,也不需要继承SqlSessionDaoSupport,而是配置dao接口的扫描,动态的实现dao接口可以注入到Mapper容器中
<!--5.扫描dao接口,动态注入到容器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--要扫描的dao包-->
<property name="basePackage" value="com.djn.dao"/>
<!--注入sqlSessionFactory-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>

浙公网安备 33010602011771号