spring集成Mybatis
Spring 集成 Mybatis 其核心是将 SqlSessionFactory 交由 Spring 管理,并由
Spring 管理对 dao 接口的代理实现。
Spring 结合 mybatis 插件包
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
配置 sqlSessionFactory
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<property name="mapperLocations" value="classpath:mappers/*Mapper.xml">
</property>
</bean>
指定生成接口代理
<bean id="mapperFactory" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.ffyc.ssm.dao"></property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory">
</property>
</bean>
AOP
AOP 为 Aspect Oriented Programming 的缩写,意为:面向切面编程,通过 预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。 AOP 是 OOP 的延续,是软件开发中的一个热点,是 java 开发中的一个重要内 容。利用 AOP 可以对业务逻辑和非业务逻辑进行隔离,从而使得各部分之间的 耦合度降低,提高程序的可重用性,同时提高了开发的效率。
AOP的基本概念
连接点(Joinpoint):类中可以被增强的方法,这个方法就被称为连接点
切入点(pointcut):类中有很多方法可以被增强,但实际中只有 add 和 update
被增了,那么 add 和 update 方法就被称为切入点(实际实现的连接点)
通知(Advice): 通知是指一个切面在特定的连接点要做的事情(增强的功能)。通
知分为方法执行前通知,方法执行后通知,环绕通知等. 目标(Target): 代理的目标对象(连接点,切入点所在类)
代理(Proxy): 向目标对象应用通知时创建的代理对象
AspectJ 中常用的通知有五种类型:
1.前置通知:
@Before 前置通知:方法执行之前
2.后置通知:
@After 后置通知:方法执行之后,无论是否出现异常
3.环绕通知:
@AfterReturnning 返回通知:方法成功执行之后通知,出现异常不执行
4.异常通知:
@AfterThrowing 异常通知:抛出异常之后通知
5.返回通知:
@Around 环绕通知:方法执行前后都有通知
基于注解方式的实现
启动 AspectJ 支持:<aop:aspectj-autoproxy />
五种类型通知代码
@Component
@Aspect
public class AOPDemo {
@Before("execution(* com.ff.spring.dao.UserDao.*(..))")
public void saveLog(){
System.out.println("saveLog");
}
@AfterThrowing(value = "execution(*com.ff.spring.dao.UserDao.*(..))",throwing = "e")
public void afterthrow(Throwable e){
System.out.println("afterthrow");
}
public void aroundAdvice(ProceedingJoinPoint joinPoint){
try {
//前置通知
Object[] objects = joinPoint.getArgs();
joinPoint.proceed();//调用我们自己的目标方法
//返回通知
} catch (Throwable throwable) {
throwable.printStackTrace();
//异常通知
}
//后置通知
}
}
AOP所需要的jar包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<!-- spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
spring.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:jdbc="http://www.springframework.org/schema/jdbc"
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/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--开启spring扫描注解 注解扫描的包-->
<context:component-scan base-package="com.ffyc.springpro"> </context:component-scan>
<!-- 开启自动代理-->
<aop:aspectj-autoproxy />
AdminDao内容
package com.ffyc.springpro.Dao;
import com.ffyc.springpro.model.Admin;
import com.mysql.cj.protocol.Resultset;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
@Repository
public class AdminDao {
@Autowired()
Admin admin;
@Autowired()
JdbcTemplate jdbcTemplate;
public void saveAdmin(){
List<Admin> admins = jdbcTemplate.query("select * from admin", new RowMapper<Admin>() {
public Admin mapRow(ResultSet resultSet, int i) throws SQLException {
Admin admin = new Admin();
admin.setAccount(resultSet.getString("account"));
admin.setPassword(resultSet.getString("password"));
return admin;
}
});
System.out.println(admins);
}
编写CommomUtil类
package com.ffyc.springpro.common;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
@Component
@Aspect
public class commonUtil {
/*
通知,向链接点添加对象
@before 前置通知 在业务方法之前执行调用
@After 后置通知 在业务方法执行后调用 即使业务出现异常也会执行
@AfterReturning 返回通知 在业务方法执行后调用 业务代码出现异常后不会执行
@AfterThrowing 异常通知 当业务代码出现异常时执行
@Around 环绕通知 可以在业务方法执行之前 之后 出异常 时候 添加功能
ProceedingJoinPoint joinPoint
*/
//@Before("execution(* com.ffyc.springpro.Dao.AdminDao.*(..))")
//@After("execution(* com.ffyc.springpro.Dao.AdminDao.*(..))")
//@AfterReturning("execution(* com.ffyc.springpro.Dao.AdminDao.*(..))")
public void printLog() {
System.out.println("打印日志");
}
//@AfterThrowing(value = "execution(* com.ffyc.springpro.Dao.AdminDao.*(..))",throwing = "throwable")
public void exception(Throwable throwable){
System.out.println("系统忙"+throwable.getMessage());
throwable.printStackTrace();
}
private void commit() {
System.out.println("提交事务");
}
// @Around(value = "execution(* com.ffyc.springpro.Dao.AdminDao.*(..))")
// public void around(ProceedingJoinPoint joinPoint){
// System.out.println("前置通知");
//
// try {
// Object[] objects = joinPoint.getArgs();//获取目标方法的参数
// System.out.println(Arrays.toString(objects));
// Object object = joinPoint.proceed();//调用目标业务的方法
// System.out.println("返回通知");
// } catch (Throwable throwable) {
// throwable.printStackTrace();
// System.out.println("异常通知");
// }
// System.out.println("后置通知");
// }
}
Test测试类
package com.ffyc.springpro.Test;
import com.ffyc.springpro.service.AdminService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class Test3 {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
AdminService adminService = applicationContext.getBean("adminService",AdminService.class);
adminService.deleteAdmin();
adminService.insertAdmin();
adminService.updateAdmin();
}
}
spring事务管理
配置事务管理器
<!-- 配置 spring 事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
注解方式
<!-- 开启注解事务管理 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
在类或方法上使用@Transactional 标签即可
声明式事务不生效的场景
1.@Transactional 用在非public方法上 2.方法中的异常被捕获 认为方法没有异常 3.方法中的编译异常 还是会提交事务 可以将rollbackFor = Exception.class 抛出所有异常 4.数据库引擎不支持事务 mysql中只有innodb引擎支持事务
代码实现
Test测试类
package com.ffyc.springpro.Test;
import com.ffyc.springpro.service.AdminService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class Test3 {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
AdminService adminService = applicationContext.getBean("adminService",AdminService.class);
adminService.deleteAdmin();
adminService.insertAdmin();
adminService.updateAdmin();
}
}
AdminService类
package com.ffyc.springpro.service;
import com.ffyc.springpro.Dao.AdminDao;
import com.ffyc.springpro.model.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
@Service (value = "adminService")
public class AdminService {
@Autowired
AdminDao adminDao ;
@Transactional(rollbackFor = Exception.class)
public void insertAdmin(){
adminDao.insert();
adminDao.insert1();
}
public void deleteAdmin(){adminDao.delete();}
public void updateAdmin(){adminDao.update();}
}
Admin类
package com.ffyc.springpro.model;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
//等同于xml中的 <bean id="admin" class="com.ffyc.springpro.model.Admin" scope="prototype">
@Component(value = "admin")
@Scope(value = "prototype")
public class Admin {
private String account;
private String password;
public Admin(String account,String password){
this.account = account;
this.password = password;
}
@Override
public String toString() {
return "Admin{" +
"account='" + account + '\'' +
", password='" + password + '\'' +
'}';
}
public Admin(){
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
AdminDao类
import java.util.List;
@Repository
public class AdminDao {
// @Autowired()
// Admin admin;
// @Autowired()
JdbcTemplate jdbcTemplate;
/*
链接点:类中可以被增强(加功能)的方法
切入点:类中实际被增强的方法
目标(Target): 代理的目标类(连接点,切入点所在类)
代理(Proxy): 向目标对象应用通知时创建的代理对象
*/
public void insert(){
System.out.println("新增");
jdbcTemplate.update("insert into admin (account , password,gender) value (?,?,?)","shangsan","111","男");
}
public void insert1() {
jdbcTemplate.update("insert into admin (account , password,gender) value (?,?,?)","shangsan","111","男");
}
public void update(){
System.out.println("修改");
}
public void delete(){
System.out.println("删除");
}
}
communtil类
package com.ffyc.springpro.common;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
@Component
@Aspect
public class commonUtil {
public void printLog() {
System.out.println("打印日志");
}
//@AfterThrowing(value = "execution(* com.ffyc.springpro.Dao.AdminDao.*(..))",throwing = "throwable")
public void exception(Throwable throwable){
System.out.println("系统忙"+throwable.getMessage());
throwable.printStackTrace();
}
private void commit() {
System.out.println("提交事务");
}
}