JAVAEE框架整合技术之spring03-SpringJdbcTemplate模板技术和事务处理

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: JAVAEE框架整合技术之spring03-SpringJdbcTemplate模板技术和事务处理

SpringJdbcTemplate

Spring的JdbcTemplate是一个对JDBC的模板封装,它提供了一套JDBC的模板,能让我们写持久层代码时减少多余的代码,简化JDBC代码,使代码看起来更简洁。在介绍Spring的JdbcTemplate使用方法之前我们先来讨论一个问题,以下这是一段常见的往数据库写入数据的JDBC代码:

public int jdbcInsert(Student student) throws SQLException {
    Connection connection = null;
    try {
        connection = dataSource.getConnection();
        String sql = "INSERT INTO student(sname,age,sex,address) VALUES (?,?,?,?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setString(1, student.getName());
        preparedStatement.setInt(2, student.getAge());
        preparedStatement.setString(3, student.getSex());
        preparedStatement.setString(4, student.getAddress());
        return preparedStatement.executeUpdate();
    } finally {
        connection.close();
    }
}
public int jdbcUpdate(Student student) throws SQLException {
    Connection connection = null;
    try {
        connection = dataSource.getConnection();
        String sql = "UPDATE student SET sname=?,age=?,sex=?,address=?";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setString(1, student.getName());
        preparedStatement.setInt(2, student.getAge());
        preparedStatement.setString(3, student.getSex());
        preparedStatement.setString(4, student.getAddress());
        return preparedStatement.executeUpdate();
    } finally {
        connection.close();
    }
}

从如上的代码中,可以看到两个方法中基本99%的代码都是重复的,除了sql语句之外,都是重复的代码,重复的代码就是坏味道,会让我们的产生大量的冗余代码,不易于维护和修改,而且写起来还累。

所以Spring提供的JdbcTemplate正是用来解决这个问题的,其实Spring的JDBCTemplate有点像DBUtils,但是有时候还没有DBUitls好用。这里来学习一下使用Spring的JdbcTemplate来玩一下CRUD,毕竟JdbcTemplate在实际开发中一般不会使用,通常都是使用Mybatis、Hibernate等成熟、优秀的数据持久层框架,不过还是得知道Spring有一个这样的jdbc模板类

添加依赖

spring核心包4+2 jdbc模板包2个

<!--spring-jdbc-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.9.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>5.2.9.RELEASE</version>
</dependency>

测试

@Test
public void test(){
    //构建数据源
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql:///test");
    dataSource.setUsername("root");
    dataSource.setPassword("root");
  //获取对象
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);    
    //创建表
    jdbcTemplate.execute("create table test01(name varchar(10) )");
}

Spring配置数据源

目标:将数据源和jdbcTemplate都交给Spring来管理:

在applicationContext.xml中配置dataSource连接池和jdbcTemplate模版对象。

spring内置数据源

<!--spring内置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql:///test"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>
</bean>
<!--jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class JdbcTempleTest {
    //注入jdbcTemplate
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Test
    public void test(){
        this.jdbcTemplate.execute("create table jdbctest05(name varchar(10))");
    }
}

dbcp数据源

Apache commons-dbcp 需要导入dbcp包和 pool包

添加依赖

<dependency>
  <groupId>commons-dbcp</groupId>
  <artifactId>commons-dbcp</artifactId>
  <version>1.4</version>
</dependency>
<!--dbcp数据源-->
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql:///test"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>
</bean>
<!--jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource2"/>
</bean>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class JdbcTempleTest {
    //注入jdbcTemplate
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Test
    public void test(){
        this.jdbcTemplate.execute("create table jdbctest06(name varchar(10))");
    }
}

C3P0 数据源

<dependency>
  <groupId>com.mchange</groupId>
  <artifactId>c3p0</artifactId>
  <version>0.9.5.2</version>
</dependency>
<!--c3p0数据源-->
<bean id="dataSource3" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl" value="jdbc:mysql:///test"/>
    <property name="user" value="root"/>
    <property name="password" value="root"/>
</bean>
<!--jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource3"/>
</bean>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class JdbcTempleTest {
    //注入jdbcTemplate
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Test
    public void test(){
        this.jdbcTemplate.execute("create table jdbctest07(name varchar(10))");
    }
}

Druid数据源

