Spring整合MyBatis实战:从配置到CRUD完整指南

Spring整合MyBatis实战:从配置到CRUD完整指南

作为一名在Java开发道路上不断探索的开发者,我深知学习SSM框架的不易。在这个过程中,我经历了无数的挫折和困惑,但也收获了满满的成就感。为了帮助更多开发者顺利跨越这些障碍,我将自己的学习经验和实战技巧整理成这份学习笔记,希望能为你照亮前行的道路。

这份笔记从基础概念讲起,逐步深入到实际应用。从Spring的IoC和DI机制,到Bean的生命周期管理;从注解的灵活运用,到Spring与MyBatis的无缝整合;从AOP面向切面编程的实战应用,到事务管理的精细控制,每一个知识点都配有详细的代码示例和实战技巧,确保你能快速理解和应用。

一、基础知识

1.1、IOC

作用:控制反转

原理:每一次实例化对象时,都需要通过所需要的类名进行实例化,不方便代码,IOC就是设置一个中间的程序,让代码需要实例化时调用中间的程序(内部资源),通过内部资源进行

1、导入spring-conterxt依赖(maven刷新)

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>6.1.5</version>
    </dependency>
</dependencies>

2、创造daoy与service方法

在这里插入图片描述

3、设置xml方法

xml为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:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
    <bean id="bookservice" class="service.impl.bookserviceimpl"></bean>
    <bean id="bookdao" class="dao.impl.bookdaoimpl"></bean>
</beans>

bean中进行设置,第一个属性为自己所取的名字,第二个为类所在的地址

4、程序的运行

 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
 bookservice bookservice = (service.bookservice) applicationContext.getBean("bookservice");
 bookservice.service();

1.2、DI

作用:依赖注入

原理:在服务器中不用实例化对象,通过set的方法来获取,将dao与service进行结合,不用在service中再new对象

1、删除服务器中的new部分内容,改为set注入

private bookdao bookdao;
public void service(){
    System.out.println("book service save......");
    bookdao.service();
}

public void setBookdao(dao.bookdao bookdao) {
    this.bookdao = bookdao;
}

2、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:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
    <bean id="bookservice" class="service.impl.bookserviceimpl">
        <!--配置server与dao的关系-->
        <!--property标签表示配置当前bean的属性
               name属性表示配置哪一个具体的属性
               ref属性表示参照哪一个bean
       -->
        <property name="bookdao" ref="bookdao"></property>
    </bean>
    <bean id="bookdao" class="dao.impl.bookdaoimpl"></bean>
</beans>

name表示service中的名字,ref表示这里的名字

二、bean类型

2.1、bean的基础类型

1、name

可以设置别名,相当于id的作用,可以设置多个,后面的ref也可以引用name中的名字

<bean id="bookdao" name="dao book se" class="dao.impl.bookdaoimpl"/>

2、scope

单例和非单例的设置,具体表现在重新创立时是否会刷新一个新的地址,(默认为单例)

ApplicationContext cs = new ClassPathXmlApplicationContext("application.xml");
//获取bean
bookdao bookdao = (bookdao)cs.getBean("bookdao");
bookdao.service();
System.out.println(bookdao);
bookdao bookdao1 = (bookdao)cs.getBean("dao");
System.out.println(bookdao1);

名字不一样是name的原因

scope为singleton时为单例(默认)

scope为prototype时为多例

<bean id="bookservice" class="service.impl.bookserviceimpl" scope="prototype">

2.2、bean的实例化

创建bean使用构造方法来完成

1、构造方法实例化

通过反射的原理(直接通过class类进行)直接进行访问构造函数,无论是公共还是私有都能强制进行访问,不能设置实参,会报错

注:没有任何改变,系统自带就有,但不能添加一个有实参的构造,这样系统不会自动生成会报错

2、静态方法实例化

factory是一个中转站,通过改变xml中的获取方式类获取到factory中的new方法,本质还是在获取new中的对象

public static bookdao getOrderDao(){
    return new bookdaoimpl();
}
方式二:静态方法实例化
 <bean id="bookfactory" class="factory.factory1" factory-method="getOrderDao"></bean>

