SSM第二季-Spring(个人笔记)

6 篇文章 0 订阅

SSM-Spring

Spring-Ico|DI概念介绍

注意bean包下的对象如果你添加上了有参构造器那就必须加上空参构造器,如果没有加上有参构造器的话,空参构造器添不添加随意,主要是spring创建对象时使用的是空参构造器

//IOC的反转:创建对象这份工作由我们自己执行反转给spring帮我们执行
	//IOC的控制:就是由spring帮我们负责创建销毁对象,掌握对象的生命周期等,我们在需要使用对象的时候跟spring申请即可
	//IOC是一种编程思想,也是一种新的设计理念
	@Test
	public void Test2() {
		//通过spring配置文件获取容器对象
		//applicationContext配置的所有bean都會在容器创建的时候被创建出来(使用空参构造器)
		//若配置的bean较多,那么在创建容器的时候,会产生内存过大的问题,此问题在机器硬件落后的时候体现明显
		/*
		 * 延迟加载 为true就是创建容器时不加载配置的bean对象,在获取的时候才创建
		 */
		ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");

		//User u = (User)ac.getBean("user");
		User u=ac.getBean(User.class);//传递字节码类型  不需要强转了
		System.out.println(u);
	}

bean属性讲解

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns="http://www.springframework.org/schema/beans" 
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">

	<!-- name是一个名字  我们可以通过name来利用容器获取对象
		name可以使用特殊字符  可以重复
		我们在实际开发中不推荐将多个对象名字命名为重复的-->
	 	<!--id与name作用基本相同,但不推荐使用 ,id不支持特殊字符 不能重复 -->
	 <!-- class:被管理对象的全包名,spring会通过这个包名来创建对象 -->
	 <!-- scope Ⅰ singleton  Ⅱ prototype 单例与多例    
	 		Ⅲ request 在web环境下,如果scope属性为request那么这个对象被创建出来 他的生命周期会与request请求一致
	 		Ⅳ session 同理  生命周期与session一致 -->
	 <!--  -->
	<bean name="user" class="com.sikiedu.bean.User" scope="singleton" init-method="userInit" destroy-method="userDestory">
		<property name="u_id" value="2"></property><!-- 依赖注入 -->
	</bean>
</beans>

HelloSpring.java

// 单例 只创建一个对象    一般项目中使用singleton
	@Test
	public void Test3() {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		// scope = "singleton" 默认值 单例的
		User u1 = ac.getBean(User.class);
		User u2 = ac.getBean(User.class);
		System.out.println(u1 == u2);// true
	}

	//多例 在获取的时候创建新的对象  特殊环境下改为prototype 比如项目中使用struts就要使用多例
	@Test
	public void Test4() {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		// scope = "prototype" 
		User u1 = ac.getBean(User.class);
		User u2 = ac.getBean(User.class);
		System.out.println(u1 == u2);// false
		
	}
	
	//init-method 与destroy-method
	@Test
	public void Test5() {
		ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		// scope = "prototype" 默认值 单例的
		User u1 = ac.getBean(User.class);
		User u2 = ac.getBean(User.class);
		System.out.println(u1 == u2);// false
		
		//如果设置scope = "prototype"  那么就不会触发销毁函数
		//想要触发销毁函数 需设置scope = "singleton"
		//关闭容器 触发bean的destroy-method
		ac.close();
	}

属性注入

Pet.java

package com.sikiedu.bean;

public class Pet {
	
	//宠物类型 猫 狗
	private String petType;
	private String color;
	public String getPetType() {
		return petType;
	}
	public void setPetType(String petType) {
		this.petType = petType;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	@Override
	public String toString() {
		return "Pet [petType=" + petType + ", color=" + color + "]";
	}
	
}

User.java

package com.sikiedu.bean;

public class User {
	private Integer u_id;
	private String u_username;
	private String u_password;
	
	//加入宠物字段
	private Pet u_pet;

	public User(String u_username,Pet u_pet) {
		System.out.println("方法1:String,Pet");
		this.u_username = u_username;
		this.u_pet = u_pet;
	}
	
	public User(Integer u_username,Pet u_pet) {
		System.out.println("方法2:Integer,Pet");
		this.u_username = u_username.toString();
		this.u_pet = u_pet;
	}
	public User(Pet u_pet,Integer u_username) {
		System.out.println("方法3:Pet,Integer");
		this.u_username = u_username.toString();
		this.u_pet = u_pet;
	}
	//spring创建对象是通过空参构造执行的  空参构造方法必须加上,因为重写了有参构造方法
	public User() {
		super();
		System.out.println("空参");
	}
	public Integer getU_id() {
		return u_id;
	}
	public Pet getU_pet() {
		return u_pet;
	}
	public void setU_pet(Pet u_pet) {
		this.u_pet = u_pet;
	}
	public void setU_id(Integer u_id) {
		this.u_id = u_id;
	}
	public String getU_username() {
		return u_username;
	}
	public void setU_username(String u_username) {
		this.u_username = u_username;
	}
	public String getU_password() {
		return u_password;
	}
	public void setU_password(String u_password) {
		this.u_password = u_password;
	}
	
