JAVA02

阿里云国内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>

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Java