factory-method用于获取类中的这个方法

3、动态工厂

在这里插入图片描述

方法三:动态方法实例化
<bean id="bookfactory" class="factory.factory2"></bean>
<bean id="dao" factory-method="getOrderDao" factory-bean="bookfactory"></bean>

第一步先实例化对象,也就是第二行代码

第二部调用实例化的对象, factory-bean获取第一部的id名

4、factorybean

通过接口来实例化一些方法,减少xml中的操作

public class factory3 implements FactoryBean<bookdao>{
    @Override
    public boolean isSingleton() {
        return  true;
    }

    @Override
    public bookdao getObject() throws Exception {
        return new bookdaoimpl();
    }

    @Override
    public Class<?> getObjectType() {
        return bookdao.class;
    }
}

isSingleton()设置是否单例

getObject() 获取返回对象

Type设置继承类型

方法四:factoryBean实例化
<bean id="factoryBean" class="factory.factory3"></bean>

2.3、bean的生命周期

1、直接创建

public void service(){
    System.out.println("book dao save.......");
}
public void init(){
    System.out.println("init");
}
public void destory(){
    System.out.println("destory");
}

需要在xml中加参数

<bean id="bookdao" name="dao book se" class="dao.impl.bookdaoimpl" init-method="init" destroy-method="destory"/>

init-method="init"设置初始化

destroy-method="destory"设置销毁

销毁的执行需要程序中进行close关闭后才能运行

ClassPathXmlApplicationContext cts = new ClassPathXmlApplicationContext("application.xml");
bookdao bookdao = (bookdao)cts.getBean("bookdao");
bookdao.service();
cts.close();

更改了ApplicationContext为ClassPathXmlApplicationContext

增加了cts.close();

2、接口创建实现

public class bookdaoimpl implements dao.bookdao, InitializingBean, DisposableBean {
    public void service(){
        System.out.println("book dao save.......");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("destory.........");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("init........");
    }
}

实现了

InitializingBean, DisposableBean 两个接口

三、注入类型

3.1、setter注入

1、引用类型

就是之前描写的DI依赖注入,引用类型主要用于整个dao方法

private UserDao userDao;
private bookdao bookdao;

public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
}

public void setBookdao(dao.bookdao bookdao) {
    this.bookdao = bookdao;
}

@Override
public void save() {
    userDao.save();
    bookdao.service();
    System.out.println("save....."+mysql+","+it);
}
<bean id="userdaos" class="dao.impl.UserDaoimpl">
    <property name="bookdao" ref="bookdao"></property>
    <property name="userDao" ref="userdao"></property>
</bean>

ref用于设置这里的名字,name跟类中的名字相同

2、简单类型

private int it;
private String mysql; 
public void setIt(int it) {
    this.it = it;
}

public void setMysql(String mysql) {
    this.mysql = mysql;
}
<bean id="userdao" class="dao.impl.UserDaoimpl">
    <property name="mysql" value="diso"></property>
    <property name="it" value="1235"></property>
 </bean>

value设置里面的值,没有顺序之分

3.2、构造器注入

1、引用类型

public class BookServiceImpl implements BookService{
    private BookDao bookDao;
    private UserDao userDao;

    public BookServiceImpl(BookDao bookDao,UserDao userDao) {
        this.bookDao = bookDao;
        this.userDao = userDao;
    }

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
        userDao.save();
    }
}

xml操作:

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
    <constructor-arg name="bookDao" ref="bookDao"/>
    <constructor-arg name="userDao" ref="userDao"/>
</bean>

name和ref代表的意义和之前的相同

2、简单类型

private String databaseName;
private int connectionNum;

public BookDaoImpl(String databaseName, int connectionNum) {
    this.databaseName = databaseName;
    this.connectionNum = connectionNum;
}

public void save() {
    System.out.println("book dao save ..."+databaseName+","+connectionNum);
}

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
    <constructor-arg name="databaseName" value="mysql"/>
    <constructor-arg name="connectionNum" value="666"/>
</bean>

3、命名的其他操作