	public void userInit() {
		System.out.println("userInit");
	}
	public void userDestory() {
		System.out.println("userDestory");
	}
	@Override
	public String toString() {
		return "User [u_id=" + u_id + ", u_username=" + u_username + ", u_password=" + u_password + ", u_pet=" + u_pet
				+ "]";
	}
	
}

set方法注入

<bean name="user" class="com.sikiedu.bean.User" scope="singleton" init-method="userInit" destroy-method="userDestory">
		<property name="u_id" value="2"/>
		<property name="u_username" value="雪风"/><!-- set方法注入值类型 -->
		<property name="u_password" value="123"/>
		<property name="u_pet" ref="dog"/>
	</bean>
	
	<!-- 注入引用类型 -->
	<bean name="dog" class="com.sikiedu.bean.Pet">
		<property name="petType" value="二哈"/>
		<property name="color"  value="灰白色"/>
	</bean>
//set方法注入
	@Test
	public void Test6() {
		ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		User u1=ac.getBean(User.class);
		System.out.println(u1);
	}

构造方法注入

<!-- 构造方法注入   如果出现多个构造方法重载,可以使用type index指定符合——位于index位置参数类型type的构造方法-->
	<!-- name调用构造方法的参数名称  value是注入值类型  type是指定参数的类型  index是指定type参数的位置-->
	<bean name="user1" class="com.sikiedu.bean.User">
		<constructor-arg name="u_username" value="66" type="java.lang.Integer" index="0"/> <!--此时这个bean指定的就是方法3-->
		<constructor-arg name="u_pet" ref="dog"/>
	</bean>
//构造方法注入
	@Test
	public void Test7() {
		ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		User u1=(User)ac.getBean("user1");
		System.out.println(u1);
	}

复杂类型注入

Array、List、Set、Map、Properties

<!-- 复杂类型注入 -->
	<bean name="collection" class="com.sikiedu.bean.MyCollection">
		
		<!-- array一个值使用方法 -->
<!-- 		<property name="array" value="123"></property> -->
		
		<!-- array 多个值使用方法-->
		<property name="array">
			<array>
				<value>123</value>
				<value>abc</value>
				<ref bean="dog"/>
			</array>
		</property>
		
		<!-- list -->
		<property name="list">
			<list>
				<value>456</value>
				<value>cas</value>
				<ref bean="user1"/>
			</list>
		</property>
		
		<!-- set -->
		<property name="set">
			<set>
				<value>782</value>
				<value>www</value>
				<ref bean="user1"/>
			</set>
		</property>
		
		<!-- map -->
		<property name="map">
			<map>
				<entry key="username" value="login"/>
				<entry key="password" value="123"/>
				<entry key-ref="user1" value-ref="dog"/>
			</map>
		</property>
		
		<!-- peopertis -->
		<property name="prop">
			<props>
				<prop key="name">雪风</prop>
				<prop key="age">12</prop>
			</props>
		</property>
	</bean>

注解配置

将对象注册到容器中

applicationContext_annotation.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" 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-4.3.xsd">
	<!-- 注解开发 -->
	<!-- 开启组件扫描  base-package扫描该包下以及子包所有的注解-->
	<context:component-scan base-package="com.sikiedu.bean"></context:component-scan>
	
	<!-- 将pet对象交给spring容器管理 -->
	<bean name="dog" class="com.sikiedu.bean.Pet">
		<property name="petType" value="二哈"/>
		<property name="color" value="灰白"/>
	</bean>
</beans>

com.sikiedu.bean下的User2.java

package com.sikiedu.bean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

//<bean name="user" class="com.sikiedu.bean.User">
/*将对象注册到容器*/
@Component("user")
//@Controller()		//对应web层
//@Service("user")			//对应service
//@Repository()		//对应dao层
public class User2 {
	
	@Value(value="1")
	private Integer u_id;	//使用暴力反射去注入的 所以推荐在set方法上注入
	private String u_username;
	private String u_password;

	//加入宠物字段
	private Pet u_pet;
	
	public Pet getU_pet() {
		return u_pet;
	}
	
	//自动装配
	//@Autowired
	//手动指定
	@Resource(name="dog")
	public void setU_pet(Pet u_pet) {
		this.u_pet = u_pet;
	}
	public User2() {
		System.out.println("User2 对象空参构造方法");
	}
	public Integer getU_id() {
		return u_id;
	}
	public void setU_id(Integer u_id) {
		this.u_id = u_id;
	}
	public String getU_username() {
		return u_username;
	}
	