<!--druid-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.3</version>
</dependency>
<!--druid数据源-->
<bean id="dataSource4" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql:///test"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>
    <!--最大连接数-->
    <property name="maxActive" value="5"/>
    <!--最小连接数-->
    <property name="minIdle" value="1"/>
</bean>
<!--jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource4"/>
</bean>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class JdbcTempleTest {
    //注入jdbcTemplate
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Test
    public void test(){
        this.jdbcTemplate.execute("create table jdbctest07(name varchar(10))");
    }
}
  • 相关配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F5402RTk-1664592948340)(assets/image-20211217000623540.png)]

外部属性文件的配置

  • db.properties
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.jdbcurl=jdbc:mysql:///test?serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=root
  • applicationContext.xml
<!--引入外部的文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!--druid数据源-->
<bean id="dataSource4" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driverClass}"/>
    <property name="url" value="${jdbc.jdbcurl}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <!--最大连接数-->
    <property name="maxActive" value="5"/>
    <!--最小连接数-->
    <property name="minIdle" value="1"/>
</bean>

基于JdbcTemplate实现CURD

数据库准备

CREATE TABLE `t_book` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `price` decimal(10,2) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

查询

实体类

@Data
public class Book {
    private Integer id;
    private String name;
    private Double price;
}

dao层

/**
 * @Auther: yanqi
 * @Desc: 继承 JdbcDaoSupport类,父类中已注入JdbcTemplate对象
 */
public class BookDao extends JdbcDaoSupport {
    /**
     * 查询所有
     */
    public List<Book> queryAll(){
        return super.getJdbcTemplate().query("select * from t_book", new BeanPropertyRowMapper<>(Book.class));
    }
}

数据源

<!--引入外部的配置文件db.properties-->
<context:property-placeholder location="classpath:db.properties"/>
<!--Druid连接池-->
<bean id="dataSource4" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driverClass}"/>
    <property name="url" value="${jdbc.jdbcurl}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
<!--dao层-->
<bean id="bookDao" class="cn.yanqi.dao.BookDao">
    <property name="dataSource" ref="dataSource4"/>
</bean>
  • db.properties
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcurl=jdbc:mysql:///test
jdbc.username=root
jdbc.password=root
  • 测试
/**
 * @Auther: yanqi
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class JdbcTemplateTest {
    @Autowired
    private BookDao bookDao;
    @Test
    public void test2(){
        List<Book> books = this.bookDao.queryAll();
        for(Book book : books){
            System.out.println(book);
        }
    }
}

实现增加、删除、修改功能

/**
 * 添加
 */
public void addBook(Book book){
    String sql = "insert into t_book(id,name,price) values(null,?,?)";
    super.getJdbcTemplate().update(sql,book.getId(),book.getName(),book.getPrice());
}
/**
 * 删除
 */
public void deleteBook(Integer id){
    String sql = "delete from t_book where id = ?";
    super.getJdbcTemplate().update(sql,id);
}
/**
 * 修改
 */
public void updateBook(Book book){
    String sql = "update t_book set name = ? where id = ?";
    super.getJdbcTemplate().update(sql,book.getName(),book.getId());
}

Spring事务管理

基于_XML的事务管理

编写转账案例,引出事务问题

  • 数据库准备
CREATE TABLE `t_account` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `money` double DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

spring-transaction

  • 添加依赖
<dependencies>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.2.3</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.6.4</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.2.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.2.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.2.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.2.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
  • dao层
public class AccountDao extends JdbcDaoSupport {
    public void out(String outName , double money){
        String sql = "update t_account set money = money - ? where name = ?";
        this.getJdbcTemplate().update(sql,money,outName);
    }
    public void in(String inName , double money){
        String sql = "update t_account set money = money + ? where name = ?";
        this.getJdbcTemplate().update(sql,money,inName);
    }
}
  • service层
public class AccountService {
    private AccountDao accountDao;
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
    public void tranfar(String outName , String  inName , double money){
        this.accountDao.out(outName,money);
        int a = 1/0;
        this.accountDao.in(inName,money);
    }
}
  • db.properties
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///test
jdbc.username=root
jdbc.password=root
  • applicationContext.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:aop="http://www.springframework.org/schema/aop"
       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/aop
   http://www.springframework.org/schema/aop/spring-aop.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context.xsd">
    <!--引入外部的文件-->
    <context:property-placeholder location="classpath:db.properties"/>
    <!--druid数据源-->
    <bean id="dataSource4" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driverClass}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <!--最大连接数-->
        <property name="maxActive" value="5"/>
        <!--最小连接数-->
        <property name="minIdle" value="1"/>
    </bean>
    <!--dao-->
    <bean id="accountDao" class="cn.yanqi.dao.AccountDao">
        <property name="dataSource" ref="dataSource4"/>
    </bean>
    <!--service-->
    <bean id="accountService" class="cn.yanqi.service.AccountService">
        <property name="accountDao" ref="accountDao"/>
    </bean>
