學習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的簡單配置
- 别名 **既可以使用别名擷取對象,也可以使用原來的**
- bean 的簡單配置
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);
}