	@Value("雪风")	//推荐在set方法上注入
	public void setU_username(String u_username) {
		this.u_username = u_username;
	}
	public String getU_password() {
		return u_password;
	}
	public void setU_password(String u_password) {
		this.u_password = u_password;
	}
	//标识在构造方法后调用
	@PostConstruct()
	public void userInit() {
		System.out.println("user init ");
	}
	
	//标识在销毁方法前调用
	@PreDestroy()
	public void userDestroy() {
		System.out.println("user destroy");
	}
	@Override
	public String toString() {
		return "User [u_id=" + u_id + ", u_username=" + u_username + ", u_password=" + u_password + ", u_pet=" + u_pet
				+ "]";
	}	
}

Spring整合Junit单元测试

package com.sikiedu.test;

import javax.annotation.Resource;

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.sikiedu.bean.Pet;


//使用junit进行测试,帮我们创建容器

@RunWith(SpringJUnit4ClassRunner.class)
//读取配置文件
@ContextConfiguration("classpath:applicationContext.xml")
public class Test_Junit {
	
	@Resource(name="dog")
	private Pet p;
	
	@Test
	public void Test() {
		System.out.println(p);
	}
	
}

使用注解方式可以帮我们处理一些测试方法中重复且冗余的代码

在主配置文件导入其他配置文件

添加如下代码即可

<!-- 导入其他Spring的配置文件 -->
<import resource="/applicationContext_Injection.xml"/>

使用spring来效验用户登陆的案例

导入jar包

c3p0-0.9.5.5.jar
com.springsource.org.apache.commons.logging-1.1.1.jar
commons-dbutils-1.6.jar
mchange-commons-java-0.2.19.jar
mysql-connector-java-8.0.16.jar
spring-beans-5.0.8.RELEASE.jar
spring-context-5.0.8.RELEASE.jar
spring-core-5.0.8.RELEASE.jar
spring-expression-5.0.8.RELEASE.jar
spring-web-5.0.8.RELEASE.jar

com.sikiedu.web下的UserLoginServlet.java

package com.sikiedu.web;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.sikiedu.bean.User;
import com.sikiedu.service.UserService;

/**
 * Servlet implementation class UserLoginServlet
 */
@WebServlet("/userLogin")
public class UserLoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	private UserService us;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 接收表单数据
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		// 封装成user对象
		User u = new User();
		u.setU_password(password);
		u.setU_username(username);

		// 通过容器获取userService  但是这样的作法不好,因为需要多次创建spring容器且没有销毁
//		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//		us = (UserService) ac.getBean("userService");

		// 在web项目中我们只需要一个spring的容器
		// application域
		// ServletContext() 生命周期 随着web项目启动而创建 随着web项目关闭而销毁
		// ServletContextListener 可以通过配置监听器来达到我们的需求,在web项目创建时候创建spring容器,销毁时候关闭spring容器
		WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
		us = (UserService) wac.getBean("userService");
		
		// 调用service方法验证用户
		User loginUser = us.getUserByInfo(u);

		// 根据用户验证结果进行操作
		if (loginUser == null) {
			// 验证失败 转发到login_page.jsp
			request.setAttribute("errorMsg", "用户名或密码错误");
			request.getRequestDispatcher("/login_page.jsp").forward(request, response);
		} else {
			// 验证成功登陆,重定向到index.jsp
			HttpSession session = request.getSession();
			session.setAttribute("user", loginUser);
			response.sendRedirect(request.getContextPath() + "/index.jsp");

		}

	}

	public UserLoginServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

com.sikiedu.service下的UserService.java

package com.sikiedu.service;

import com.sikiedu.bean.User;
import com.sikiedu.dao.UserDao;

public class UserService {
	
	private UserDao ud;
	
	public void setUd(UserDao ud) {
		this.ud = ud;
	}

	public User getUserByInfo(User u) {
		return ud.getUserByInfo(u);
	}

}

com.sikiedu.dao下的UserDao.java

package com.sikiedu.dao;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.sikiedu.bean.User;

public class UserDao {
	
	private ComboPooledDataSource dataSource;
	public void setDataSource(ComboPooledDataSource dataSource) {
		this.dataSource = dataSource;
	}
	//未使用spring时需要在静态代码块里配置dataSource
//	private static ComboPooledDataSource dataSource;
//	static {
//		//链接数据库 使用c3p0
//		try {
//			dataSource = new ComboPooledDataSource();
//			dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
//			dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT");
//			dataSource.setUser("login");
//			dataSource.setPassword("123");
//		}catch (Exception e) {
//			e.printStackTrace();
//		}
//		
//	}

