JAVA框架技术之十八节springboot课件上手教程(二)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: JAVA框架技术之十八节springboot课件上手教程

JAVA框架技术之十八节springboot课件上手教程(一)https://developer.aliyun.com/article/1432888

4.SpringBoot实战

接下来,我们来看看如何用SpringBoot来玩转以前的SSM,我们沿用之前讲解SSM用到的数据库tb_user和实体类User。

4.1.创建工程

4.2.编写基本代码

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>cn.yh.user</groupId>
    <artifactId>yh-user</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

参照上边的项目,编写引导类:

@SpringBootApplication
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class);
    }
}

编写UserController:

@RestController
@RequestMapping("user")
public class UserController {
    @GetMapping("hello")
    public String test(){
        return "hello ssm";
    }
}

4.3.整合SpringMVC

虽然默认配置已经可以使用SpringMVC了,不过我们有时候需要进行自定义配置。

4.3.1.修改端口

添加全局配置文件:application.properties

端口通过以下方式配置

# 映射端口
server.port=80

重启服务后测试:

4.3.2.访问静态资源

现在,我们的项目是一个jar工程,那么就没有webapp,我们的静态资源该放哪里呢?

回顾我们上面看的源码,有一个叫做ResourceProperties的类,里面就定义了静态资源的默认查找路径:

默认的静态资源路径为:

  • classpath:/META-INF/resources/
  • classpath:/resources/
  • classpath:/static/
  • classpath:/public/

只要静态资源放在这些目录中任何一个,SpringMVC都会帮我们处理。

我们习惯会把静态资源放在classpath:/static/目录下。我们创建目录,并且添加一些静态资源:

重启项目后测试:

在浏览器直接测试,具体内容由你而定。

4.4.整合连接池

HikariCP 是一个高性能的 JDBC 连接池组件,号称性能最好的后起之秀,是一个基于BoneCP做了不少的改进和优化的高性能JDBC连接池。

其作者还有产出了另外一个开源作品HikariJSON——高性能的JSON解析器。

代码体积更是少的可怜,130kb。Spring Boot 2都已经宣布支持了该组件,由之前的Tomcat换成HikariCP。

其性能远高于c3p0、tomcat等连接池,以致后来BoneCP作者都放弃了维护,在Github项目主页推荐大家使用HikariCP。

上边说到是在BoneCP基础上做了优化,那做了哪些优化呢?

字节码精简 :优化代码(HikariCP利用了一个第三方的Java字节码修改类库Javassist来生成委托实现动态代理,动态代理的实现在ProxyFactory类),直到编译后的字节码最少,这样,CPU缓存可以加载更多的程序代码;

优化代理和拦截器:减少代码,例如HikariCP的Statement proxy只有100行代码,只有BoneCP的十分之一;

自定义数组类型(FastStatementList)代替ArrayList:避免每次get()调用都要进行range check,避免调用remove()时的从头到尾的扫描,相对与ArrayList极大地提升了性能,而其中的区别是,ArrayList在每次执行get(Index)方法时,都需要对List的范围进行检查,而FastStatementList不需要,在能确保范围的合法性的情况下,可以省去范围检查的开销。

自定义集合类型(ConcurrentBag):支持快速插入和删除,特别是在同一线程既添加又删除项时,提高并发读写的效率;

针对CPU的时间片算法进行优化:尽可能在一个时间片里面完成各种操作(具体机制比较模糊)。

针对连接中断的情况:比其他CP响应时间上有了极好的优化,响应时间为5S,会抛出SqlException异常,并且后续的getConnection()可以正常进行

关于Connection的操作:另外在Java代码中,很多都是在使用完之后直接关闭连接,以前都是从头到尾遍历,来关闭对应的Connection,而HikariCP则是从尾部对Connection集合进行扫描,整体上来说,从尾部开始的性能更好一些。

jdbc连接池是spring配置中的重要一环,在SpringBoot中该如何处理呢?

答案是不需要处理,我们只要找到SpringBoot提供的启动器即可:

在pom.xml中引入jdbc的启动器:

<!--jdbc的启动器,默认使用HikariCP连接池-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--不要忘记数据库驱动,因为springboot不知道我们使用的什么数据库,这里选择mysql-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

SpringBoot已经自动帮我们引入了一个连接池:

HikariCP应该是目前速度最快的连接池了,我们看看它与c3p0的对比:

maximum-pool-size 池中最大连接数(包括空闲和正在使用的连接)

minimum-idle 池中最小空闲连接数量。默认值10