name的命名可能耦合度过高

1、采取type=“” 类型来进行确定

2、采取index=""位置来进行确定

在这里插入图片描述

3.3、自动注入

在xml中进行配置直接进行注入

<bean class="com.itheima.dao.impl.BookDaoImpl"/>
<!--autowire属性:开启自动装配,通常使用按类型装配-->
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byType"/>

autowire一般情况使用bytype按类型

当有两个名字的情况进行按名字,名字取决于dao中的private类型

注意:setter类型不能够忘记,不然会报错

在这里插入图片描述

3.4、集合

配置

private int[] array;

private List<String> list;

private Set<String> set;

private Map<String,String> map;

private Properties properties;

数组

<property name="array">
    <array>
        <value>100</value>
        <value>200</value>
        <value>300</value>
    </array>
</property>

List

<property name="list">
<property name="list">
    <list>
        <value>itcast</value>
        <value>itheima</value>
        <value>boxuegu</value>
        <value>chuanzhihui</value>
    </list>
</property>

set

<property name="set">    
    <set>
        <value>itcast</value>
        <value>itheima</value>
        <value>boxuegu</value>
        <value>boxuegu</value>
    </set>
</property>

Map

<property name="set">
<map>
        <entry key="country" value="china"/>
        <entry key="province" value="henan"/>
        <entry key="city" value="kaifeng"/>
    </map>
</property>

property

<property name="properties">    
    <props>
        <prop key="country">china</prop>
        <prop key="province">henan</prop>
        <prop key="city">kaifeng</prop>
    </props>
</property>

四、数据库资源管理

4.1、引入第三方资源

1、引入资源

<denpendency>  
  <groupId>com.alibaba</groupId>
  <artifactId>druid</artifactId>
  <version>1.1.16</version>
</dependency>

2、xml配置

<bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource">
    <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>
 </bean>

在这里插入图片描述

4.2、c3p0设置

1、引入资源

  <groupId>c3p0</groupId>
  <artifactId>c3p0</artifactId>
  <version>0.9.1.2</version>
</dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.47</version>
</dependency>

2、xml配置

<bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    <property name="jdbcUrl" value="jdbc:mysqal://localhost:3306/spring_db"></property>
    <property name="user" value="root"></property>
    <property name="password" value="root"></property>
</bean>

3、aqp展示

//类路径
ApplicationContext cd = new ClassPathXmlApplicationContext("application.xml");
DataSource dataSource = (DataSource) cd.getBean("datasource");
System.out.println(dataSource);

4.3、加载properties文件

1、四个context地方进行修改

<?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.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
"
>
</beans>

在这里插入图片描述

2、引入properties

<context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER"/>

location="classpath*:.properties" 用于设置路径,两个可以让所有的进行便利

system-properties-mode=“NEVER” 在properties中有些名字和系统的相同,这个可以避免使用系统的

3、使用

<bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource">
    <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>
 </bean>

五、容器

5.1、文件类型

类路径
ApplicationContext cd = new ClassPathXmlApplicationContext("application.xml");
文件路径
ApplicationContext sd = new FileSystemXmlApplicationContext("D:\\idea web学习\\demo4\\src\\main\\resources\\application.xml");
多个路径(ctrl+h,查看接口)
ApplicationContext sds = new ClassPathXmlApplicationContext("bean1.xml","bean2.xml");

类路径:直接采用文件名.xml即可,比较方便,类:ClassPathXmlApplicationContext

文件路径:采用的绝对路径,不常用,类:FileSystemXmlApplicationContext

5.2、BeanFactory初始化

顶层接口,了解即可,所有的bean均为延迟加载(不进行get方法不进行构造函数)

六、注解

6.1、xml中bean的替代

1、@Component(“bookdao”)

Component可以总的代表bean类型, 不用到xml中去书写信息

@repository 可以在dao中去使用,给程序员看的,帮助程序员更好的去理解程序

@controller 适用于contronller层

@servicei 适用于service

后面的括号内容为设置的名字

xml内容书写

<context:component-scan base-package="com.example"/>

