柏竹 柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档

柏竹

奋斗柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档
  • Java基础

  • JavaWeb

  • 拓展技术

  • 框架技术

  • 数据库

  • 数据结构

  • Spring

    • Spring
    • Spring IOC
    • Spring AOP
    • Spring拓展
      • SpringJDBC实现
      • Spring事务管理
        • 事务管理接口
        • xml应用
        • Annotation应用
  • SpringMVC

  • SpringBoot

  • SpringClound

  • Ruoyi-Vue-Plus

  • 后端
  • Spring
柏竹
2021-07-08
目录

Spring拓展

# Spring拓展

# SpringJDBC实现

Spring 针对数据库开发提供了 JdbcTemplate 类,它封装了 JDBC,支持对数据库的所有操作

JDBC以往的说明:Java学习记录 JDBC篇 (opens new window)

Class JdbcTemplate

org.springframework.jdbc.core.JdbcTemplate

方法

修饰符 返回 方法 说明
public int update(String sql) 用于执行新增、修改、删除等语句
public int update(String sql,Object... args) 用于执行新增、修改、删除等语句 args 表示需要传入的参数
public void execute(String sql) 可以执行任意 SQL,一般用于执行 DDL 语句 action 表示执行完 SQL 语句后,要调用的函数
public T query(String sql, ResultSetExtractor rse) 用于执行查询语句 以 ResultSetExtractor 作为参数的 query 方法返回值为 Object
public List query(String sql, RowMapper rse) 使用查询结果需要对其进行强制转型 以 RowMapper 作为参数的 query 方法返回值为 List
public Map<String, Object> queryForMap(String sql) SQL查询多个聚合函数结果值,查询出的结果值形式:key-value