	public User getUserByInfo(User u) {
		//通过数据库获取用户
		try {
			//使用dbutils操作数据库 查询并返回用户对象
			QueryRunner qr = new QueryRunner(dataSource);
			String sql = "select * from user where u_username=? and u_password =?";
			return qr.query(sql, new BeanHandler<User>(User.class), u.getU_username(), u.getU_password());			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
}

com.sikiedu.bean下的User.java

package com.sikiedu.bean;

public class User {
	private Integer u_id;
	private String u_username;
	private String u_password;
	/*各个属性的get和set方法,以及空参和有参构造器*/	
	
}

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns="http://www.springframework.org/schema/beans" 
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">

<!-- 配置dataSource -->
	<bean name="dataSource"
		class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="jdbcUrl"
			value="jdbc:mysql://localhost:3306/spring?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=GMT%2B8"></property>
		<property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
		<property name="user" value="login"></property>
		<property name="password" value="123"></property>
	</bean>
<!-- 配置Dao -->
	<bean name="userDao" class="com.sikiedu.dao.UserDao">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
<!-- 配置service -->
	<bean name="userService" class="com.sikiedu.service.UserService">
		<property name="ud" ref="userDao"></property>
	</bean>
</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>ssm_spring_servlet</display-name>
  <!-- 配置监听器,在web项目启动的时候让spring启动 -->
  <listener>
  	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <!-- 读取spring的配置文件 -->
  <context-param>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>classpath:applicationContext.xml</param-value>
  </context-param>
</web-app>

Spring-aop

Proxy动态代理:被代理的对象必须要实现接口

com.sikiedu.service包
UserService.java接口
package com.sikiedu.service;

public interface UserService {
	//增
	void save();
	
	//删
	void delete();
	
	//改
	void update();
	
	//查
	void find();
	
}
UserServiceImpl.java实现类
package com.sikiedu.service;

public class UserServiceImpl implements UserService {

	@Override
	public void save() {
		System.out.println("save");

	}

	@Override
	public void delete() {
		System.out.println("delete");

	}

	@Override
	public void update() {
		System.out.println("update");

	}

	@Override
	public void find() {
		System.out.println("find");

	}

}
com.sikiedu.test包
AopTest.java
package com.sikiedu.test;

import org.junit.jupiter.api.Test;

import com.sikiedu.service.UserService;
import com.sikiedu.service.UserServiceImpl;

public class AopTest {

	@Test
	public void Test1(){
		UserServiceProxy usProxy = new UserServiceProxy();
		UserService us =new UserServiceImpl();
		UserService us_PowerUp = usProxy.getUserServiceProxy(us);
		us_PowerUp.find();
	}
}

UserServiceProxy.java
package com.sikiedu.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import com.sikiedu.service.UserService;
import com.sikiedu.service.UserServiceImpl;

/**
 * UserService代理类
 * @author 
 *
 */
public class UserServiceProxy {
	public UserService getUserServiceProxy(UserService us) {
		return (UserService) Proxy.newProxyInstance(UserServiceProxy.class.getClassLoader(),
				UserServiceImpl.class.getInterfaces(),
				new InvocationHandler() {
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						//增强代码
						System.out.println("开启事务");
						//调用原始的方法
						Object invoke = method.invoke(us, args);
						//增强代码
						System.out.println("提交/回滚");
						return invoke;
					}
				});
	}
}

控制台输出

开启事务
find
提交/回滚

使用xml文件来配置spring-aop

创建com.sikiedu.aop包下的MyAdvice.java
package com.sikiedu.aop;

import org.aspectj.lang.ProceedingJoinPoint;

/**
 * 自定义通知类
 */
public class MyAdvice {

	//before 前置通知 在目标方法前调用
	public void before() {
		System.out.println("before");
	}
	
	//after 最终通知(后置通知)在目标方法后调用,无论是否出现异常都会执行 finally
	public void after() {
		System.out.println("after");
	}
	
	//afterReturning 成功通知(后置通知)在目标方法执行后,并且执行成功,如果方法出现异常则不调用
	public void afterReturning() {
		System.out.println("afterReturning");
	}
	
	//afterThrowing 异常通知(后置通知)在目标方法执行出现异常的时候才会调用
	public void afterThrowing() {
		System.out.println("afterThrowing");
	}
	
	//around 环绕通知 需要我们手动调用目标方法,并且可以设置通知
	public Object around(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("around before");
		Object proceed = pjp.proceed();
		System.out.println("around after");
		return proceed;
	}
}
在applicationContext.xml文件中添加配置切入点和五种通知
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" 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-4.3.xsd">
	<!-- 目标对象 -->
	<bean name="userService" class="com.sikiedu.service.UserServiceImpl"></bean>

	<!-- 通知对象 -->
	<bean name="myAdvice" class="com.sikiedu.aop.MyAdvice"></bean>

	<aop:config>
		<!-- 切入点 expression 切入点表达式 可以配置要增强的方法 public void com.sikiedu.service.UserServiceImpl.save() * com.sikiedu.service.*ServiceImpl.*(..) id 就是唯一标识 -->
		<aop:pointcut expression="execution(* com.sikiedu.service.*ServiceImpl.*(..))" id="servicePc" />