6.2、xmL资源通过注解在一个类中进行实现

在这里插入图片描述

@Configuration
@ComponentScan("example")
public class dst {
}

@Configuration将该类设置为xml内置资源

@ComponentScan(“example”)等同于<context:component-scan base-package=“com.example”/> 相当于设置识别的bean范围

注解开发需要把程序中导入类进行改变

ApplicationContext ct1 = new AnnotationConfigApplicationContext(dst.class);
bookdao bookdao = (bookdao) ct1.getBean("bookdao");

6.3、bean生命周期的设置

@Scope作用 设置是否单例,跟前面的作用一致

可以设置prototype多地址和singleton单地址(默认为单地址)

@postconstruct 设置初始化,需要先导入Java.annotion

@predestroy 设置销毁,程序多地址时没有,多地址默认不使用生命周期

6.4、依赖注入

1、引用类型注入

@Autowired 自动注入,不用再set设置,构造函数可以直接实现

@Service("bookservice")
public class bookserviceimpl implements bookservice {
    @Autowired
    @Qualifier("bookdao")
    //删除业务层中使用new的方式创建的dao对象
    private bookdao bookDao;
    public void service(){
        System.out.println("book service save......");
        bookDao.service();
    }
}

@Qualifier与 @Autowired是相互匹配的,可以设置注入的对象,想当于下面的private

2、简单类型注入

@Value("123")
private String op;
public void service(){
    System.out.println("book dao save......."+op);
}

@Value(“123”) 可以设置op的值为123

简单类型通过内置资源随时进行改变值

@Configuration
@ComponentScan("example")
@PropertySource("jdbc.properties")
public class dst {
}

xml类中进行设置

@PropertySource(“jdbc.properties”)与内置资源进行联系

properties设置

name = 123;

设置位置

@Value("${name}")
private String op;
public void service(){
    System.out.println("book dao save......."+op);
}

通过value进行读取

6.5、第三方bean配置导入

@Bean表示当前方法的返回值设置为Bean

在这里插入图片描述

jdbc设置

    //Bean表示当前方法的返回值设置为Bean
    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysqal://localhost:3306/spring.db");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        return dataSource;
    }
}

程序中的设置

//第三方的引入
ApplicationContext op = new AnnotationConfigApplicationContext(dst.class);
DataSource dataSource = (DataSource) op.getBean("dataSource");
System.out.println(dataSource);

dst中设置导入

@Configuration
@ComponentScan("example")
@PropertySource("jdbc.properties")
@Import(jdbc.class)
public class dst {
}

@Import进行导入

第三方类型进行注入操作

1、 引用类型

在这里插入图片描述

直接进行导入既可以使用了

2、简单类型

@Value("com.mysql.jdbc.Driver")
private String tname;
@Value("jdbc:mysqal://localhost:3306/spring.db")
private String tUrl;
@Value("root")
private String root;
@Value("123456")
private String password;

设置一个使用一个

6.6、对比

在这里插入图片描述

七、spring和Mybatis的结合

项目结构

在这里插入图片描述

7.1、dao设计

@Component("userMapper")
public interface UserMapper {
    user getUserId(int id);
}
<resultMap id="users" type="com.pojo.user">
    <result column="pwd" property="password"></result>
</resultMap>
<select id="getUserId" resultMap="users" parameterType="int" >
    select * from mybatis.user where id=${id};
</select>

7.2、pojo设计

@Date
@All
@No
public class user {
    private int id;
    private String name;
    private String password;
}

7.3、service设计

@Service
public class userService implements userserviceimpl {
    @Autowired
    private UserMapper userMapper ;
    @Override
    public user getUserIds(int id) {
       return userMapper.getUserId(id);
    }
}
public interface userserviceimpl {
    user getUserIds(int id);
}

7.4、zhujie设计

jdbc

public class jdbc {
    @Value("${jdbc.name}")
    private String name;

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.root}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(name);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

Mybatis

public class Mybatis {
    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
        SqlSessionFactoryBean sq = new SqlSessionFactoryBean();
        sq.setDataSource(dataSource);
        return sq;
    }
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer ms = new MapperScannerConfigurer();
        ms.setBasePackage("com/dao");
        return ms;
    }
}