</beans>
  • 测试
@RunWith(SpringRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class AccountServiceTest {
    @Autowired
    private AccountService accountService;
    @Test
    public void tranfar() {
        this.accountService.tranfar("jack","rose",100);
    }
}
发现事务管理问题:没有事务的情况下,如果出现异常,则会转账不成功,数据异常。
扩展:如果不配置事务,那么每一个数据库的操作都是单独的一个事务。

加入事务

  • 添加tx事务约束
<?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
   http://www.springframework.org/schema/context/spring-context.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop.xsd
   http://www.springframework.org/schema/tx 
   http://www.springframework.org/schema/tx/spring-tx.xsd">
  • 事务控制
<!--事务平台管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource4"/>
    </bean>
    <!--配置事务方法-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--
                name:事务所管理的方法
                isolation: 事务隔离级别,默认值DEFAULT,使用的是数据库的默认隔离级别(mysql默认隔离级别:repeatable read 可重重读)
                propagation: 事务传播形为,默认值REQUIRED  支持当前事务, A调用B,如果A事务存在,B和A处于同一个事务
                timeout:事务超时时间(单位是秒),默认值-1,使用的数据库的超时时间
                rollback-for: 指哪些异常可以回滚
                no-rollback-for: 指哪些异常不回滚,其他都回滚
            -->
            <tx:method name="transactionAccount"
                       isolation="DEFAULT"
                       propagation="REQUIRED"
                       timeout="-1"
                       rollback-for=""
                       no-rollback-for=""/>
            <!--<tx:method name="update*"/>-->
            <!--<tx:method name="save*"/>-->
        </tx:attributes>
    </tx:advice>
    <!--配置aop-->
    <aop:config>
        <!--切入点-->
        <aop:pointcut id="txPointcut" expression="bean(*Service)"/>
        <!--切面-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
    </aop:config>
</beans>
  • 测试
/**
 * @Auther: yanqi
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class AccountServiceTest {
    @Autowired
    private AccountService accountService;
    @Test
    public void transactionAccount() {
        this.accountService.transactionAccount("jack","rose",100.0);
    }
}

遇到异常不回滚(相当于没有事务)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kb1d6f3J-1664592948342)(assets/image-20211217202707415.png)]

事务的传播行为PropagationBehavior

什么是事务的传播行为?

一个事务调用了另 一个事务,如果出现错误,两个事务是否属于同一个事务

有什么作用?

事务传播行为用于解决两个被事务管理的方法互相调用问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JlTaNfFY-1664592948344)(assets/image-20211217202839587.png)]

  • 事务的传播行为的7种类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J1A4nxQU-1664592948345)(assets/image-20211217202857824.png)]

  • 主要分为三大类
 PROPAGATION_REQUIRED(默认值)、PROPAGATION_SUPPORTS、PROPAGATION_MANDATORY
支持当前事务, A调用B,如果A事务存在,B和A处于同一个事务 。
事务默认传播行为 REQUIRED。最常用的。
 PROPAGATION_REQUIRES_NEW、PROPAGATION_NOT_SUPPORTED、PROPAGATION_NEVER 
不会支持原来的事务 ,A调用B, 如果A事务存在, B肯定不会和A处于同一个事务。
常用的事务传播行为:PROPAGATION_REQUIRES_NEW
 PROPAGATION_NESTED
嵌套事务 ,只对DataSourceTransactionManager有效 ,底层使用JDBC的SavePoint机制,允许在同一个事务设置保存点,回滚保存点

基于_注解声明式事务

导入的依赖包跟xml方式一样

pring-transactional-ann

声明式事务

/**
 * @Auther: yanqi
 */
@Service
// @Transactional //当前类都会被 事务管理
public class AccountService {
    @Autowired
    private AccountDao accountDao;
    @Transactional //事务管理
    public void transactionAccount(String outName, String inName , Double money){
        this.accountDao.out(outName,money);
        int a = 1/0;
        this.accountDao.in(inName,money);
    }
}
  • dao层
/**
 * @Auther: yanqi
 * @Desc: 先用jdbcTemplate完成对数据库的操作
 */
@Repository
public class AccountDao extends JdbcDaoSupport {
    /**
     * 随便写一个set方法,注入DataSource,使用父数据源
     * @param dataSource
     */
    @Autowired
    public void setJdbcDaoSupport(DataSource dataSource){
        super.setDataSource(dataSource);
    }
    /**
     * 减钱
     */
    public void out(String name , Double money){
        String sql = "update t_account set money = money - ? where name = ?";
        super.getJdbcTemplate().update(sql,money, name);
    }
    /**
     * 加钱
     */
    public void in(String name , Double money){
        String sql = "update t_account set money = money + ? where name = ?";
        super.getJdbcTemplate().update(sql,money, name);
    }
}

配置注解事务

<!--开启注解-->
<context:component-scan base-package="cn.yanqi"/>
<!--引入外部的配置文件db.properties-->
<context:property-placeholder location="classpath:db.properties"/>
<!--Druid连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
<!--事务的平台管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
<!--开启事务的注解-->
<tx:annotation-driven transaction-manager="transactionManager"/>
  • 配置事务的定义属性信息,在注解中直接配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EpZrVRlh-1664592948346)(assets/image-20211217203126239.png)]

  • 优化配置