pool-name 连接池的名字

auto-commit 是否自动提交池中返回的连接。默认值为true。

idle-timeout 空闲时间。仅在minimum-idle小于maximum-poop-size的时候才会起作用。默认值10分钟。

max-lifetime 连接池中连接的最大生命周期。当连接一致处于闲置状态时,数据库可能会主动断开连接。

connection-timeout 连接超时时间。默认值为30s,可以接收的最小超时时间为250ms。

我们只需要指定连接池参数即可:

# 连接四大参数
spring.datasource.password=root
spring.datasource.username=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
#连接池:参数
spring.datasource.hikari.idle-timeout=60000
spring.datasource.hikari.maximum-pool-size=30
spring.datasource.hikari.minimum-idle=10

当然,如果你更喜欢Druid连接池,也可以使用Druid官方提供的启动器:

<!-- 阿里:Druid连接池;效果也非常高; -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.6</version>
</dependency>

而连接信息的配置与上面是类似的,只不过在连接池特有属性上,方式略有不同:

#初始化连接数
spring.datasource.druid.initial-size=1
#最小空闲连接
spring.datasource.druid.min-idle=1
#最大活动连接
spring.datasource.druid.max-active=20
#获取连接时测试是否可用
spring.datasource.druid.test-on-borrow=true
#监控页面启动
spring.datasource.druid.stat-view-servlet.allow=true

4.5.整合mybatis

使用一下注释可以配置自己定义的AutoConfig

@ConditionalOnBean:当容器中有指定的Bean的条件下

@ConditionalOnClass:当类路径下有指定的类的条件下

@ConditionalOnMissingBean:当容器中没有指定Bean的情况下

@ConditionalOnMissingClass:当类路径下没有指定的类的条件下

此处的源码没图,看秘增视频。

4.5.1.mybatis

SpringBoot官方并没有提供Mybatis的启动器,不过Mybatis官方自己实现了:

<!--mybatis -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.2</version>
</dependency>

配置(基本没有需要配置,我们这里没有写,大家别写,现在)

# mybatis 别名扫描
# mybatis.type-aliases-package=com.yh.pojo
# mapper.xml文件位置,如果没有映射文件,请注释掉
#mybatis.mapper-locations=classpath:mappers/*.xml

需要注意,这里没有配置mapper接口扫描包,因此我们需要给每一个Mapper接口添加@Mapper注解,才能被识别。

@Mapper注解是由Mybatis框架中定义的一个描述数据层接口的注解,注解往往起到的都是一个描述性作用,用于告诉sprigng框架此接口的实现类由Mybatis负责创建,并将其实现类对象存储到spring容器中。在编译之后会生成相应的接口实现类。

@MapperScan注解的使用

作用:指定要变成实现类的接口所在的包,包下面的所有接口在编译之后都会生成相应的实现类。

@Mapper
@Repository
public interface StockMapper {
    @Select("select * from stock")
    public List<Stock> findAllStocks();
}

Stock对象

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Stock {
    private int id; //编号
    private String name;    //名;
    private int num;  //数量
    private String desp;        //描述信息;
}

业务接口和实现类:

public interface StockService {
    public List<Stock> findAllStocks();
}
实现类:在impl下加一个实体类;
/**
 * 3.service层:业务层(服务层),来调用mapper(dao)层对象;StockMapper
 *  3.1 需要声明一个成员变量;stockMapper;  Autowired:,自动注入,由于spring是IOC机制;
 *  3.2 在方法内部,由stockMapper,提供数据
 *  3.3 千万别忘了,@Service 服务注解;
 */
@Service
public class StockServiceImpl implements StockService {
    @Autowired
    StockMapper stockMapper;
    @Override
    public List<Stock> findAllStocks() {
        return stockMapper.findAllStocks();
    }
}

控制层,增加代码

@Autowired
    StockService stockService;    
  //由数据库提供数据;
    @RequestMapping("/findAllStocks")
    public ModelAndView findAllStocks(){
        ModelAndView mv=new ModelAndView("stocklist");
        List<Stock>stockList=stockService.findAllStocks();
        mv.addObject("stocklist",stockList);
        return mv;
    }

测试json数据输出

4.6.完整项目结构

完整的pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>cn.yh</groupId>
    <artifactId>yh-user</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--jdbc的启动器,默认使用HikariCP连接池-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!--不要忘记数据库驱动,因为springboot不知道我们使用的什么数据库,这里选择mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!-- 通用mapper -->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.0.2</version>
        </dependency>
    </dependencies>