xml

@Configuration
@ComponentScan("com")
@PropertySource("cp.properties")
@Import({ Mybatis.class,jdbc.class})
public class xml {
}

7.5、程序使用

public class app {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(xml.class);
        userService bean = context.getBean(userService.class);
//        UserMapper bean = context.getBean(UserMapper.class);
        user userId = bean.getUserIds(2);
        System.out.println(userId);
    }
}

7.6、资源设置

jdbc.name = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;characterEncoding=UTF-8&amp;useUnicode=true&amp;serverTimezone=GMT
jdbc.root = root
jdbc.password = 123456

7.7、pom设置

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.17</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>RELEASE</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>6.1.5</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>6.1.5</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.2.16</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>3.0.3</version>
    </dependency>
</dependencies>
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

理解:Mybatis为主体框架,首先是dao的设计,确定要使用的方法,可以在dao中的接口用注解的方法进行实现,也可以用xml进行代码操作,然后设计数据库的类型在pojo中完成,在service中引入dao(通过依赖注入),最重要的在zhujie中进行整体框架的构建,xml实现内置资源,jdbc完成数据库操作,mybatis完成Mybatis的操作,再整体导入xml中,整个程序只要调用xml和需要的service类就能进行

8、spring整合junit(测试类进行)

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = xml.class)
public class userTest extends TestCase {
    @Autowired
    private UserMapper userMapper ;
    @Test
    public void testID(){
        user userId = userMapper.getUserId(2);
        System.out.println(userId);
    }
}

前两个类是为了要自动装配的完成

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = xml.class)

八、AOP(面向切面程序)

8.1、基础知识

连接点:可以是程序执行时的任意位置

在springboot中可以特指方法的执行

切入点:需要进行匹配的方法

通知:需要加入的信息写在里面

切面:描述通知与切入点的对应关系

在这里插入图片描述

8.2、基础程序的创建

在这里插入图片描述

1、myadvice

@Component
@Aspect
public class myadvice {
    @Pointcut("execution(void com.service.AopService.updates())")
    private void pd(){}

    @Before("pd()")
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}

@Component 设置为bean方法已进行实现

@Aspect 设置整个 类型为切面

@Pointcut(“execution(void com.service.AopService.updates())”) 设置切面的位置

void表示类型 后面到具体位置的方法

private void pd(){} 别名的设置,相当于将所在位置的方法设置为这个别名

@Before(“pd()”) 设置执行的顺序

public void method(){
System.out.println(System.currentTimeMillis());
}

设置要实现的方法

2、xml

@Configuration
@ComponentScan("com")
@EnableAspectJAutoProxy()
public class xml {
}

@EnableAspectJAutoProxy() 开启aspects的自动代理

8.3、工作流程

在这里插入图片描述

代理表现

在这里插入图片描述

System.out.println(bean.getClass());

bean.getClass获取的内容即可查看是否为代理对象

8.4、AOP表达式的格式

1、切入点的两种表达方式

类中:

@Pointcut("execution(void com.service.AopService.updates())")

接口中:

@Pointcut("execution(void com.service.impl.AOpServiceimpl.updates())")

2、标准格式

在这里插入图片描述

注意:方法返回类型千万不能忘记

3、 符号代替描述

1、*

在这里插入图片描述

可以代替一整个类或方法,也可以代替后缀前缀

2、…

在这里插入图片描述

…匹配的范围更大,可以将多个类路径一起描述,也可以说明是否有值,不用像*必须确定个数

3、书写技巧

描述返回类型为public时可以省略不写

返回类型为增删改时用精准匹配,为查询时用*匹配

包名中尽量不使用…,匹配效率太低

接口名采用 * 匹配,如*service

8.5、AOP的通知类型

1、前置通知

@Before()

在事务的前面进行实现

2、后置通知

@After

在事务的后面进行

3、环绕通知(重点)