		<!-- 切面 通知+切入点 -->
		<aop:aspect ref="myAdvice">
			<!-- 通知类型 -->
			<aop:before method="before" pointcut-ref="servicePc" />
			<!-- 最终通知 后置通知 -->
			<aop:after method="after" pointcut-ref="servicePc" />
			<!-- 成功通知 后置通知 -->
			<aop:after-returning method="afterReturning" pointcut-ref="servicePc" />
			<!-- 异常通知 后置通知 -->
			<aop:after-throwing method="afterThrowing" pointcut-ref="servicePc" />
			<!-- 环绕通知 -->
			<aop:around method="around" pointcut-ref="servicePc" />
		</aop:aspect>
	</aop:config>
</beans>
在AopTest.java中添加方法测试
package com.sikiedu.test;

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.sikiedu.service.UserService;
import com.sikiedu.service.UserServiceImpl;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
	
	@Test
	public void Test1() {
		UserServiceProxy usProxy = new UserServiceProxy();
		UserService us = new UserServiceImpl();
		UserService us_PowerUp = usProxy.getUserServiceProxy(us);
		
		us_PowerUp.find();
	}
	
	@Resource(name="userService")
	UserService us;
	@Test
	public void Test2() {
		us.delete();
	}
}

运行Test2方法控制台打印

before
around before
delete
around after
afterReturning
after

Spring使用JdbcTemplate

导入相关jar包

c3p0-0.9.5.5.jar
com.springsource.org.apache.commons.logging-1.1.1.jar
mchange-commons-java-0.2.19.jar
mysql-connector-java-8.0.16.jar
spring-aop-5.0.8.RELEASE.jar
spring-beans-5.0.8.RELEASE.jar
spring-context-5.0.8.RELEASE.jar
spring-core-5.0.8.RELEASE.jar
spring-expression-5.0.8.RELEASE.jar
spring-jdbc-5.0.8.RELEASE.jar
spring-test-5.1.8.RELEASE.jar
spring-tx-5.0.8.RELEASE.jar

创建com.sikiedu.bean下的User.java

package com.sikiedu.bean;

public class User {
	private Integer u_id;
	private String u_username;
	private String u_password;
	/* 各个属性的get和set方法以及空参和有参构造器以及toString方法*/
	
}

创建com.sikiedu.dao包

接口UserDao.java
package com.sikiedu.dao;

import java.util.List;

import com.sikiedu.bean.User;

public interface UserDao {

	//增
	void saveUser(User u);
	//删
	void deleteUserById(Integer id);
	//改
	void updateUser(User u);
	//id查找用户
	User selectUserById(Integer id);
	//查找用户List
	List<User> selectAllUser();
	//查找用户数量s
	Integer selectUserCount();
}

实现类UserDaoImpl.java
package com.sikiedu.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

import com.sikiedu.bean.User;

public class UserDaoImpl extends JdbcDaoSupport implements UserDao{
	
//	JdbcTemplate jt;
//	注入自己配置的JdbcTemplate
//	public void setJt(JdbcTemplate jt) {
//		this.jt = jt;
//	}
	//保存用户
	@Override
	public void saveUser(User u) {
		String sql = "insert into user values(null,?,?)";
		getJdbcTemplate().update(sql, u.getU_username(), u.getU_password());
	}
	//根据id删除用户
	@Override
	public void deleteUserById(Integer id) {
		String sql="delete from user where u_id =?";
		getJdbcTemplate().update(sql, id);
	}
	//更新用户
	@Override
	public void updateUser(User u) {
		String sql="update user set u_username=?, u_password=? where u_id =?";
		getJdbcTemplate().update(sql, u.getU_username(), u.getU_password(), u.getU_id());
	}
	//根据id查询一个用户
	@Override
	public User selectUserById(Integer id) {
		String sql = "select * from user where u_id = ?";
		User user = getJdbcTemplate().queryForObject(sql, new RowMapper<User>() {

			@Override
			public User mapRow(ResultSet rs, int index) throws SQLException {
				User u =new User();
				u.setU_id(rs.getInt("u_id"));
				u.setU_username(rs.getString("u_username"));
				u.setU_password(rs.getString("u_password"));
				return u;
			}
			
		}, id);
		return user;
	}
	//查询用户列表
	@Override
	public List<User> selectAllUser() {
		String sql = "select * from user";
		List<User> list = getJdbcTemplate().query(sql, new RowMapper<User>() {
			@Override
			public User mapRow(ResultSet rs, int index) throws SQLException {
				User u =new User();
				u.setU_id(rs.getInt("u_id"));
				u.setU_username(rs.getString("u_username"));
				u.setU_password(rs.getString("u_password"));
				return u;
			}
		});
		return list;
	}
	//查询用户数量
	@Override
	public Integer selectUserCount() {
		String sql = "select count(*) from user";
		return getJdbcTemplate().queryForObject(sql, Integer.class);
	}
	
}