</project>

完整的application.properties:

server.port=80
logging.level.org.springframework=debug
spring.datasource.url=jdbc:mysql://localhost:3306/dms
spring.datasource.username=root
spring.datasource.password=root
# mybatis 别名扫描
mybatis.type-aliases-package=cn.yh.pojo
# mapper.xml文件位置,如果没有映射文件,请注释掉
# mybatis.mapper-locations=classpath:mappers/*.xml

5.Thymeleaf快速入门

SpringBoot并不推荐使用jsp,但是支持一些模板引擎技术。jsp需要服务器,tomcat、jetty,由服务器对页面的指令进行编译、解释,才能够执行。主流开发趋势,是前后端分离,前端页面上信息呈现,可以不依赖后台服务器,可以做预览。

以前大家用的比较多的是Freemarker,但是我们今天的主角是Thymeleaf!

5.1.为什么是Thymeleaf?

简单说, Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP 。相较于其他的模板引擎,它有如下四个极吸引人的特点:

  • 动静结合:Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。
  • 开箱即用:它提供标准和spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,避免每天套模板、改jstl、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。
  • 多方言支持:Thymeleaf 提供spring标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。
  • 与SpringBoot完美整合,SpringBoot提供了Thymeleaf的默认配置,并且为Thymeleaf设置了视图解析器,我们可以像以前操作jsp一样来操作Thymeleaf。代码几乎没有任何区别,就是在模板语法上有区别。

接下来,我们就通过入门案例来体会Thymeleaf的魅力:

5.2.提供数据

编写一个controller方法,返回一些用户数据,放入模型中,将来在页面渲染

@GetMapping("/all")
public String all(ModelMap model) {
    // 查询用户
    List<User> users = this.userService.queryAll();
    // 放入模型
    model.addAttribute("users", users);
    // 返回模板名称(就是classpath:/templates/目录下的html文件名)
    return "users";
}

5.3.引入启动器

直接引入启动器:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

5.3.1 把源码

SpringBoot会自动为Thymeleaf注册一个视图解析器:

与解析JSP的InternalViewResolver类似,Thymeleaf也会根据前缀和后缀来确定模板文件的位置:

  • 默认前缀:classpath:/templates/
  • 默认后缀:.html

所以如果我们返回视图:users,会指向到 classpath:/templates/users.html

一般我们无需进行修改,默认即可。

5.4.静态页面

根据上面的文档介绍,模板默认放在classpath下的templates文件夹,我们新建一个html文件放入其中:

编写html模板,渲染模型中的数据:

注意,把html 的名称空间,改成:xmlns:th="http://www.thymeleaf.org" 会有语法提示

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
    <style type="text/css">
        table {border-collapse: collapse; font-size: 14px; width: 80%; margin: auto}
        table, th, td {border: 1px solid darkslategray;padding: 10px}
    </style>
</head>
<body>
<div style="text-align: center">
    <span style="color: darkslategray; font-size: 30px">欢迎光临!</span>
    <hr/>
<table class="list">
    <tr>
        <th>id</th>
        <th>姓名</th>
        <th>用户名</th>
        <th>年龄</th>
        <th>性别</th>
        <th>生日</th>
    </tr>
    <tr th:each="stock :${stockList}">
        <td th:text="${stock.id}"></td>
        <td th:text="${stock.name}"></td>
        <td th:text="${stock.num}"></td>
    </tr>
</div>
</body>
</html>

我们看到这里使用了以下语法:

  • ${} :这个类似与el表达式,但其实是ognl的语法,比el表达式更加强大
  • th-指令:th-是利用了Html5中的自定义属性来实现的。如果不支持H5,可以用data-th-来代替
  • th:each:类似于c:foreach 遍历集合,但是语法更加简洁
  • th:text:声明标签中的文本
  • 例如,如果user.id有值,会覆盖默认的1
  • 如果没有值,则会显示td中默认的1。这正是thymeleaf能够动静结合的原因,模板解析失败不影响页面的显示效果,因为会显示默认值!
  • th:if: 做条件判断
    th:switch -th:case 做条件判断

忽略所有警告或错误

<!--解决idea thymeleaf 表达式模板报红波浪线,建议用这种。-->
<!--suppress ALL -->

或者下面方式解决:

如果是IDEA设置是setting 下方的editor 的inspectors 找到查找窗口,thymeleaf ,第二个勾去掉。

5.5.测试

接下来,我们打开页面测试一下:

5.6.模板缓存