JDBC应用

  1. 导入包 spring-jdbc-x.x.x.jar 、spring-tx-x.x.x.jar 以下为个人用Maven配置

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.2.13.RELEASE</version>
    </dependency>
    
  2. 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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <!--    XML 配置数据源-->
        <bean id="dateSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <!--驱动加载-->
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <!--连接数据库的url  . 本次连接 test库-->
         	<!--指定IP地址 、 库(个人应用的 test库)-->   
            <property name="url" value="jdbc:mysql://192.168.74.131/test"/>
            <property name="username" value="root"/>
            <property name="password" value="root"/>
        </bean>
    
    <!--    配置jdbc模板-->
        <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <!--必须使用数据源-->
            <property name="dataSource" ref="dateSource"/>
        </bean>
    
    <!--    配置注入类使用-->
        <bean id="xxx" class="xxx">
            <property name="jdbcTemplate" ref="jdbcTemplate"/>
        </bean>
    <!--	例如:-->
    <!--    <bean id="studentDao" class="com.StudentDao">-->
    <!--        <property name="jdbcTemplate" ref="jdbcTemplate"/>-->
    <!--    </bean>-->
    	...
    </beans>
    

    配置注入类需要自己指定类进行配置

  3. 创建实体类 Student

    package com;
    
    public class Student {
        int id ;
        String name;
        int age;
        
        public Student() {
        }
        
        public Student(int id , String name , int age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
        
        public Student(String name , int age) {
            this.name = name;
            this.age = age;
        }
        
        public int getAge() {
            return age;
        }
        
        public void setAge(int age) {
            this.age = age;
        }
        
        public int getId() {
            return id;
        }
        
        public void setId(int id) {
            this.id = id;
        }
        
        public String getName() {
            return name;
        }
        
        public void setName(String name) {
            this.name = name;
        }
        
        @Override
        public String toString() {
            return "Student{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
  4. 数据库 test库引入库

    id name age
    DROP TABLE IF EXISTS `student`;
    CREATE TABLE `student`  (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `age` int(11) NULL DEFAULT 16,
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
    
  5. 指定类注入使用 JdbcTemplate类 (应用指定实例 StudentDao;实现一个操作业务即可)

    package com;
    
    import org.springframework.dao.DataAccessException;
    import org.springframework.jdbc.core.ResultSetExtractor;
    import org.springframework.jdbc.core.RowMapper;
    import org.springframework.jdbc.core.support.JdbcDaoSupport;
    
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.List;
    import java.util.Map;
    
    public class StudentDao extends JdbcDaoSupport {
        
        //方法封装
        public Student turnEncapsulation(ResultSet resultSet) throws SQLException {
            Student student = new Student();
            student.setId(resultSet.getInt("id"));
            student.setName(resultSet.getString("name"));
            student.setAge(resultSet.getInt("age"));
            return student;
        }
        
        /**
         * 添加数据
         * @param student 学生类封装
         * @return 更变条数
         */
        public int insert(Student student) {
            if (student == null) {
                return 0;
            } 
            String sql = "INSERT INTO student(name,age) VALUE(?,?)";
            return this.getJdbcTemplate().update(sql,student.getName(),student.getAge());
        }
        
        /**
         * 删除数据
         * @param id 删除指定id
         * @return 更变条数
         */
        public int delete(int id) {
            String sql = "DELETE FROM student WHERE id = ?";
            return this.getJdbcTemplate().update(sql,id);
        }
        
        /**
         * 更变数据
         * @param id 指定学生id
         * @param student 更变指定 学生类
         * @return 更变条数
         */
        public int update(int id , Student student) {
            String sql = "UPDATE student set name=?,age=? WHERE id=?";
            return this.getJdbcTemplate().update(sql,student.getName(),student.getAge(),id);
        }
        
        /**
         * 查询所有条数
         * @return 学生队列
         */
        public List<Student> queryAll(){
            String sql = "SELECT * FROM student";
            /* 原型
            return this.getJdbcTemplate().query(sql , new RowMapper<Student>() {
               @Override
               public Student mapRow(ResultSet resultSet , int i) throws SQLException{
                   System.out.println("\ti : " + i);
                   return turnEncapsulation(resultSet);
               }
            });
    		*/
            // 简写 
            return this.getJdbcTemplate().query(sql, (rs,i) -> turnEncapsulation(rs));
        }
        
        /**
         * 查询指定学生
         * @param id 指定学生id
         * @return 学生队列
         */
        public List<Student> queryFindById(int id) {
            String sql = "SELECT * FROM student WHERE id = ?";
            return this.getJdbcTemplate().query(sql,new Object[]{id}, new RowMapper<Student>() {
                @Override
                public Student mapRow(ResultSet resultSet , int i) throws SQLException {
                    System.out.println("\ti : " + i);
                    return turnEncapsulation(resultSet);
                }
            });
        }
        
        /**
         * 查询指定学生名称
         * @param name 名称
         * @return 学生队列
         */
        public List<Student> queryFindByName(String name) {
            String sql = "SELECT * FROM student WHERE name = ?";
            //匿名 new RowMapper<Student>() 替换为 lambda
            return this.getJdbcTemplate().query(sql,new Object[]{name}, (resultSet , i) -> {
                System.out.println("\ti : " + i);
                return turnEncapsulation(resultSet);
            });
        }
        
        /**
         * 聚合函数应用
         */
        /**
         * 获取学生总数
         * @return 学生总数
         */
        public int tableSize(){
            String sql = "SELECT count(id) FROM student";
            return this.getJdbcTemplate().queryForObject(sql,Integer.class);
        }
        
        /**
         * 学生首尾id
         * @return MAP形式返回id首尾
         */
        public Map<String , Object> tableMaxMin(){
            String sql = "SELECT max(id),min(id) FROM student";
            return this.getJdbcTemplate().queryForMap(sql);
        }
        
    }
    
  6. 测试类 (测试业务)

    package com;
    
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.jdbc.core.JdbcTemplate;
    
    import java.beans.PropertyVetoException;
    import java.util.List;
    import java.util.Map;
    
    //连接测试
    public class connectionMySQL {
    
        ApplicationContext ac = new ClassPathXmlApplicationContext("springJDBC.xml");
        StudentDao dao = (StudentDao) ac.getBean("studentDao");
        
        /**
         * xml应用
         */
        @Test
        public void test01_Insert(){
            int insert = dao.insert(new Student("老哥" , 23));
            System.out.println("insert : " + insert);
        }
        @Test
        public void test02_Delete() {
            int delete = dao.delete(19);
            System.out.println("delete : " + delete);
            
        }
        @Test
        public void test03_Update() {
            int update = dao.update(16,new Student("黑马",32));
            System.out.println("update : " + update);
        }
        @Test
        public void test04_Query() {
            List<Student> student = dao.queryFindById(17);
            System.out.println("student : " + student);
        }
        @Test
        public void test04_Querys() {
            List<Student> students = dao.queryAll();
            // List<Student> students = dao.queryFindByName("李四");
            for (Student student : students) {
                System.out.println(student.toString());
            }
        }
        @Test
        public void test05_group(){
            int i = dao.tableSize();
            System.out.println("i : " + i);
            System.out.println("==============");
            Map<String, Object> stringObjectMap = dao.tableMaxMin();
            System.out.println("stringObjectMap : " + stringObjectMap);
        }
        
    }
    

# Spring事务管理

事务(Transaction)是面向关系型数据库(RDBMS)企业应用程序的重要组成部分,用来确保数据的完整性和一致性。

事务了解 :MySQL学习记录 事务篇 (opens new window)

Spring 实现声明式事务管理主要有 2 种方式:

  • 基于 XML 方式的声明式事务管理
  • 通过 Annotation 注解方式的事务管理

# 事务管理接口

Spring 的事务管理 :PlatformTransactionManager、TransactionDefinition 是事务主要核心接口

PlatformTransactionManager接口

该接口用于管理事务。其主要用于完成事务的提交、回滚,及获取 事务的状态信息

public interface PlatformTransactionManager extends TransactionManager {
    TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException;

    void commit(TransactionStatus var1) throws TransactionException;

    void rollback(TransactionStatus var1) throws TransactionException;
}
返回 抽象方法 说明
TransactionStatus getTransaction(@Nullable TransactionDefinition var1) 获取事务的状态信息
void commit(TransactionStatus var1) 提交事务
void rollback(TransactionStatus var1) 回滚事务

TransactionDefinition接口

该接口主要获取事务相关信息的作用

public interface TransactionDefinition {
    ....

    default int getPropagationBehavior() {
        return 0;
    }

    default int getIsolationLevel() {
        return -1;
    }

    default int getTimeout() {
        return -1;
    }

    default boolean isReadOnly() {
        return false;
    }

    @Nullable
    default String getName() {
        return null;
    }
	....
}
返回 抽象方法 说明
int getPropagationBehavior() 获取事务的 传播行为
int getIsolationLevel() 获取事务的 隔离级别
int getTimeout() 获取事务的 超时时间
boolean isReadOnly() 获取事务是否 只读
String getName() 获取事务的 名称

属性说明

事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。

传播行为名称值 说明
PROPAGATION_MANDATORY 支持当前事务,如果不存在当前事务,则引发异常
PROPAGATION_NESTED 如果当前事务存在,则在嵌套事务中执行
PROPAGATION_NEVER 不支持当前事务,如果当前事务存在,则引发异常
PROPAGATION_NOT_SUPPORTED 不支持当前事务,始终以非事务方式执行
PROPAGATION_REQUIRED 默认传播行为,支持当前事务,如果不存在,则创建一个新的
PROPAGATION_REQUIRES_NEW 创建新事务,如果已存在事务则暂停当前事务,应用新的
PROPAGATION_SUPPORTS 支持当前事务,如果不存在事务,则以非事务方式执行

# xml应用

主要配置组件(.xml)

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <!--            <tx:method name="insert*" propagation="REQUIRED"/>-->
        <!--            <tx:method name="add*" propagation="REQUIRED"/>-->
        <!--            <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>-->
        <tx:method name="*" />
    </tx:attributes>
</tx:advice>
<!--   aop编写,让Spring自动对目标生成代理,需要使用AspectJ的表达式 -->
<aop:config>
    <aop:pointcut id="pt" expression="execution(* com.service..*.*(..))"/>
    <aop:advisor advice-ref="txAdvice"  pointcut-ref="pt" />
</aop:config>

应用前提:

添加依赖

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.6</version>
</dependency>

实体类:(Student)

package com;

public class Student {
    int id ;
    String name;
    int age;
    
    public Student() {
    }
    
    public Student(int id , String name , int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    
    public Student(String name , int age) {
        this.name = name;
        this.age = age;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
    
    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

StudentDao类:(信息交互类)

package com.dao;

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

public class StudentDao extends JdbcDaoSupport {
    
    /**
     * 添加数据
     * @param student 学生类封装
     * @return 更变条数
     */
    public int insert(Student student) {
        if (student == null) {
            return 0;
        }
        String sql = "insert into student(name,age) value(?,?)";
        return this.getJdbcTemplate().update(sql,student.getName(),student.getAge());
    }
    
    //其他业务操作省略
    ····
}

StudentService类:(业务处理类)

package com.service;

import com.Student;
import com.dao.StudentDao;

public class StudentService {
    
    private StudentDao studentDao;
    
    public void setStudentDao(StudentDao studentDao) {
        this.studentDao = studentDao;
    }
    
    public int insert(Student student){
        int a = studentDao.insert(student);
        System.out.println("(1)添加成功 数据: " + student + "\t影响条目:"+a);
        int aa = 1/0;   //制造异常
        student.setAge(student.getAge()+1);
        int b = studentDao.insert(student);
        System.out.println("(2)添加成功 数据: " + student + "\t影响条目:"+a);
        return a+b;
    }
}

Spring 容器配置:(.xml文件)

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

    <!--    XML 配置数据源-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
        <property name="jdbcUrl"
                  value="jdbc:mysql://192.168.6.129:3306/test?serverTimezone=UTC&amp;characterEncoding=utf8&amp;useUnicode=true&amp;useSSL=false"/>
        <property name="user" value="root"/>
        <property name="password" value="root"/>
    </bean>
    <!--    配置jdbc模板-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--    类注入应用-->
    <bean id="studentDao" class="com.dao.StudentDao">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>
    <bean id="studentService" class="com.service.StudentService">
        <property name="studentDao" ref="studentDao"/>
    </bean>

    <!--    事务管理器-->
    <bean id="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="insert*" propagation="REQUIRED"/>-->
            <!--            <tx:method name="add*" propagation="REQUIRED"/>-->
            <!--            <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>-->
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>
    <!--   aop编写,让Spring自动对目标生成代理,需要使用AspectJ的表达式 -->
    <aop:config>
        <aop:pointcut id="pt" expression="execution(* com.service..*.*(..))"/>
        <aop:advisor advice-ref="txAdvice"  pointcut-ref="pt" />
    </aop:config>

</beans>

测试:

@Test
public void test_XML(){
    
    ApplicationContext ac = new ClassPathXmlApplicationContext("SpringConfig.xml");
   
    StudentService service = (StudentService) ac.getBean("studentService");
    
    //在studentService类 会异常回滚 
    int number = service.insert(new Student("李四" , 33));
    System.out.println("number : " + number);

}

# Annotation应用

主要组件

@Transactional

@Transactional常用属性

属性名 说明
propagation 配置 事务传播行为
isolation 配置 事务隔离级别
readOnly 配置 事务是否只读
timeout 配置 事务超时事件(单位: s)

应用前提:

  • 添加事务管理

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
  • 注册加载驱动

    <tx:annotation-driven transaction-manager="txManager"/>
    
  • 应用方法需要添加 @Transactional 注解

实体类:(Student)

package com;

public class Student {
    int id ;
    String name;
    int age;
    
    public Student() {
    }
    
    public Student(int id , String name , int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    
    public Student(String name , int age) {
        this.name = name;
        this.age = age;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
    
    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

StudentDao类:(信息交互类)

package com.dao;

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

public class StudentDao extends JdbcDaoSupport {
    
    /**
     * 添加数据
     * @param student 学生类封装
     * @return 更变条数
     */
    public int insert(Student student) {
        if (student == null) {
            return 0;
        }
        String sql = "insert into student(name,age) value(?,?)";
        return this.getJdbcTemplate().update(sql,student.getName(),student.getAge());
    }
    
    //其他业务操作省略
    ····
}

StudentService类:(业务处理类)

package com.service;

import com.Student;
import com.dao.StudentDao;
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
public class StudentService {
    
    //注入类
    @Autowired
    private StudentDao studentDao;
    
    //事务配置
    @Transactional(propagation = Propagation.REQUIRED , rollbackFor = {Exception.class})
    public int insert(Student student){
        int a = studentDao.insert(student);
        System.out.println("(1)添加成功 数据: " + student + "\t影响条目:"+a);
        
        int aa = 1/0;   //制造异常
        
        student.setAge(student.getAge()+1);
        int b = studentDao.insert(student);
        System.out.println("(2)添加成功 数据: " + student + "\t影响条目:"+a);
        return a+b;
    }
    
}

Spring 容器配置:(.xml文件)

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

    <!--    XML 配置数据源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!--驱动加载-->
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <!--连接数据库的url  . 本次连接 test库-->
        <property name="url" value="jdbc:mysql://192.168.6.129/test"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
    <!--    配置jdbc模板-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--必须使用数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
	
    <!--扫描包-->
    <context:component-scan base-package="com"/>
<!--    事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
<!--    事务应用-->
    <bean id="studentDao" class="com.dao.StudentDao">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>
	<!--以注解形式应用-->
    <tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

测试:

 @Test
public void test_Annotation() {
    ApplicationContext ac = new ClassPathXmlApplicationContext("SpringConfig_Annotation.xml");
    StudentServic service = (StudentService) ac.getBean("");

    int number = service_annotation.insert(new Student("赵六" , 34));
    System.out.println("number : " + number);
    
}
#spring
上次更新: 2023/03/12, 00:43:49

← Spring AOP SpringMVC→

最近更新
01
HTTPS自动续签
10-21
02
博客搭建-简化版(脚本)
10-20
03
ruoyi-vue-plus-部署篇
07-13
更多文章>
Theme by Vdoing | Copyright © 2019-2024 | 桂ICP备2022009417号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式