创建测试类JdbcTest.java

package com.sikiedu.test;

import java.util.Iterator;
import java.util.List;

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.sikiedu.bean.User;
import com.sikiedu.dao.UserDao;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcTest {

	@Resource(name="userDao")
	private UserDao ud;
	@Test
	public void saveUser() {
		User u = new User();
		u.setU_username("jifeng");
		u.setU_password("123");
		ud.saveUser(u);
	}
	
	@Test
	public void updateUserById() {
		User u = new User();
		u.setU_id(2);
		u.setU_username("alice.alice");
		u.setU_password("234");
		ud.updateUser(u);
	}
	
	@Test
	public void findUserById() {
		User u = ud.selectUserById(3);
		System.out.println(u);
	}
	
	@Test
	public void findAllUser() {
		List<User> u_list = ud.selectAllUser();
		for (User user : u_list) {
			System.out.println(user);
		}
	}
	
	@Test
	public void findCountUser() {
		Integer count = ud.selectUserCount();
		System.out.println(count);
	}
	
	@Test
	public void deleteUserById() {
		ud.deleteUserById(2);
	}
}

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:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
	
	<!-- 依赖关系 dao ->  -> dataSource -->
	<!-- 读取配置文件 -->
	<context:property-placeholder location="db.properties"/>
	
	<!-- 配置 dataSource -->
	<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"/>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
		<property name="user" value="${jdbc.user}"/>
		<property name="password" value="${jdbc.password}"/>
	</bean>
	
	<!-- 自己配置jdbcTemplate  -->
	<!-- 	<bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"/>
	</bean> -->
	
	<!-- dao -->
	<bean name="userDao" class="com.sikiedu.dao.UserDaoImpl">
		<!-- <property name="jt" ref="jdbcTemplate"/> -->
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
</beans>

db.properties

jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
jdbc.user=login
jdbc.password=123

Spring-aop事务

事务基本知识

1、 事务相关知识:

a) 什么是事务:把多条数据库操作捆绑到一起执行,要么都成功,要么都失败;

b) 事务的原则ACID:

​ i. 原子性:事务包含的所有操作,要么全部成功,要么全部失败回滚,成功全部应用到数据库,失败不能对数据库有任何影响;

​ ii. 一致性:事务在执行前和执行后必须一致;例如A和B一共有100块钱,无论A、B之间如何转账,他们的钱始终相加都是100;

​ iii. 隔离性:多用户并发访问同一张表时,数据库为每一个用户开启新的事务,该事务不能被其他事务所影响,相互有隔离;

​ iv. 持久性:一个事务一旦提交,则对数据库中数据的改变是永久的,即便系统故障也不会丢失;

c) 并发可能引起的问题:

​ i. 脏读:一个事务读取到另一个事务未提交的数据;

​ ii. 不可重复读:一个事务读取到另一个事务已提交(Update操作)的数据,导致前后读取不一致;

​ iii. 幻读(虚读):一个事务中读取到别的事务插入(Insert操作)的数据,导致前后读取不一致;

d) 事务的隔离级别:根据实际情况选择;

​ i. Serializable串行化:可避免脏读、不可重复读和幻读;

​ ii. Repeatable read可重复读:可避免脏读、不可重复读;(MySql默认值)

​ iii. Read committed读已提交:可避免脏读;

​ Ⅳ Read uncommitted 读未提交:任何情况都无法保证

经典转账案例

a) 使用经典的转账案例进行测试,准备数据:bean、service、dao;

b) 使用事务需要额外导入tx包和tx约束;

c) 配置事务核心管理器: DataSourceTransactionManager;

d) 配置事务通知 tx:Advice;

e) 配置aop;

通过xml方式配置事务
导入相关的jar包

c3p0-0.9.5.5.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.apache.commons.logging-1.1.1.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
mchange-commons-java-0.2.19.jar
mysql-connector-java-8.0.16.jar
spring-aop-5.0.8.RELEASE.jar
spring-beans-5.0.8.RELEASE.jar
spring-context-5.0.8.RELEASE.jar
spring-core-5.0.8.RELEASE.jar
spring-expression-5.0.8.RELEASE.jar
spring-jdbc-5.0.8.RELEASE.jar
spring-test-5.1.8.RELEASE.jar
spring-tx-5.0.8.RELEASE.jar

创建bean包下的Account.java
package com.sikiedu.bean;

public class Account {
	private Integer id;
	private String name;
	private Double money;
	/* 各个属性的get和set方法以及空参和有参构造器以及toString方法*/
}

创建AccountDao.java接口和AccountDaoImpl.java实现类
package com.sikiedu.dao;