Thymeleaf会在第一次对模板解析之后进行缓存,极大的提高了并发处理能力。但是这给我们开发带来了不便,修改页面后并不会立刻看到效果,我们开发阶段可以关掉缓存使用:

# 开发阶段关闭thymeleaf的模板缓存
spring.thymeleaf.cache=false

注意

在Idea中,我们需要在修改页面后按快捷键:`Ctrl + Shift + F9` 对项目进行rebuild才可以。
eclipse中没有测试过。

我们可以修改页面,测试一下。

附录:所有的标签,供参考。


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
30天前
|
Java API Maven
2025 Java 零基础到实战最新技术实操全攻略与学习指南
本教程涵盖Java从零基础到实战的全流程,基于2025年最新技术栈,包括JDK 21、IntelliJ IDEA 2025.1、Spring Boot 3.x、Maven 4及Docker容器化部署,帮助开发者快速掌握现代Java开发技能。
307 1
|
1月前
|
JavaScript 安全 前端开发
Java开发:最新技术驱动的病人挂号系统实操指南与全流程操作技巧汇总
本文介绍基于Spring Boot 3.x、Vue 3等最新技术构建现代化病人挂号系统,涵盖技术选型、核心功能实现与部署方案,助力开发者快速搭建高效、安全的医疗挂号平台。
126 3
|
1月前
|
存储 人工智能 算法
Java 大视界 -- Java 大数据在智能医疗影像数据压缩与传输优化中的技术应用(227)
本文探讨 Java 大数据在智能医疗影像压缩与传输中的关键技术应用,分析其如何解决医疗影像数据存储、传输与压缩三大难题,并结合实际案例展示技术落地效果。
|
1月前
|
机器学习/深度学习 算法 Java
Java 大视界 -- Java 大数据在智能物流运输车辆智能调度与路径优化中的技术实现(218)
本文深入探讨了Java大数据技术在智能物流运输中车辆调度与路径优化的应用。通过遗传算法实现车辆资源的智能调度,结合实时路况数据和强化学习算法进行动态路径优化,有效提升了物流效率与客户满意度。以京东物流和顺丰速运的实际案例为支撑,展示了Java大数据在解决行业痛点问题中的强大能力,为物流行业的智能化转型提供了切实可行的技术方案。
|
1月前
|
分布式计算 Cloud Native 安全
Java:历久弥新的技术基石
Java:历久弥新的技术基石
|
1月前
|
分布式计算 Java 大数据
Java:技术生态中的常青树
Java:技术生态中的常青树
|
1月前
|
人工智能 自然语言处理 分布式计算
AI 驱动传统 Java 应用集成的关键技术与实战应用指南
本文探讨了如何将AI技术与传统Java应用集成,助力企业实现数字化转型。内容涵盖DJL、Deeplearning4j等主流AI框架选择,技术融合方案,模型部署策略,以及智能客服、财务审核、设备诊断等实战应用案例,全面解析Java系统如何通过AI实现智能化升级与效率提升。
180 0
|
4月前
|
JavaScript 前端开发 Java
制造业ERP源码,工厂ERP管理系统,前端框架:Vue,后端框架:SpringBoot
这是一套基于SpringBoot+Vue技术栈开发的ERP企业管理系统,采用Java语言与vscode工具。系统涵盖采购/销售、出入库、生产、品质管理等功能,整合客户与供应商数据,支持在线协同和业务全流程管控。同时提供主数据管理、权限控制、工作流审批、报表自定义及打印、在线报表开发和自定义表单功能,助力企业实现高效自动化管理,并通过UniAPP实现移动端支持,满足多场景应用需求。
421 1
|
5月前
|
前端开发 Java 关系型数据库
基于Java+Springboot+Vue开发的鲜花商城管理系统源码+运行
基于Java+Springboot+Vue开发的鲜花商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的鲜花商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。技术学习共同进步
409 7
|
4月前
|
供应链 JavaScript BI
ERP系统源码,基于SpringBoot+Vue+ElementUI+UniAPP开发
这是一款专为小微企业打造的 SaaS ERP 管理系统,基于 SpringBoot+Vue+ElementUI+UniAPP 技术栈开发,帮助企业轻松上云。系统覆盖进销存、采购、销售、生产、财务、品质、OA 办公及 CRM 等核心功能,业务流程清晰且操作简便。支持二次开发与商用,提供自定义界面、审批流配置及灵活报表设计,助力企业高效管理与数字化转型。
428 2
ERP系统源码,基于SpringBoot+Vue+ElementUI+UniAPP开发