配置注解驱动事务管理的时候,tx:annotation-driven/默认会自动查找并加载名字为transactionManager的事务管理器Bean,因此,当事务管理器的bean的名字为transactionManager 时,可以省略transaction-manager的属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pNV522gW-1664592948347)

(assets/image-20211217203218262.png)]
taSource">


- **配置事务的定义属性信息,在注解中直接配置**
[外链图片转存中...(img-EpZrVRlh-1664592948346)] 
- **优化配置**
>配置注解驱动事务管理的时候,<tx:annotation-driven/>默认会自动查找并加载名字为transactionManager的事务管理器Bean,因此,当事务管理器的bean的名字为transactionManager 时,可以省略transaction-manager的属性
[外链图片转存中...(img-pNV522gW-1664592948347)]


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
12天前
|
存储 安全 Java
事件的力量:探索Spring框架中的事件处理机制
事件的力量:探索Spring框架中的事件处理机制
26 0
|
21天前
|
缓存 Java Spring
Spring 框架中 Bean 的生命周期
Spring 框架中 Bean 的生命周期
30 1
|
1月前
|
开发框架 安全 Java
Spring 框架:企业级应用开发的强大工具
在当今数字化时代,企业级应用开发的需求日益增长。为了满足这一需求,开发者们需要一款功能强大、易于使用的开发框架。Spring 框架作为 Java 领域的领先者,为企业级应用开发提供了全面的解决方案。本文将深入探讨 Spring 框架的各个方面,包括其历史、核心模块、优势以及应用场景。
23 0
|
4天前
|
安全 Java API
第5章 Spring Security 的高级认证技术(2024 最新版)(上)
第5章 Spring Security 的高级认证技术(2024 最新版)
29 0
|
5天前
|
Java 关系型数据库 MySQL
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
UWB (ULTRA WIDE BAND, UWB) 技术是一种无线载波通讯技术,它不采用正弦载波,而是利用纳秒级的非正弦波窄脉冲传输数据,因此其所占的频谱范围很宽。一套UWB精确定位系统,最高定位精度可达10cm,具有高精度,高动态,高容量,低功耗的应用。
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
|
20天前
|
开发框架 安全 Java
探索 Spring 框架:企业级应用开发的强大工具
探索 Spring 框架:企业级应用开发的强大工具
19 1
|
25天前
|
Java 应用服务中间件 Maven
SpringBoot 项目瘦身指南
SpringBoot 项目瘦身指南
40 0
|
2月前
|
缓存 Java Maven
Spring Boot自动配置原理
Spring Boot自动配置原理
48 0
|
1月前
|
缓存 安全 Java
Spring Boot 面试题及答案整理,最新面试题
Spring Boot 面试题及答案整理,最新面试题
111 0
|
1月前
|
前端开发 搜索推荐 Java
【Spring底层原理高级进阶】基于Spring Boot和Spring WebFlux的实时推荐系统的核心:响应式编程与 WebFlux 的颠覆性变革
【Spring底层原理高级进阶】基于Spring Boot和Spring WebFlux的实时推荐系统的核心:响应式编程与 WebFlux 的颠覆性变革

热门文章

最新文章