public interface AccountDao {
	//扣钱
	void subMoney(Integer id, Double money);
	//加钱
	void addMoney(Integer id, Double money);
	
}

package com.sikiedu.dao;

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

public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
	
	@Override
	public void subMoney(Integer id, Double money) {
		String sql= "update account set money = money - ? where id =?";
		getJdbcTemplate().update(sql, money, id);
	}

	@Override
	public void addMoney(Integer id, Double money) {
		String sql= "update account set money = money + ? where id =?";
		getJdbcTemplate().update(sql, money, id);

	}

}
创建AccountService.java接口和AccountServiceImpl.java实现类
package com.sikiedu.service;
public interface AccountService {
	//转账接口
	void transferAccounts();
}

package com.sikiedu.service;

import com.sikiedu.dao.AccountDao;

public class AccountServiceImpl implements AccountService {

	//账户dao
	private AccountDao ad;
	
	public void setAd(AccountDao ad) {
		this.ad = ad;
	}

	@Override
	public void transferAccounts() {
		//先从A账户扣款
		ad.subMoney(1,50d);
		
		//int a= 1/0;
		//再给B账户扣款
		ad.addMoney(2,50d);
	}
}

配置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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
	
	<!-- 依赖关系 dao ->  -> dataSource -->
	<!-- 读取配置文件 -->
	<context:property-placeholder location="db.properties"/>
	
	<!-- 配置 dataSource -->
	<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"/>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
		<property name="user" value="${jdbc.user}"/>
		<property name="password" value="${jdbc.password}"/>
	</bean>
	
	<!-- dao -->
	<bean name="accountDao" class="com.sikiedu.dao.AccountDaoImpl">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<!-- service -->
	<bean name="accountService" class="com.sikiedu.service.AccountServiceImpl">
		<property name="ad" ref="accountDao"/>
	</bean>
	
	<!-- 配置事务核心管理器 不同平台不一样 -->
	<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<!-- 事务通知 -->
	<tx:advice id="txAdivce" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="transferAccounts" isolation="DEFAULT"  propagation="REQUIRED" read-only="false"/>
			<tx:method name="save*" isolation="DEFAULT"  propagation="REQUIRED" read-only="false"/>
			<tx:method name="delete*" isolation="DEFAULT"  propagation="REQUIRED" read-only="false"/>
			<tx:method name="update*" isolation="DEFAULT"  propagation="REQUIRED" read-only="false"/>
			<tx:method name="select*" isolation="DEFAULT"  propagation="REQUIRED" read-only="true"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- 配置aop -->
	<aop:config>
		<aop:pointcut expression="execution(* com.sikiedu.service.*ServiceImpl.*(..))" id="txPc"/>
		<aop:advisor advice-ref="txAdivce" pointcut-ref="txPc"/>
	</aop:config>
	
</beans>
db.properties
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
jdbc.user=login
jdbc.password=123
添加测试方法
package com.sikiedu.test;

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.sikiedu.service.AccountService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TxTest {
	
	@Resource(name="accountService")
	private AccountService as;
	@Test
	public void Test1() {
		as.transferAccounts();
	}
}
通过注解方式配置事务
修改AccountServiceImpl.java
package com.sikiedu.service;

import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.sikiedu.dao.AccountDao;

//给类添加注解 类下所有方法都有效
@Transactional(isolation=Isolation.DEFAULT, propagation=Propagation.REQUIRED, readOnly=true)
public class AccountServiceImpl implements AccountService {

	//账户dao
	private AccountDao ad;
	public void setAd(AccountDao ad) {
		this.ad = ad;
	}

	@Override
	@Transactional(isolation=Isolation.DEFAULT, propagation=Propagation.REQUIRED, readOnly=false)
	public void transferAccounts() {
		//转账逻辑
		
		//先从A账户扣款
		ad.subMoney(1, 50d);
		
		int a = 1/0;
		
		//再给B账户加款
		ad.addMoney(2, 50d);
	}

}

修改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:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
	
	<!-- 依赖关系 dao ->  -> dataSource -->
	<!-- 读取配置文件 -->
	<context:property-placeholder location="db.properties"/>
	
	<!-- 配置 dataSource -->
	<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"/>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
		<property name="user" value="${jdbc.user}"/>
		<property name="password" value="${jdbc.password}"/>
	</bean>

	<!-- dao -->
	<bean name="accountDao" class="com.sikiedu.dao.AccountDaoImpl">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<!-- service -->
	<bean name="accountService" class="com.sikiedu.service.AccountServiceImpl">
		<property name="ad"  ref="accountDao"/>
	</bean>
	
	<!-- 配置事务核心管理器 不同平台不一样 -->
	<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<!-- 开启注解事务 -->
	<tx:annotation-driven/>
	
</beans>

Spring整合Mybatis框架

导入相关jar包