@Around("pd()")
public Object method(ProceedingJoinPoint pro) throws Throwable {
    System.out.println(System.currentTimeMillis());
    Object proceed = pro.proceed();
    System.out.println(System.currentTimeMillis());
    return proceed;
}

可以设置事务在语句中进行

ProceedingJoinPoint pro代表设置的对象

Object用于设置返回值,记得类型的改变上面的void的类型也要改变

4、返回值后通知

@AfterReturning

用于有返回值后再给通知,保异常不给

5、报错后通知

@AfterThrowing

用于有报错后再进行通知,没有报错则不进行

8.6、AOP中获取参数和返回参数

1、AOP中获取类型和名字

@Pointcut("execution(* com.service.impl.userService.*(..))")
private void pd(){}

@Around("pd()")
public void method(ProceedingJoinPoint pro) throws Throwable {
    long t1 = System.currentTimeMillis();
    Signature signature = pro.getSignature();
    Class declaringType = signature.getDeclaringTypeName().getClass();
    String name = signature.getName();
    for(int i=0;i<10000;i++)
        pro.proceed();
    long t2 = System.currentTimeMillis();
    System.out.println("该"+declaringType+":"+name+"---------->"+"执行"+(t2-t1)+"ms");
}

Signature signature = pro.getSignature();为引用该类型

Class declaringType = signature.getDeclaringTypeName().getClass(); 获取类型名

String name = signature.getName();获取名字

2、获取参数值

@After("pd()")
public void method(JoinPoint jp){
    Object[] args = jp.getArgs();
    System.out.println("输入的值为:"+ Arrays.toString(args));
}

Arrays.toString(args)需要加这个进行转换

通过getArgs进行完成

3、将返回值进行改变

@Around("pd()")
public Object method(ProceedingJoinPoint pro) throws Throwable {
    Object[] args = pro.getArgs();
    System.out.println(Arrays.toString(args));
    args[0] = 10;
    Object proceeds = pro.proceed(args);
    return proceeds;
}

重新设置过后通过proceed重新传回去

4、获取返回值数据

@AfterReturning(value = "pd()",returning = "i")
public void method(int i){
    System.out.println("js:"+i);
}

有返回值后输出,可以自己设置类型

@AfterThrowing(value = "pd()",throwing = "jps")
public void method(Throwable jps){
    System.out.println("异常:"+jps);
}

有异常的时候输出,可以在around中进行

九、事务管理

原理:在数据操作时同成功,同失败

作用:比如银行转账时,需要一个账户扣钱,一个加钱,如果出现异常的情况这个过程就可能出错,所以可以用事务进行管理

9.1、实现条件:

1、在接口或类中添加事务

@Transactional
public void transfor(String out,String in,int money);

2、在 配置文件中指明位置

@Configuration
@ComponentScan("com")
@PropertySource("cp.properties")
@Import({ Mybatis.class,jdbc.class})
@EnableTransactionManagement

3、在数据库中进行操作

public PlatformTransactionManager platformTransactionManager(DataSource dataSource){
    DataSourceTransactionManager dataSourceTransactionManager =  new DataSourceTransactionManager();
    dataSourceTransactionManager.setDataSource(dataSource);
    return dataSourceTransactionManager;
}

9.2、事务的方法使用

在这里插入图片描述

@Transactional(readOnly = true)

可以直接进行设置

rollbackFor的使用主要是因为有两个异常不会进行数据回滚,需要进行设置

9.3、事务的传播

在这里插入图片描述

事务是可以通过设置来确定是否传播的

@Transactional(propagation = Propagation.REQUIRES_NEW)

这个就是创建一个新的事物管理员,跟之前的事物进行分开

SUPPORTS是有事物管理员时就加入,没有就不创建

NOT_SUPPORTS是无论如何都不创建事务

MANDATORY是有事务就加入,没有就报错

NEVER是没有事务

这个是我之前在学习过程中所写的笔记,可能其中的内容会有一些缺漏之处,欢迎大家在评论区里面进行指出,另外这篇博文只是将spring部分进行粗略的写出,详细部分可以去看一下我的Spring模块下的其他内容,后续的SpringMvc和SpringBoot会在后面的文章中进行发表

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值