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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 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)]


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
12天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
562 7
|
8天前
|
存储 缓存 Java
在Spring Boot中使用缓存的技术解析
通过利用Spring Boot中的缓存支持,开发者可以轻松地实现高效和可扩展的缓存策略,进而提升应用的性能和用户体验。Spring Boot的声明式缓存抽象和对多种缓存技术的支持,使得集成和使用缓存变得前所未有的简单。无论是在开发新应用还是优化现有应用,合理地使用缓存都是提高性能的有效手段。
15 1
|
9天前
|
XML 前端开发 Java
控制spring框架注解介绍
控制spring框架注解介绍
|
9天前
|
存储 NoSQL Java
Spring Session框架
Spring Session 是一个用于在分布式环境中管理会话的框架,旨在解决传统基于 Servlet 容器的会话管理在集群和云环境中的局限性。它通过将用户会话数据存储在外部介质(如数据库或 Redis)中,实现了会话数据的跨服务器共享,提高了应用的可扩展性和性能。Spring Session 提供了无缝集成 Spring 框架的 API,支持会话过期策略、并发控制等功能,使开发者能够轻松实现高可用的会话管理。
Spring Session框架
|
17天前
|
Java 应用服务中间件 开发者
深入探索并实践Spring Boot框架
深入探索并实践Spring Boot框架
27 2
|
17天前
|
机器学习/深度学习 数据采集 JavaScript
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
ADR药品不良反应监测系统是一款智能化工具,用于监测和分析药品不良反应。该系统通过收集和分析病历、处方及实验室数据,快速识别潜在不良反应,提升用药安全性。系统采用Java开发,基于SpringBoot框架,前端使用Vue,具备数据采集、清洗、分析等功能模块,并能生成监测报告辅助医务人员决策。通过集成多种数据源并运用机器学习算法,系统可自动预警药品不良反应,有效减少药害事故,保障公众健康。
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
|
9天前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
XML Java 数据格式
JavaEE Spring IoC注解
1. @Resource--手动注入 使用Field注入(用于注解方式),注入依赖对象可以采用手工装配或自动装配.在实际应用中建议使用手工装配,因为自动装配会产生未知情况,开发人员无法预见最终的装配结果。
776 0
|
2月前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
|
3月前
|
Java 测试技术 数据库
Spring Boot中的项目属性配置
本节课主要讲解了 Spring Boot 中如何在业务代码中读取相关配置,包括单一配置和多个配置项,在微服务中,这种情况非常常见,往往会有很多其他微服务需要调用,所以封装一个配置类来接收这些配置是个很好的处理方式。除此之外,例如数据库相关的连接参数等等,也可以放到一个配置类中,其他遇到类似的场景,都可以这么处理。最后介绍了开发环境和生产环境配置的快速切换方式,省去了项目部署时,诸多配置信息的修改。
下一篇
无影云桌面