aop相关

com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
spring-aop-5.0.8.RELEASE.jar
spring-aspects-5.0.8.RELEASE.jar

spring基本包

com.springsource.org.apache.commons.logging-1.1.1.jar
spring-beans-5.0.8.RELEASE.jar
spring-context-5.0.8.RELEASE.jar
spring-core-5.0.8.RELEASE.jar
spring-expression-5.0.8.RELEASE.jar

事务

spring-jdbc-5.0.8.RELEASE.jar
spring-tx-5.0.8.RELEASE.jar

数据库驱动

c3p0-0.9.5.5.jar
mchange-commons-java-0.2.19.jar
mysql-connector-java-8.0.16.jar

mybatis核心包

mybatis-3.4.6.jar

mybatis与spring整合包

mybatis-spring-1.3.2.jar

spring的Junit的test包

spring-test-5.1.8.RELEASE.jar

com.sikiedu.bean下的Account.java

package com.sikiedu.bean;

public class Account {
	private Integer id;
	private String name;
	private Double money;
	
	//转账金额  不在数据库中
	private Double tranferMoney;
	/*属性的get和set方法*/
	public Account(Integer id, String name, Double money) {
		super();
		this.id = id;
		this.name = name;
		this.money = money;
	}
	public Account() {
		super();
	}
	
}

com.sikiedu.mapper

AccountMapper.java接口
package com.sikiedu.mapper;

import com.sikiedu.bean.Account;

//账户mapper接口
public interface AccountMapper {
	//操作数据库 扣款和加款
	
	//扣
	void subMoney(Account pay);
	
	//加
	void addMoney(Account collect); 
}

AccountMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sikiedu.mapper.AccountMapper">
	<update id="subMoney" parameterType="Account">
		update account set money = money - #{tranferMoney} where id = #{id}
	</update>
	
	<update id="addMoney" parameterType="Account">
		update account set money = money + #{tranferMoney} where id = #{id}
	</update>
</mapper>

com.sikiedu.service

AccountService.java接口
package com.sikiedu.service;

public interface AccountService {
	//未配置事务的方法
	void tranferAccount();
	
	//配置事务的方法
	void updateTranferAccount();
}

AccountServiceImpl.java
package com.sikiedu.service;

import javax.annotation.Resource;

import com.sikiedu.bean.Account;
import com.sikiedu.mapper.AccountMapper;

public class AccountServiceImpl implements AccountService {
	@Resource(type = AccountMapper.class)
	private AccountMapper mapper;
	
	//未使用事务的方法
	@Override
	public void tranferAccount() {
		Double tranferMoney = 1000d;

		Account pay = new Account();
		pay.setId(1);
		pay.setTranferMoney(tranferMoney);
		// 先扣
		mapper.subMoney(pay);
		
		//异常
		int a=1/0;

		Account collect = new Account();
		collect.setId(2);
		collect.setTranferMoney(tranferMoney);
		// 再加
		mapper.addMoney(collect);
	}

	//配置事务的方法
	@Override
	public void updateTranferAccount() {
		Double tranferMoney = 1000d;

		Account pay = new Account();
		pay.setId(1);
		pay.setTranferMoney(tranferMoney);
		// 先扣
		mapper.subMoney(pay);
		
		//异常
		int a=1/0;
		
		Account collect = new Account();
		collect.setId(2);
		collect.setTranferMoney(tranferMoney);
		// 再加
		mapper.addMoney(collect);
	}

}

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: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-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
		
	<!-- 读取配置文件 -->
	<context:property-placeholder location="db.properties"/>
	
	<!-- 配置 dataSource -->
	<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"/>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
		<property name="user" value="${jdbc.user}"/>
		<property name="password" value="${jdbc.password}"/>
	</bean>
	
	<!-- mybatis -->
	<bean name="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource"/>
		<property name="configLocation" value="classpath:sqlMapConfig.xml"/>
	</bean>
	
	<!-- mapper工厂 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.sikiedu.mapper"/>
	</bean>
	
	<!-- service -->
	<bean name="accountService" class="com.sikiedu.service.AccountServiceImpl"></bean>
	
	<!-- 需要事务核心管理器 -->
	<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<!-- 配置事务通知 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="update*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- 配置aop -->
	<aop:config>
		<aop:pointcut expression="execution(* com.sikiedu.service.*ServiceImpl.*(..))" id="txPc"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"/>
	</aop:config>
	
</beans>

sqlMapConfig.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.sikiedu.bean"/>
  	</typeAliases>
  </configuration>

db.properties

jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
jdbc.user=login
jdbc.password=123

测试类MapperTest.java

package com.sikiedu.test;

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.sikiedu.service.AccountService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class MapperTest {
	
	@Resource(name="accountService")
	private AccountService as;
	
	@Test
	public void Test1() {
		as.tranferAccount();
	}
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值