学习Spring框架的简单使用
官方文档:https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#spring-core
中文文档:https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference
- Spring框架的重点是Spring容器,将所有对象注册到容器中,需要用的时候再取
- 将原来需要new 的对象,直接在配置文件中注册,如果需要修改,就直接修改配置文件,而不需要修改程序,实现解耦
- 在配置文件中每一个对象,就是一个bean
- 配置文件application-config.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">
<bean id="对象的标识" class="对象的完全限定的类名">
<!-- 内部的参数(属性的设置),实际上采用的是set方法进行设置属性 -->
<!-- ref标识引用类型 value表示基本类型和String类型 -->
<property name="daouse" ref="daoimpl3"/>
</bean>
</beans>
1. IOC(控制反转)
- 不是什么技术,而是一种设计思想
- Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制(new),实现解耦
- 简单使用,需要导入Spring的 maven依赖(maven会进行依赖导入,直接导入最大的就行)
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.18.RELEASE</version>
</dependency>
</dependencies>
<bean id="daoimpl" class="com.xxx.dao.daoimpl"/>
<bean id="daoimpl2" class="com.xxx.dao.daoimpl2"/>
<bean id="daoimpl3" class="com.xxx.dao.daoimpl3"/>
<bean id="serviceimpl" class="com.xxx.service.serviceimpl">
<!-- 这里可以修改ref的引用,就能修改程序的对象 -->
<property name="daouse" ref="daoimpl2"/>
</bean>
- 使用时需要读取主配置文件,获取想要的对象
// 加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
// 在容器中获取id为serviceimpl的对象
serviceimpl simpl= (serviceimpl) context.getBean("serviceimpl");
simpl.show();
2. spring创建对象的方式(默认是单例,获取的是同一个对象)
- 默认使用无参构造创建对象,
- 使用有参构造创建对象的几种形式
- 根据类型传参 如果类型相同则按顺序赋值
<bean id="u2" class="com.xxx.pojo.User">
<constructor-arg type="java.lang.String" value="xx1"/>
<constructor-arg type="java.lang.String" value="1xx"/>
</bean>
- 根据索引传参(从0开始)
<bean id="u2" class="com.xxx.pojo.User">
<constructor-arg index="0" value="xx1"/>
<constructor-arg index="1" value="1xx"/>
</bean>
- 根据参数名称传参
<bean id="u2" class="com.xxx.pojo.User">
<constructor-arg name="add" value="xx1"/>
<constructor-arg name="name" value="1xx"/>
</bean>
3. spring的简单配置
- 别名 **既可以使用别名获取对象,也可以使用原来的**
<alias name="u1" alias="uuu"/>
- bean 的简单配置
<bean id="u1" class="com.xxx.pojo.User" name="可以取多个别名,用,/;/空格分隔" scope="作用范围常用的是singleton(单例,是同一个对象)/prototype(每次都会创建对象)">
scope官方介绍:
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-scopes
- import 导入xml 进行合并
<import resource="bean1.xml"/>
<import resource="bean2.xml"/>
4. 依赖注入(DI)通过set 和 P命名空间(相当于set)和C命名空间(构造器)
- 复杂属性的注入(普通类型/String,null值,对象,数组,list,map,set,properties)
<bean id="" class="">
<property name="基本类型和String" value="值"/>
<property name="String">
<null/>
</property>
<property name="对象类型" ref="引用别的Bean"/>
<property name="数组类型属性名">
<array>
<value>值1</value>
<value>值2</value>
<value>值3</value>
</array>
</property>
<property name="list列表">
<list>
<value>值1</value>
<value>值2</value>
<value>值3</value>
</list>
</property>
<property name="map类型">
<map>
<entry key="键1" value="值1"/>
<entry key="键2" value="值2"/>
</map>
</property>
<property name="set类型">
<set>
<value>值1</value>
<value>值2</value>
</set>
</property>
<property name="properties类型">
<props>
<prop key="键1">值1</prop>
<prop key="键2">值2</prop>
</props>
</property>
</bean>
p命名空间 在xml 中需要配置xml约束,才能使用
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 简化了<property name="" value=""> -->
<bean id="" class="" p:属性="value值" p:属性-ref="引用类型"/>
c命名空间 在xml 中需要配置xml约束,才能使用
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<!-- 简化了<constructor-arg name="" value=""> -->
<bean id="" class="" c:属性="value值" c:属性-ref="引用类型"/>
5. 在<bean autowire="">中设置自动装配
- autowire=“byName” :根据名字自动装配,但是需要beanid和set方法后面的属性相同
- autowire=“byType” : 根据类型自动装配,但是需要确保类型唯一,且和set方法的类型一致
6. 使用注解实现 自动装配(jdk1.9好像不支持@Resource)
- JDK1.9 使用@Resource 需要导入maven依赖
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-annotations-api</artifactId>
<version>9.0.13</version>
</dependency>
- 需要使用注解的约束
<?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/>
</beans>
- 使用固定的一句,支持注解
context:annotation-config/ - 使用**@Autowired,@Qualifier,@Resource**
// 默认先按ByType进行匹配,如果太多,则按ByName进行匹配,找id为cat2的
@Autowired
private Cat cat2;
// 默认required为true,在容器中找不到就报错,选择false则找不到不注入,但是使用时该对象是null
@Autowired(required = false)
private Cat cat2;
// 搭配 @Qualifier 可以指定查找id为cac的
@Autowired
@Qualifier("cac")
private Cat cat2;
// 默认先按ByName进行匹配,找id为dog2的,如果不匹配,则按ByType进行匹配,再不匹配就为null
@Resource
private Dog dog2;
7. 其他重要注解(注册bean的,代替配置文件的。。)
- 产生Bean的注解,等价于
**需要扫描包,进行使用注解对bean在spring容器中进行注册 **
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns: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/>
<!-- 扫描包,对使用注解的进行注册到容器中 等价于多个<bean ....> -->
<context:component-scan base-package="com.xxx.pojo"/>
</beans>
这4个注解作用一样,都能在spring容器中注册bean,
- @Component 加在类上,产生bean 默认id为类名首字母小写
- @Repository
- @Service
- @Controller
- 普通属性的注入 @Value 能作用在属性上也能作用在set方法上
@Value("xxx")
private String name;
@Value("xxx")
public void setName(String name) {
this.name = name;
}
- 可以完全不用xml文件,使用配置类实现
@Configuration // 表示该类是配置类,
@ComponentScan("com.xxx.pojo") // 扫描包,注册bean,相当于<context:component-scan base-package="com.xxx.pojo"/>
@Import({xxx.class,ccc.class}) // 导入别的配置类,进行合并 相当于 <import resource=""/>
public class MyConfig {
@Bean // 注册bean(一般用于非自己创建的类),默认的bean的id是方法名
public User u(){
System.out.println(123);
return new User();
}
}
@Component("u") // 注册id为u的bean 且是单例的
@Scope("singleton") // 单例模式
//@Scope("prototype") // 每次都会创建一个新的对象
public class User {
public User() {
System.out.println(111);
}
@Value("xsw") // 普通属性注入
private String name;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
// 使用注解读取配置的类
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User getuser = (User) context.getBean("u");
System.out.println(getuser);
8. aop(切面编程)
- 代理模式:静态代理模式
public class Real implements CommomInterface{
public void show(){
System.out.println("真实对象的业务功能");
}
}
public class StaticProxy implements CommomInterface{
private Real real; // 真实对象 也实现了CommomInterface接口
public void setReal(Real real){ // 注入真实对象
this.real = real;
}
// 公共业务接口
public void show(){
System.out.println("代理做的额外的事情,如日志输出。。");
real.show(); // 代理对象的show方法
}
}
// 使用时
Real real = new Real(); // 创建真实对象
StaticProxy sp = new StaticProxy(); // 创建代理对象
sp.setReal(real); // 将真实对象传给代理对象
sp.show(); // 此时代理对象 既能实现真实对象的方法也能实现额外的功能
- 动态代理模式(有基于类的和基于接口的)
基于接口的实现
- 第一步写公共接口
- 第二步写真实对象
- 第三步写调用处理器(传入真实对象,为真实对象的方法添加功能),这里实现之前静态代理的公共方法部分(实现接口InvocationHandler)
- 第四步依靠调用处理器,生成动态代理类(通过Proxy动态生成)
- 执行真实对象的方法,会增加在调用处理器增加的功能
// 1. 公共接口
public interface Inter {
void show();
void find();
}
// 2.真实对象的类实现公共接口
public class web implements Inter {
public void show() {
System.out.println("web show");
}
public void find() {
System.out.println("web find");
}
}
// 3. 实现调用处理器接口 InvocationHandler
public class proxyjdk implements InvocationHandler {
// 真实对象
private Object obj;
// 使用有参构造 传入真实对象,即被代理对象
public proxyjdk(Object obj){
this.obj=obj;
}
// 动态实现代理方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("====== in proxy ======");
// method 为调用什么方法 method就是什么 args 表示该方法的参数
// 本质利用反射
result = method.invoke(obj,args);
return result;
}
}
// 测试
public static void main(String[] args) {
// 生成被代理类
Inter web = new web();
// 调用处理器,传入被代理对象
proxyjdk pj = new proxyjdk(web);
// 4. 动态生成代理类实例对象(前两个参数固定,一个类加载器,一个真实对象的接口对象 只有最后一个参数不同,需要传入真实对象的处理器)
Inter it = (Inter) Proxy.newProxyInstance(web.getClass().getClassLoader(), web.getClass().getInterfaces(), pj);
it.find();
System.out.println("=================");
it.show();
}
// 结果
====== in proxy ======
web find
=================
====== in proxy ======
web show
9. AOP实现动态代理(注意使用接口来接收生成的动态代理类)
- 增强类实现对应的接口,重写该方法
public class afterLog implements AfterReturningAdvice {
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println(method.getName()+"方法执行了,返回值为: "+ o);
}
}
/*
void afterReturning(@Nullable
Object returnValue,
Method method,
Object[] args,
@Nullable
Object target)
throws Throwable
*/
<bean id="po" class="com.xxx.pojo"/>
<bean id="log" class="com.xxx.afterLog"/>
<!-- execution()表达式 返回值类型 包名.类名.方法名(参数类型) * 表示任意类型 ..表示参数任意个 -->
<aop:config>
<aop:pointcut id="point" expression="execution(* com.xxx.pojo.*(..))"/>
<aop:advisor advice-ref="log" pointcut-ref="point"/>
</aop:config>
- 写普通类,使用切面定义
public class strong {
public void beforeStrong(){
System.out.println("before");
}
public void afterStrong(){
System.out.println("after");
}
public void afterreturnStrong(){
System.out.println("afterreturn");
}
// 环绕方法比较特殊 , 需要传入切点的对象, pj.proceed() 表示原方法的执行,并得到返回结果
public Object around(ProceedingJoinPoint pj) throws Throwable {
System.out.println("around");
int proceed = (Integer)pj.proceed();
return proceed;
}
}
<bean id="po" class="com.xxx.pojo"/>
<bean id="str" class="com.xxx.strong"/>
<aop:config>
<!-- 定义切面 (对象) -->
<aop:aspect ref="str">
<!-- 定义切点 -->
<aop:pointcut id="pointcut" expression="execution(* com.xxx.pojo.*(..))"/>
<!-- 对切面的方法进行设置 前置增强 后置增强 after after-returning的执行顺序与配置的顺序有关 等等 -->
<aop:before method="beforeStrong" pointcut-ref="pointcut"/>
<aop:after method="afterStrong" pointcut-ref="pointcut"/>
<aop:after-returning method="afterreturnStrong" pointcut-ref="pointcut"/>
<aop:around method="around" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
- 注解实现**(需要注解支持)** 需要将切面类在spring容器中注册为Bean对象
<!-- 注解支持 -->
<aop:aspectj-autoproxy/>
// 表示这是一个切面类
@Aspect
public class strong {
@Before("execution(* com.xxx.pojo.*(..))")
public void beforeStrong(){
System.out.println("before");
}
@After("execution(* com.xxx.pojo.*(..))")
public void afterStrong(){
System.out.println("after");
}
//(after-returning先执行 after后执行)
@AfterReturning("execution(* com.xxx.pojo.*(..))")
public void afterreturnStrong(){
System.out.println("afterreturn");
}
@Around("execution(* com.xxx.pojo.*(..))")
public Object around(ProceedingJoinPoint pj) throws Throwable {
System.out.println("around");
int proceed = (Integer)pj.proceed(); // 执行真实对象的方法
return proceed; // 返回真实对象的执行结果
}
}
10. 整合Mybatis-spring
mybatis-spring文档: http://mybatis.org/spring/zh/index.html
- 需要导入的jar包:
数据库mysql驱动包,spring的包,mybatis的包,mybatis-spring的包,asj动态代理织入包,spring-jdbc操作数据库的包
<dependencies>
<!-- 导入spring核心包(maven会依赖导入,直接导入最大的) -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.18.RELEASE</version>
</dependency>
<!--jdk1.9 的@Resource 注解支持-->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-annotations-api</artifactId>
<version>9.0.13</version>
</dependency>
<!--mysql驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--mybatis的包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.0</version>
</dependency>
<!--spring操作数据库的包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
<!--mybatis和spring整合的包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.3</version>
</dependency>
<!-- aspectJ AOP 织入器 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.6</version>
</dependency>
</dependencies>
2. 先测试使用Mybatis
<!-- 主配置文件 -->
<?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.xxx.pojo"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 注册映射器 -->
<mappers>
<mapper resource="userMapper.xml"/>
</mappers>
</configuration>
<!-- 映射器配置文件 -->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxx.mapper.UserMapper">
<select id="selectAll" resultType="user">
select * from user
</select>
</mapper>
// 映射器对应的接口
public interface UserMapper {
List<User> selectAll();
}
// pojo实体类
public class User {
private int id;
private String name;
private String address;
}
// 测试代码
public static void main(String[] args) throws IOException {
// 读取Mybatis的主配置文件, 最后得到 sqlSession 数据库连接对象
InputStream ris = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(ris);
SqlSession sqlSession = build.openSession();
// 指定映射器的接口,执行对应的方法
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.selectAll();
for (User user : users) {
System.out.println(user);
}
}
- 第一步整合(省略sqlsessionFactory,sqlsession的创建,直接在容器中)
官网实例:http://mybatis.org/spring/zh/factorybean.html
3.1 第一步,先创建数据源对象(这里使用spring的)
3.2 第二步,创建sqlsessionFactory对象,传入数据源(必须要),可以设置别的(抛弃配置文件)或者导入配置文件
3.3 第三步,根据sqlsessionFactory对象,创建SqlSessionTemplate的对象(本质是sqlsession) 只能使用构造器注入
3.4 第四部, 就和使用Mybatis相似,获取mapper对象
<!-- spring 主配置文件 -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns: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
">
<!-- 1.数据源,使用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/smbms?useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!-- 2.生成sqlsessionFactory对象 -->
<bean id="sqlsessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="datasource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!-- 3.生成sqlsessinTemplent对象 即本质上是sqlsession对象 -->
<bean id="sqlsession" class="org.mybatis.spring.SqlSessionTemplate">
<!-- 只能通过构造器注入 -->
<constructor-arg index="0" ref="sqlsessionFactory"/>
</bean>
</beans>
<!-- mybatis的配置文件(其实可以全部在spring中设置) -->
<?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.xxx.pojo"/>
</typeAliases>
<mappers>
<mapper resource="userMapper.xml"/>
</mappers>
</configuration>
<!-- 映射器文件 -->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxx.mapper.UserMapper">
<select id="selectAll" resultType="user">
select * from user
</select>
</mapper>
// 测试代码
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
SqlSessionTemplate sqlsession = (SqlSessionTemplate) context.getBean("sqlsession");
UserMapper mapper = sqlsession.getMapper(UserMapper.class);
List<User> users = mapper.selectAll();
for (User user : users) {
System.out.println(user);
}
- 使用接口的实现类丢到spring容器中,注入SqlSessionTemplate对象
<bean id="rere" class="com.xxx.mapper.aabbcc">
<property name="sqlSession" ref="sqlsession"/>
</bean>
public class aabbcc implements UserMapper {
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession){
this.sqlSession = sqlSession;
}
public List<User> selectAll(){
return sqlSession.getMapper(UserMapper.class).selectAll();
}
}
// 测试
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
aabbccabc = (aabbcc) context.getBean("rere");
List<User> users = abc.selectAll();
for (User user : users) {
System.out.println(user);
}
- 使用接口自动生成映射器对象**(导入对应的约束)**
https://www.cnblogs.com/likeju/p/5323705.html
<?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:mybatis="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd
">
<!-- 配置自动扫描注解,base-package 扫描的包 mybatis:scan 需要容器中有sqlsessionFactory或者sqlsessionTemplate对象 -->
<mybatis:scan base-package="com.xxx.mapper"/>
<!-- 这两种自动扫描接口 动态生成实现类 效果相同 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.inter"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
// 通过上面的自动扫描 将接口注册到spring中,动态生成映射器类
// 默认名字为首字母小写的类名,可以通过类型查找getBean(UserMappper.class)
public interface UserMapper {
List<User> selectAll(User user);
int addUser(User user);
int deleteUser(int id);
}
// 测试代码
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper bean = context.getBean(UserMapper.class);
// UserMapper bean = context.getBean("userMapper");
List<User> users = bean.selectAll(new User());
for (User user : users) {
System.out.println(user);
}
11. 事务
http://mybatis.org/spring/zh/transactions.html
- 使用事务需要在spring的xml文件中加入tx约束
- 步骤1:要开启 Spring 的事务处理功能,在 Spring 的配置文件中创建一个 DataSourceTransactionManager 对象:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="datasource" ref="dataSource"/>
</bean>
- 步骤2 : 使用AOP实现动态添加事务
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"/>
</bean>
<!-- 配置事务通知,结合AOP -->
<tx:advice id="txadvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 为不同的方法设置不同的事务属性 -->
<tx:method name="add*" propagation="REQUIRED"/>
<!--<tx:method name="select*" read-only="true"/>-->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 配置事务织入 -->
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.xxx.mapper.*.*(..))"/>
<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut"/>
</aop:config>
public class aabbcc implements UserMapper {
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession){
this.sqlSession = sqlSession;
}
public List<User> selectAll(User user){
addUser(user);
deleteUser(8);
return sqlSession.getMapper(UserMapper.class).selectAll(user);
}
public int addUser(User user) {
return sqlSession.getMapper(UserMapper.class).addUser(user);
}
public int deleteUser(int id) {
return sqlSession.getMapper(UserMapper.class).deleteUser(id);
}
}
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper abc = (UserMapper) context.getBean("rere"); // 需要使用接口来接收,因为生成了动态代理类
List<User> users = abc.selectAll(new User(0,"aaa","eeeee"));
for (User user : users) {
System.out.println(user);
}