阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
今日内容
1. SpringAOP和数据库进行curd操作
SpringAOP
Spring核心技术之一
对数据库进行curd操作时,进行增强
思想
增强数据库的curd业务,将SpringAOP技术整合进去,为后面的Spring方式控制事务做准备
需要准备的依赖包
mybatis
mysql驱动
spring-context依赖包
druid连接池-德鲁伊
log4j-日志包
junit-单元测试包
spring-jdbc存在
lombok
mybatis-spring整合包
springAspect-AOP核心技术
mybatis分页查询-pageHelper
spring-test测试
spring-tx事务管理
package com.szr.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
//用户实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
//和数据库字段一一对应
private Integer id ;
private String name ;
private Integer age ;
private String gender ;
}
package com.szr.mapper;
import com.szr.pojo.User;
import org.springframework.stereotype.Repository;
import java.util.List;
//数据访问接口
//spring提供注解创建对象,数据访问层用@Repository
@Repository//后面没有内容,代表默认名称为当前类名
public interface UserMapper {
/**
* 获取所有用户信息
* @return 返回用户信息集合
*/
List<User> getAllUserInfo();
}
package com.szr.service;
import com.github.pagehelper.PageInfo;
import com.szr.pojo.User;
import java.util.List;
//用户业务层
public interface UserService {
/**
* 获取所有用户信息
* @return 返回所有用户信息的分页结果信息
*/
List<User> getAllUser();
}
package com.szr.service.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.szr.mapper.UserMapper;
import com.szr.pojo.User;
import com.szr.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
//用户业务实现类
//spring提供创建对象注解再service层@Service
@Service("userService")//后面不跟内容,代表默认名称为该类类名首字母小写
public class UserServiceImpl implements UserService {
//调用mapper数据访问层,自动注入
@Autowired
private UserMapper userMapper ;
/**
* 获取所有用户信息
* @return 返回所有用户信息的分页结果信息
*/
@Override
public List<User> getAllUser() {
//调用pagehelper分页查询
//设置分页条件
PageHelper.startPage(1,1);
//完成调用方法
List<User> userInfo = userMapper.getAllUserInfo();
//创建pageinfo对象
PageInfo<User> pageInfo = PageInfo.of(userInfo);
System.out.println(pageInfo);
return userInfo;
}
}
package com.szr.myAspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
//创建类对象的方式之一
@Component
//切面类
@Aspect//springAOP方法注解,标记这个类是一个切面类
public class MyAspect{
//创建切点-在什么方法进行时进行通知-切点表达式
@Pointcut("execution(* *.*.service.impl.*.*(..))")
public void pointCut(){}
//配置环绕通知
@Around("pointCut()")//标记这个方法时环绕通知方法-里面是引入切点
public Object myAround(ProceedingJoinPoint joinPoint){
Object obj = null ;
try {
//进行执行方法之前的通知
System.out.println("已经校验过权限!");
//进行反射获取方法
obj = joinPoint.proceed();
//完成执行方法后通知
System.out.println("已经记录到日志!");
return obj ;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null ;
}
}
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--配置映射文件,完成对数据库的curd-->
<mapper namespace="com.szr.mapper.UserMapper">
<!--配置基本集合存放数据-->
<resultMap id="baseMap" type="user">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<result property="gender" column="gender"></result>
</resultMap>
<!--书写操作语句-->
<select id="getAllUserInfo" resultMap="baseMap">
select * from user
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd">
<!--读取全局注解文件-->
<context:component-scan base-package="com.szr"/>
<!--配置spring-config配置文件,三大部分-->
<!--第一部分-->
<!--读取外部配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置数据库数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<!--el表达式,使用${}将数据加载变成动态获取-->
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<!--其他参数-->
<property name="maxActive" value="${jdbc.maxActive}"></property>
</bean>
<!--第二部分-->
<!--配置SqlSessionFactoryBean,就是mybatis和spring整合包内容-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--关联数据库数据源,上面已经配置过,直接关联名称即可-->
<property name="dataSource" ref="dataSource"></property>
<!--给实体类起别名-->
<property name="typeAliasesPackage" value="com.szr.pojo"></property>
<!--配置数据访问层相对应的映射文件-->
<property name="mapperLocations" value="com/szr/mapper/*Mapper.xml"></property>
<!--配置分页查询插件-->
<property name="plugins">
<array>
<!--配置了拦截器,如果配置了但是没有使用,会报错!-->
<bean class="com.github.pagehelper.PageInterceptor"></bean>
</array>
</property>
</bean>
<!--第三部分-->
<!--配置MapperScannerConfigurer,mybatis和spring整合包-->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--关联SqlSessionFactoryBean-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<!--对数据访问接口进行包扫描-->
<property name="basePackage" value="com.szr.mapper"></property>
</bean>
<!--开启AOP注解-->
<aop:aspectj-autoproxy/>
</beans>
package com.szr.test;
import com.github.pagehelper.PageInfo;
import com.szr.pojo.User;
import com.szr.service.UserService;
import com.szr.service.impl.UserServiceImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
//测试类
public class SpringTest {
@Test
public void SpringTestCurd(){
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
UserService userService = (UserService) context.getBean("userService");
//调用方法
List<User> allUser = userService.getAllUser();
System.out.println(allUser);
/*
已经校验过权限!
2023-02-03 20:38:19,744 0 [ main] INFO aba.druid.pool.DruidDataSource - {dataSource-1} inited
PageInfo{pageNum=1, pageSize=1, size=1, startRow=1, endRow=1, total=2, pages=2, list=Page{count=true, pageNum=1, pageSize=1, startRow=0, endRow=1, total=2, pages=2, reasonable=false, pageSizeZero=false}[User(id=1, name=钟离, age=500, gender=男)], prePage=0, nextPage=2, isFirstPage=true, isLastPage=false, hasPreviousPage=false, hasNextPage=true, navigatePages=8, navigateFirstPage=1, navigateLastPage=2, navigatepageNums=[1, 2]}
已经记录到日志!
Page{count=true, pageNum=1, pageSize=1, startRow=0, endRow=1, total=2, pages=2, reasonable=false, pageSizeZero=false}[User(id=1, name=钟离, age=500, gender=男)]
*/
}
}
2. Spring开启事务管理
事务
理解
同进退,共生死--要么一起成功,要么都别成功,回到最开始的样子
特点
原子性
一致性
隔离性
持久性
事务的隔离级别
读未提交read uncommitted
读已提交 read committed
可重复读repeatable read mysql的默认隔离级别
串行话 serializable
Spring事务
两种方式开启事务
xml文件配置方式
1)加入Spring事务的约束文件
2)配置Spring-jdbc事务管理器
DataSourceTransactionManager
注入数据库数据源
3)管理事务管理器
id属性:唯一通知的标识
transaction-manager:管理事务管理器DataSourceTrancationManager
4)配置事务的属性
tx:method name ="要开启事务的方法名"
isolation="事务的隔离级别 可以不写默认 mysql的隔离级别"
propagation:事务的 传播行为
REQUIRED 需要在update/add/delete修改添加删除的都需要控制事务
SUPPORTS:支持事务 findxxx/selectXXX/searchXXX 查询操作 设置SUPPORTS
rollback-for="Exception" 当前业务出现了什么异常,进行回滚,exception最大异常类
package com.szr.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
//账户实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Account {
//账户ID
private Integer id ;
//账户金额
private Integer money ;
//账户拥有者
private String name ;
}
package com.szr.mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
//数据库访问层
@Repository//数据访问层的创建实例注解
public interface AccountMapper {
/**
* 转账
* @param lostmoney 转账人
* @param changemoney 转账金额
*/
void updateLost(@Param("lostmoney") String lostmoney,
@Param("changemoney") Integer changemoney);
/**
* 收账
* @param getmoney 收账人
* @param changemoney 转账金额
*/
void updateAdd(@Param("getmoney") String getmoney,
@Param("changemoney") Integer changemoney);
}
package com.szr.service;
/*
账户操作业务层
*/
public interface AccountService {
/**
* 转账操作
* @param lostmoney 转账人
* @param getmoney 接收人
* @param changemoney 转账金额
*/
void ChangeMoney(String lostmoney , String getmoney , Integer changemoney);
}
package com.szr.service.impl;
import com.szr.mapper.AccountMapper;
import com.szr.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
//业务层实现类
@Service("accountService")//业务层创建实例注解
public class AccountServiceImpl implements AccountService {
//自动注入
@Autowired
private AccountMapper accountMapper ;
/**
* 转账操作
* @param lostmoney 转账人
* @param getmoney 接收人
* @param changemoney 转账金额
*/
@Override
public void ChangeMoney(String lostmoney, String getmoney, Integer changemoney) {
//完成转账操作
//转账
accountMapper.updateLost(lostmoney,changemoney);
//错误异常
//int i = 10 / 0 ;
//收账
accountMapper.updateAdd(getmoney,changemoney);
//提示
System.out.println("转账成功!");
}
}
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.szr.mapper.AccountMapper">
<!--转账操作-->
<update id="updateLost">
update acount set money = money - #{changemoney} where name = #{lostmoney}
</update>
<!--收账操作-->
<update id="updateAdd">
update acount set money = money + #{changemoney} where name = #{getmoney}
</update>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd">
<!--读取全局注解文件-->
<context:component-scan base-package="com.szr"/>
<!--配置spring-config配置文件,三大部分-->
<!--第一部分-->
<!--读取外部配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置数据库数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<!--el表达式,使用${}将数据加载变成动态获取-->
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<!--其他参数-->
<property name="maxActive" value="${jdbc.maxActive}"></property>
</bean>
<!--第二部分-->
<!--配置SqlSessionFactoryBean,就是mybatis和spring整合包内容-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--关联数据库数据源,上面已经配置过,直接关联名称即可-->
<property name="dataSource" ref="dataSource"></property>
<!--给实体类起别名-->
<property name="typeAliasesPackage" value="com.szr.pojo"></property>
<!--配置数据访问层相对应的映射文件-->
<property name="mapperLocations" value="com/szr/mapper/*Mapper.xml"></property>
</bean>
<!--第三部分-->
<!--配置MapperScannerConfigurer,mybatis和spring整合包-->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--关联SqlSessionFactoryBean-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<!--对数据访问接口进行包扫描-->
<property name="basePackage" value="com.szr.mapper"></property>
</bean>
<!--配置Spring事务约束-->
<!--配置spring-jdbc事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置事务通知-->
<tx:advice id="tx" transaction-manager="transactionManager">
<!--配置事务属性-->
<tx:attributes>
<!--开启事务的方法名 在修改,删除,添加开启的事务 遇见异常回滚 -->
<tx:method name="ChangeMoney" propagation="REQUIRED" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
<!--配置aop的通知类型-->
<aop:config>
<aop:advisor advice-ref="tx" pointcut="execution(* *.*.service.impl.*.*(..))"></aop:advisor>
</aop:config>
</beans>
package com.szr.test;
import com.szr.service.AccountService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
//测试类
public class SpringTransactionTest {
@Test
public void transactionTest(){
//完成转账操作
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
AccountService account = (AccountService) context.getBean("accountService");
account.ChangeMoney("胡桃","钟离",500);
}
}
注解配置方式
1)加入Spirng事务约束文件
2)配置Spring-jdbc事务管理器
注入数据库数据源
3)开启事务注解
<tx:annotation-driven transaction-manager="transactionManager"/>
注意
事务和切面中的异常报错不能同时配置
事务需要通过异常来回滚,切面中的异常报错也需要异常来输出信息
这会导致切面中提前捕获异常输出信息,后面的程序不执行,所以事务无法回滚!
package com.szr.service.impl;
import com.szr.mapper.AccountMapper;
import com.szr.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
//业务层实现类
@Service("accountService")//业务层创建实例注解
public class AccountServiceImpl implements AccountService {
//自动注入
@Autowired
private AccountMapper accountMapper ;
/**
* 转账操作
* @param lostmoney 转账人
* @param getmoney 接收人
* @param changemoney 转账金额
*/
//这里使用注解方式,一句话解决
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void ChangeMoney(String lostmoney, String getmoney, Integer changemoney) {
//完成转账操作
//转账
accountMapper.updateLost(lostmoney,changemoney);
//错误异常
//int i = 10 / 0 ;
//收账
accountMapper.updateAdd(getmoney,changemoney);
//提示
System.out.println("转账成功!");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd">
<!--读取全局注解文件-->
<context:component-scan base-package="com.szr"/>
<!--配置spring-config配置文件,三大部分-->
<!--第一部分-->
<!--读取外部配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置数据库数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<!--el表达式,使用${}将数据加载变成动态获取-->
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<!--其他参数-->
<property name="maxActive" value="${jdbc.maxActive}"></property>
</bean>
<!--第二部分-->
<!--配置SqlSessionFactoryBean,就是mybatis和spring整合包内容-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--关联数据库数据源,上面已经配置过,直接关联名称即可-->
<property name="dataSource" ref="dataSource"></property>
<!--给实体类起别名-->
<property name="typeAliasesPackage" value="com.szr.pojo"></property>
<!--配置数据访问层相对应的映射文件-->
<property name="mapperLocations" value="com/szr/mapper/*Mapper.xml"></property>
</bean>
<!--第三部分-->
<!--配置MapperScannerConfigurer,mybatis和spring整合包-->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--关联SqlSessionFactoryBean-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<!--对数据访问接口进行包扫描-->
<property name="basePackage" value="com.szr.mapper"></property>
</bean>
<!--配置Spring事务约束-->
<!--配置spring-jdbc事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--开启事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>