版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
软件架构与应用开发--SpringBoot+Vue全栈应用开发实践罗荣良软件架构演进与主流技术栈选型本节核心问题1.什么是“软件架构”?
2.为什么现在的系统都要“前后端分离”?
3.为什么SpringBoot+Vue是黄金搭档?
4.在这门课里,我们将构建什么样的系统?5.如何利用人工智能研发应用系统?6.课程的配套教材是什么?什么是软件架构定义:软件架构是系统的草图。
类比:
写代码=砌砖头
做架构=设计大楼的蓝图(承重结构、水电布局、功能分区)
核心价值:稳定性、可扩展性、可维护性。架构演进史:从混沌到有序阶段一:单体架构(All-in-One)
JSP/Servlet时代,页面和逻辑混在一起,牵一发而动全身。
阶段二:MVC分层架构
职责开始分离,但仍在一个工程里。
阶段三:前后端分离架构
(本课重点)
前端独立部署,后端只负责数据,通过API对话。核心趋势:前后端分离核心优势:各司其职多端复用并行开发核心素养:契约精神:API接口一经定义,必须严格遵守。协同共生:高内聚低耦合,为了共同的目标高效配合。技术选型:为什么后端选SpringBoot1.Java生态的基石:占据企业级开发80%份额。
2.约定优于配置:告别繁琐的XML,开箱即用。
3.微服务入口:向SpringCloud进阶的必经之路。
地位:后端开发的“工业标准”。技术选型:为什么前端选Vue31.渐进式框架:易学易用,上手曲线平滑。
2.组合式API(CompositionAPI):逻辑复用更强,更适合大型项目。
3.生态繁荣:ElementPlus,Pinia,Vite工具链完善。
地位:国内最流行的前端框架。本课程的“架构蓝图”|展示全景架构图前端层:Vue3+Vite+Axios+ElementPlus
-网关/接口层:RESTfulAPI
-后端应用层:SpringBoot(Controller-Service-Dao)
-数据层:MySQL+JPA/MyBatis从架构师的角度看代码不仅仅是写if-else。我们要考虑:-规范:RESTful接口设计-分层:高内聚,低耦合-复用:组件化思维-安全:认证与鉴权为什么这门课叫“应用开发”架构是骨架,应用是血肉。
我们将通过一个完整的企业级案例,填充这副骨架。
不纸上谈兵,要在实战中理解架构。学习路径规划基础篇:Vue3语法&SpringBoot入门进阶篇:组件化开发&数据库交互实战篇:全栈联调与系统构建部署篇:从代码到产品AI辅助篇:AI协作应用研发小结懂架构的程序员,才有未来。
让我们开始搭建你的第一个现代化企业级应用。罗荣良全栈开发环境搭建与项目初始化本节目标:搭建全栈流水线1.后端环境:JDK17+Maven3.x
2.前端环境:Node.js(LTS)+npm/pnpm
3.数据库:MySQL8.0+客户端
4.开发工具:IntelliJIDEA+VisualStudioCode(VSCode)
5.实战验证:初始化并运行HelloWorld全栈开发工具链概览-运行环境层(Runtime):JDK,Node.js
-数据层(Data):MySQL
-编码层(Editor):IDEA,VSCode
-协作层(Optional):Git,Postman后端基石:JDK安装与配置版本选择:推荐JDK17
以上版本。关键步骤:下载安装包(Oracle官方网站)2.配置环境变量JAVA_HOME3.验证:java-version后端依赖管理:Maven作用:管jar包的。
痛点:下载慢。
解决方案:配置阿里云镜像
(settings.xml)。
IDE配置:在IDEA中指定Maven路径。Maven的全局配置文件settings.xml(通常位于Maven安装目录的conf文件夹下或用户主目录下的.m2/settings.xml<settings><mirrors><mirror><id>aliyun</id><name>AliYun</name><url>/repository/public</url><mirrorOf>central</mirrorOf><!--此项配置表示代理Maven中央仓库的请求--></mirror></mirrors></settings>前端基石:Node.js环境类比:Node.js之于前端=JDK之于后端。版本:务必下载LTS(长期支持版),不要尝鲜最新版。/en/download验证:node-v和npm-v。数据库准备:MySQL8安装:MySQLCommunityServer8.0+
注意:记住你的root密码!
客户端:推荐MySQLWorkbench(自带)或Navicat。
验证:能连接成功即达标。IDE神器:IntelliJIDEA&VSCode-旗舰版(学生可申请免费)vs社区版(够用)
-插件:Lombok
前端VSCode:
-轻量级,生态强
-必装插件:VueVolarextensionPack(Vue3核心)实战1:初始化SpringBoot项目工具:SpringInitializr(start.spring.io)或IDEA内置。
配置:
-BuildTool:Maven
-Language:Java
-JavaVersion:17
-Dependencies:SpringWeb后端:运行Application.java->控制台看到SpringLogo->访问localhost:8080环境验证:Vue3开发环境工具:Vite(新一代构建工具)。命令:npmcreatevue@latest选项:-JavaScript:Yes
-VueRouter:YesPinia:Yes环境验证:跑通HelloWorld前端:npmrundev->访问localhost:5173成功标准:浏览器能看到两个默认页面。小结与下节预告小结:环境没问题,开发才顺畅。
预告:下节课我们将正式开始写后端代码,学习SpringBoot的核心概念。罗荣良创建第一个SpringBoot应用本节学习目标1.掌握使用SpringInitializr创建项目
2.掌握使用IntelliJIDEA创建项目
3.深入理解SpringBoot项目标准目录结构
4.编写并运行第一个"HelloWorld"接口第一个APP创建方式概览方式一:在线创建(start.spring.io)
方式二:IDE内置工具(IntelliJIDEA)
核心:基于SpringInitializr脚手架在线创建演示(start.spring.io)访问http://start.spring.io/
创建SpringBoot项目界面SpringInitializr官网界面
标注关键配置区:Project,Language,SpringBootVersion关键参数配置详解添加依赖Dependencies必选依赖:SpringWeb
作用:提供Web开发支持(含Tomcat和SpringMVC)
操作:点击"ADDDEPENDENCIES"->搜索"Web"IDEA创建演示IDEA"NewProject"窗口
ServerURL:start.spring.io
强调:与在线版参数一致项目解压与导入在线版:下载zip->解压->IDEA
打开pom.xml
IDE版:自动打开项目窗口提示:首次加载需等待Maven下载依赖项目目录结构全景src/main/java(代码)src/main/resources(资源)src/test(测试)pom.xml(配置)Java代码目录规范models–存放所有的模型类controllers–用于存放所有控制器类services–存放所有服务类repositories–保留所有数据存储库类configs–存放配置类utils–存放工具类Resources资源目录static/:存放静态文件(js,css,images)templates/:存放模板文件(Thymeleaf)perties:核心配置文件核心配置文件:pom.xmlParent:spring-boot-starter-parent(版本管理)Dependencies:spring-boot-starter-web(Web功能)Build:spring-boot-maven-plugin(打包插件)入口类深度解析核心注解:@SpringBootApplication启动方法:SpringApplication.run()实战:编写HelloController实战:编写HelloController实战:编写HelloController操作:点击入口类的Run按钮(绿色三角形)观察:Console控制台日志关键信息:Tomcatstartedonport8080验证运行结果浏览器访问:http://localhost:8080/hello预期结果:页面显示"HelloSpringBoot"常见问题:JDK版本错误现象:java:错误:无效的源发行版:19原因:项目设置JDK19但本地只有JDK8解决:ProjectStructure->ProjectSDK->选择JDK19+本节小结与作业浏览器访问:http://localhost:8080/hello预期结果:页面显示"HelloSpringBoot"罗荣良SpringBoot基础配置与注解本节学习目标1.深入理解@SpringBootApplication启动类原理2.掌握Web开发核心注解(@RestController等)3.掌握perties与YAML配置文件4.实现多环境配置切换(Dev/Prod)回顾:HelloWorld后的思考问题:程序是怎么知道从哪里开始运行的?又是如何知道要处理
/hello
请求的?答案:注解(Annotations)核心注解:@SpringBootApplication公式:@SpringBootApplication
=1.
@Configuration
(配置类)2.
@EnableAutoConfiguration
(自动配置)3.
@ComponentScan
(组件扫描)@EnableAutoConfiguration:作用:根据classpath中的依赖自动配置Bean。例子:看到spring-web依赖->自动配置Tomcat和SpringMVC。自动配置的魔法组件扫描机制@ComponentScan:作用:自动扫描当前包及其子包下的Bean。图示:包结构扫描范围示意图(Main类在根包,Controller在子包)。Web开发核心注解:@RestController公式:@RestController
=
@Controller
+
@ResponseBody作用:将类标记为Web控制器,且返回值自动转换为JSON。场景:RESTfulAPI开发。路由映射:@RequestMapping系列@RequestMapping:基础映射@GetMapping:处理GET请求(查询)@PostMapping:处理POST请求(提交)@PutMapping
/
@DeleteMapping实战案例:处理请求参数代码:@RequestParam(value="name",defaultValue="SpringBoot")访问:/hello?name=Spring结果:HelloSpringSpringBoot配置文件作用:修改默认配置(端口、数据库连接等)默认文件:src/main/resources/perties格式对比:Properties(键值对)vsYAML(层级结构)perties文件格式:server.port=8081=demo特点:简单,扁平,但层级深时冗余。Properties语法示例YAML语法示例(推荐)application.yaml文件格式:
spring:datasource:url:jdbc:mysql:///mydb特点:树状结构,清晰,注意缩进。自定义启动Banner
(趣味环节)截图:控制台由SpringLogo变为自定义字符画操作:在resources下创建
banner.txt作用:项目启动时的个性化标识。场景图:开发环境(Dev)->连接本地数据库(localhost)生产环境(Prod)->连接线上数据库(IP:192.168.x.x)多环境配置的需求多环境配置实现(Profile)文件命名规则:application-{profile}.yml示例:application-dev.yml
(开发)application-prod.yml
(生产)激活指定环境操作:在主配置文件
application.yml
中设置files.active=dev效果:系统加载dev配置,忽略prod配置常见问题与总结1.YAML缩进必须用空格,不能用Tab。2.注解没生效?检查包路径是否在启动类包的下层。3.端口冲突(Port8080alreadyinuse)。本节小结与作业作业:1.修改端口为8888。2.创建dev和test环境,分别输出不同的欢迎语。3.制作一个个性化的
banner.txt。罗荣良SpringBootStarter原理与应用本节学习目标1.理解Starter(起步依赖)的核心概念2.掌握Starter的命名规范3.熟悉官方常用Starters列表4.实战:引入SecurityStarter体验自动配置5.掌握查看Maven依赖树的方法痛点回顾:传统开发的“依赖地狱”SSM时代庞大的pom.xml,几十个<dependency>且都要写版本号。版本冲突报错截图(ClassNotDefFoundError)。繁琐、易错、版本不兼容。什么是Starter?定义:Starter是一组依赖的集合(聚合)。比喻:传统方式=单点菜品(我要买面粉、糖、鸡蛋...)Starter=套餐/预制菜(我要买“蛋糕制作套装”)spring-boot-starter-web(父)├──spring-webmvc├──spring-web├──jackson-databind(JSON处理)└──tomcat-embed-core(服务器)文字:一站式引入,开箱即用。核心原理:依赖传递常用官方Starters清单--组件扫描机制spring-boot-starter-web(Web开发)spring-boot-starter-test(测试)spring-boot-starter-data-jpa(数据库)spring-boot-starter-security(安全)spring-boot-starter-thymeleaf(模板)Starter命名规范官方官方:spring-boot-starter-{模块名}例:spring-boot-starter-web第三方社区:{模块名}-spring-boot-starter例:mybatis-spring-boot-starter版本仲裁中心:Parentpom.xml顶部的<parent>标签。作用:spring-boot-starter-parent统一管理了所有官方依赖的版本号。优势:引入依赖时不需要写<version>。实战演示:体验Starter的魔力目标:给现有的HelloWorld项目增加安全控制。操作:仅添加spring-boot-starter-security依赖。预期:无需写代码,所有接口自动被保护。实战步骤1:修改POM文件浏览器访问/hello->自动跳转到登录页这就是Starter触发的自动配置(AutoConfiguration)。实战步骤2:重启与验证工具篇:查看Maven依赖树截图:IntelliJIDEA右侧Maven面板->Dependencies->ShowDependencies(图标)。展示:可视化的依赖拓扑图。如何查找需要的Starter?1.官网:SpringInitializr2.搜索网站:3.IDE智能补全1.Starter是依赖的聚合,解决了选包和版本冲突问题。2.官方命名spring-boot-starter-*。3.ParentPOM负责版本管理。4.引入Starter往往会触发自动配置。本节总结作业1.查看你的项目依赖树,看看starter-web引入了哪个版本的Tomcat。2.尝试引入spring-boot-starter-thymeleaf依赖。罗荣良Web开发实战:MVC与Thymeleaf本节学习目标1.深入理解MVC设计模式(Model-View-Controller)2.了解SpringMVC的核心执行流程3.掌握Thymeleaf模板引擎的集成4.实战:使用Thymeleaf渲染动态数据列表什么是MVC模式Model(模型):数据与业务逻辑View(视图):用户看到的界面(HTML)Controller(控制器):接收请求,协调M和V核心思想:解耦
生活中的MVC:餐厅类比顾客=用户服务员=Controller(接收点单,传菜)厨师=Model(处理食材,业务逻辑)菜品=View(最终呈现给用户的结果)|人性化教学DispatcherServlet(前端控制器):整个流程的指挥官。Request->DispatcherServlet->Controller->ViewResolver->ResponseSpringMVC核心组件为什么学习Thymeleaf?服务端渲染
:HTML在服务器生成。优势:1.简单易学,所见即所得。2.SEO(搜索引擎优化)友好。3.SpringBoot官方推荐替代JSP。说明:虽然有Vue,但服务端渲染仍有场景。项目集成Thymeleaf依赖引入:spring-boot-starter-thymeleaf目录结构:src/main/resources/templates/->放HTML文件src/main/resources/static/->放CSS/JS/图片
实战案例:学生列表展示目标:在页面上显示一组学生信息。步骤:1.创建Student实体类。2.创建Controller模拟数据。3.编写Thymeleaf页面展示数据。Step1:创建实体类(Model)属性:id,name,ageStep2:编写Controller注解:@Controller(注意不是@RestController)方法:list(Modelmodel)关键点:model.addAttribute("students",list)Model:SpringMVC提供的接口。作用:Controller与View之间的数据桥梁。语法:model.addAttribute("key",value)->相当于把数据放进“快递盒”。数据传输的核心:Model对象Step3:编写View(HTML)头部引入:<htmlxmlns:th="">关键:引入命名空间才能有代码提示。Thymeleaf语法1:文本替换th:text代码:<spanth:text="${name}">默认名</span>解释:如果有值,替换"默认名";没值显示"默认名"(原型支持)。th:each代码:<trth:each="stu:${students}">解释:类似Java的for(Studentstu:students)。取值:<tdth:text="${}"></td>Thymeleaf语法2:循环遍历Thymeleaf语法3:条件判断配置实现th:if/th:unless代码:<spanth:if="${stu.age>18}">已成年</span>解释:满足条件才渲染该标签。运行效果演示浏览器访问localhost:8080/students展示:一个包含多行数据的表格。对比:查看网页源代码,看到的是纯HTML(服务端渲染完毕)。服务端渲染vs前后端分离
Thymeleaf:服务器压力大,适合简单页面。Vue.js:浏览器渲染,服务器只发JSON,交互性强。本课路线:先懂服务端渲染原理,后续全面转向Vue。本节小结与作业小结:MVC流程、Controller跳转、Thymeleaf常用标签。作业:创建一个页面,根据分数显示“及格”或“不及格”(使用th:if)。罗荣良Controller深度详解本节学习目标1.理解RESTful风格的API设计2.掌握URL路径参数接收(@PathVariable)3.掌握查询参数接收(@RequestParam)4.掌握JSON数据接收(@RequestBody)5.熟练使用Postman测试接口从页面跳转到数据接口上节课:Request->Controller->HTML页面这节课:Request->Controller->JSON数据(API)结论:为Vue前端做准备RESTful风格简介资源(Resource):一切皆资源(Users,Books)动作:HTTP方法对应操作GET(查询),POST(新增),PUT(修改),DELETE(删除)场景:查询ID为5的用户URL:/users/5注解:@PathVariable语法:@GetMapping("/users/{id}")场景一:获取路径上的参数代码演示:@PathVariable场景二:获取查询参数场景:搜索姓名为“luo"的用户URL:/users/search?name=luo注解:@RequestParam语法:publicUsersearch(@RequestParamStringname)代码演示:@RequestParam场景三:接收复杂JSON数据场景:注册新用户(包含姓名、年龄、邮箱等)URL:/users(POST)数据格式:JSONObject注解:@RequestBody(最关键!)代码演示:@RequestBody@PostMappingpublicUsercreateUser(@RequestBodyUseruser){//Spring自动把JSON转为User对象returnuserService.save(user);}三大参数注解对比(核心总结)@PathVariable:用于URL路径上的值。就像你去书架上拿第5本书@RequestParam:用于问号后的查询参数。就像你要找所有红色的书@RequestBody:用于POST/PUT的Body数据。就像你写了一本新书的内容要存进去HTTP状态码的设计
不仅仅返回数据,还要返回状态。200OK-成功201Created-创建成功400BadRequest-参数错误404NotFound-资源不存在实战:设计RESTful用户控制器类定义:@RestController+@RequestMapping("/users")实战:CRUD完整代码(1/2)查询所有:查询单个:新增用户:实战:CRUD完整代码(2/2)@PutMapping("/{id}")@DeleteMapping("/{id}")测试神器:Postman/Apifox为什么要用工具?浏览器地址栏只能发GET请求。POST/PUT/JSON需要专用工具。截图:Postman发送JSON请求的界面。常见错误与避坑
1.JSON字段名与实体类属性名不一致(导致接收为null)。2.忘记加@RequestBody(导致对象为空)。3.路径参数{id}与@PathVariable("id")名称不对应。本节小结与作业小结:三种参数接收方式。作业:实现一个BookController,包含增删改查图书的接口,并用Postman测试。罗荣良AOP切面编程与异常处理本节学习目标1.理解AOP(面向切面编程)的核心思想2.掌握AOP五大术语与切入点表达式3.实战:使用AOP实现Web请求日志记录4.掌握SpringBoot全局异常处理机制5.设计标准化的API统一响应格式痛点引入:代码里的“牛皮癣”如果要实现日志和异常处理功能:有三个Controller方法,每个开头都写System.out.println("日志...")
结尾都有try-catch。问题:如何消除重复的非业务代码?什么是AOP(面向切面编程)定义:将通用逻辑(日志、权限、事务)从业务逻辑中分离出来。比喻:汉堡包模型。面包片=切面逻辑(AOP)肉饼=业务逻辑(Controller/Service)切面(Aspect):关注点的模块化(类)连接点(JoinPoint):程序执行的点(方法)切入点(Pointcut):匹配连接点的规则通知(Advice):在切入点执行的动作AOP核心术语图解通知(Advice)的类型@Before:方法执行前@After:方法执行后(无论成功失败)@AfterReturning:方法成功返回后@AfterThrowing:抛出异常后@Around:环绕(最强大,可控制执行)实战一:Web请求日志切面目标:记录每个接口的URL、IP、方法名、耗时。依赖:spring-boot-starter-aop步骤:定义Aspect类->编写Pointcut->编写Advice切入点表达式详解代码:execution(public*com.example.controller.*.*(..))解析:*(返回值)com.example...(包路径)*(类名)*(方法名)(..)(任意参数)代码演示:定义切面类代码演示:获取请求信息
在@AfterReturning中记录result。技巧:利用ThreadLocal或@Around计算System.currentTimeMillis()差值。代码演示:记录返回值与耗时痛点二:丑陋的异常处理Controller中充斥着大量的try-catch块。弊端:代码臃肿,且返回给前端的错误格式不统一(有时是404页,有时是报错堆栈)。希望发生错误,后端都返回一个统一的JSON格式,比如:{"code":500,"msg":"系统繁忙"}全局异常处理原因@ControllerAdvice:控制器的增强器。@ExceptionHandler:捕获特定异常。流程:Controller抛出异常->被Advice捕获->返回友好的JSON。前后端分离标准JSON格式:code:状态码(200,500)msg:提示信息data:数据载体创建Result封装类。实战二:定义统一响应结构代码演示:全局异常处理器编写核心类GlobalExceptionHandler进阶:处理特定异常捕获ArithmeticException(除零错误)或自定义BusinessException。展示优先级:精确匹配优先。最终效果对比
Before:控制台报错,前端收到500堆栈页面。After:控制台打印优雅日志,前端收到{code:500,msg:"系统繁忙"}。本节小结与作业小结:AOP解耦业务与系统逻辑,全局异常统一出口。作业:实现一个AOP切面,统计所有Service方法的执行时间,超过1秒则打印警告。罗荣良单元测试与热部署本节学习目标1.掌握SpringBootDevTools热部署配置2.解决IntelliJIDEA热部署不生效的痛点3.理解单元测试的重要性与starter-test组件4.实战:编写Service层业务逻辑测试5.实战:使用MockMvc进行Controller接口测试痛点一:无尽的等待经常出现的场景:修改一行代码->点击重启->等待10秒->刷新页面。“重启应用”是开发效率的头号杀手。解决方案:SpringBoot依赖引入:spring-boot-devtools原理:1.两个类加载器(Base/Restart)。2.只重新加载变化的类(RestartClassLoader)。3.速度极快(通常<1秒)。Settings->Compiler->Buildprojectautomatically(打钩)AdvancedSettings->Allowauto-maketostart...(打钩)IDEA默认不自动编译,必须手动开启!关键配置:IDEA的特殊设置前端模板热部署问题:修改Thymeleaf页面,刷新没变化?原因:默认开启了缓存。解决:application.yml->spring.thymeleaf.cache=false痛点二:不敢重构代码场景:修改了一个核心算法,不敢发布,怕改坏了旧功能。解决方案:单元测试(UnitTesting)。价值:自动化验证、代码的“安全网”。
SpringBoot测试全家桶依赖:spring-boot-starter-test包含组件:1.JUnit5:测试框架核心2.Mockito:模拟对象(Mock)3.AssertJ:流畅断言库4.MockMvc:Web接口测试敬畏之心,保障质量的工匠精神:将每次测试视为交付前的重要质检,是对自己和用户负责。JUnit5核心注解@SpringBootTest:加载Spring上下文@Test:标记测试方法@BeforeEach/@AfterEach:每个测试前后执行@DisplayName:给测试起个中文名实战一:Service层测试目标:测试StudentService.createStudent()代码演示:1.注入Service(@Autowired)2.调用方法3.断言(Assertions.assertEquals)
什么是断言?判断“实际结果”是否等于“预期结果”。常用方法:assertEquals(expected,actual)assertTrue(condition)assertNotNull(object)不满足于“代码能跑”,追求逻辑严密、边界清晰:精益求精,注重细节的工匠精神断言(Assertions):测试的灵魂实战二:Controller层测试(MockMvc)挑战:不启动Tomcat怎么测HTTP接口?神器:MockMvc原理:模拟HTTP请求发送给DispatcherServlet,获取响应。MockMvc代码详解截图:mockMvc.perform(get("/students")).andExpect(status().isOk()).andExpect(jsonPath("$.name").value("张三"))IDEA测试运行面板。绿色钩=通过;红色叉=失败。文字:失败时查看"ExpectedvsActual"对比。测试运行与结果查看本节小结与作业小结:配置DevTools提速,编写JUnit保证质量。在测试中践行工匠精神,就是将测试从一项被迫完成的任务,升华为一种主动构建高质量、可维护软件的自觉和习惯。作业:1.为你的StudentController的新增接口编写MockMvc测试。2.尝试修改代码逻辑导致测试失败,体验“安全网”的作用。罗荣良JDBCTemplate操作数据库本节学习目标1.引入JDBC相关依赖2.掌握JdbcTemplate的自动注入3.实现数据的增删改(INSERT/UPDATE/DELETE)4.实现数据的查询(SELECT)与结果映射5.理解Spring对原生JDBC的封装思想痛点回顾:JDBC的繁琐痛点:原生JDBC需要手动写Connection,PreparedStatement,ResultSet处理繁琐的try-catch-finally。解决:Spring提供的一个轻量级工具类。作用:自动管理连接生命周期,只关注SQL语句本身。步骤一:引入依赖pom.xml代码片段:<!--JDBCTemplate依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--MySQL数据库依赖-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>注意:属性名要和数据库字段名保持一致或驼峰对应下划线步骤二:准备实体类与表publicclassUserimplementsRowMapper<User>{
privateintid;//定义主键id
privateStringaccount;//定义账号
privateStringpassword;//定义密码
publicUser(){
}
publicUser(intid,Stringaccount,Stringpassword){
this.id=id;
this.account=account;
this.password=password;
}
@Override
publicUsermapRow(ResultSetrs,introwNum)throwsSQLException{
Useruser=newUser();
user.setId(rs.getInt("id"));
user.setAccount(rs.getString("account"));
user.setPassword(rs.getString("password"));
returnuser;
}//settergetter。。。步骤三:注入JdbcTemplateSpringBoot启动时已自动配置好,直接@Autowired拿来用。@Service
publicclassUserDao{
@Autowired
privateJdbcTemplatejdbcTemplate;
实战:创建表结构(createtable)利用execute()来创建表。@Autowired
privateJdbcTemplatejdbcTemplate;
//创建表
publicvoidcreateTable(){
Stringsql="CREATETABLE`user`(\n"+
"`id`int(11)NOTNULLAUTO_INCREMENT,\n"+
"`account`varchar(255)NOTNULL,\n"+
"`password`varchar(255)NOTNULL,\n"+
"PRIMARYKEY(`id`)\n"+
")ENGINE=InnoDB;";
jdbcTemplate.execute(sql);;
}实战:插入数据(INSERT)核心方法:update()用于增、删、改。//新增用户
publicintaddUser(Useruser){
Stringsql="INSERTINTOuser(account,password)VALUES(?,?)";
returnjdbcTemplate.update(sql,user.getAccount(),user.getPassword());
}实战:修改与删除(UPDATE/DELETE)都是用update方法//更新用户信息
publicintupdateUser(Useruser){
Stringsql="UPDATEuserSETaccount=?,password=?WHEREid=?";
returnjdbcTemplate.update(sql,user.getAccount(),user.getPassword(),user.getId());
}
//删除用户
publicintdeleteUser(intid){
Stringsql="DELETEFROMuserWHEREid=?";
returnjdbcTemplate.update(sql);
}实战:查询对象(RowMapper)痛点:查询结果是ResultSet,怎么变成User对象?神器:BeanPropertyRowMapper//根据id查询用户
publicUsergetUserById(intid){
Stringsql="SELECT*FROMuserWHEREid=?";
returnjdbcTemplate.queryForObject(sql,newUser(),newObject[]{id});
}场景:查询用户。注意:使用query()查询全部
和queryForObject()查询单条。实战:查询列表(QueryList)//查询所有用户
publicList<User>getAllUsers(){
Stringsql="SELECT*FROMuser";
returnjdbcTemplate.query(sql,newBeanPropertyRowMapper<>(User.class));
}//根据账号和密码查询记录
publicUsergetUserByAccountAndPassword(Stringaccount,Stringpassword){
Stringsql="SELECTid,account,passwordFROMuserWHEREaccount=?andpassword=?";
returnjdbcTemplate.queryForObject(sql,newUser(),newObject[]{account,password});
}JdbcTemplate优缺点分析优点:1.简单、运行速度快(接近原生JDBC)。2.适合批量操作和复杂SQL。缺点:1.SQL必须手写(容易拼错)。2.结果集映射虽然有RowMapper,但比起ORM还是很麻烦。本节小结与下节预告小结:依赖引入->注入Bean->update增删改->query查询。预告:为了不写SQL,下节课我们将引入JPA来操作数据库。罗荣良SpringDataJPA基础本节学习目标1.理解ORM(对象关系映射)的核心思想2.辨析JPA、Hibernate与SpringDataJPA的关系3.掌握实体类(Entity)的常用注解配置4.掌握Repository接口的继承体系与使用5.实战:配置MySQL数据源并自动生成表痛点回顾:JDBC的繁琐JDBC代码(连接、SQL、ResultSet遍历)。问题:能否像操作Java集合一样操作数据库?什么是ORM?定义:Object-RelationalMapping(对象关系映射)。JavaObject(类/属性)<-->ORMBridge<-->DBTable(表/字段)作用:消除“阻抗不匹配”,自动转换数据。JPA:规范/接口(Sun/Oracle定义的标准)Hibernate:实现(最流行的ORM框架)SpringDataJPA:封装(Spring提供的更高级抽象)公式:SpringDataJPA>JPA>HibernateJPA:规范/接口(Sun/Oracle定义的标准)SpringDataJPA核心特性1.Repository接口:零SQL实现CRUD。2.方法名查询:findByName自动生成SQL。3.分页排序:内置PagingAndSorting支持。4.自动建表:根据Java类生成数据库表。实战第一步:引入依赖spring-boot-starter-data-jpamysql-connector-j(驱动)<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
实战第二步:配置数据源pertiesurl:jdbc:mysql://localhost:3306/...username/passwordddl-auto:update(自动更新表结构)spring.datasource.url=jdbc:mysql://localhost:3306/jpadb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.show-sql=true实战第三步:定义实体类(Entity)代码截图:Student.java注解:@Entity(标记为实体)@Table(指定表名)@Id(主键)@Entity
@Table(name="student")
publicclassStudent{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
privateLongid;
//学号
@Column(name="xh",length=10)
privateStringxh;
//姓名
@Column(name="cn_name",length=20,nullable=false)
privateStringcnName;
实体类注解详解:主键策略@Id:必须有。@GeneratedValue:主键生成策略。strategy=GenerationType.IDENTITY(MySQL自增)AUTO(默认)@Column:name:数据库列名(默认驼峰转下划线)nullable:是否允许为空length:长度限制@Transient:忽略该字段(不映射到数据库)实体类注解详解:字段映射实体第四步:定义Repository代码截图:StudentRepository.java继承关系:extendsJpaRepository<Student,Long>泛型T:实体类类型(Student)泛型ID:主键类型(Long)publicinterfaceStudentRepositoryextendsJpaRepository<Student,Long>{
}
Repository接口继承体系Repository(标记接口)└──CrudRepository(增删改查)└──PagingAndSortingRepository(分页排序)└──JpaRepository(JPA特有功能)save(entity):保存或更新findById(id):根据ID查询findAll():查询所有deleteById(id):根据ID删除count():统计数量JpaRepository开箱即用的方法演示:自动建表的神奇效果启动SpringBoot应用。查看数据库:发现student表被自动创建了。原理:hibernate.ddl-auto=update演示:基本的CRUD测试在StudentService或测试类中调用studentRepository.save()和findAll()。强调:这就是“零SQL”开发。常见问题与避坑
1.实体类必须有无参构造函数(Lombok@NoArgsConstructor)。2.主键类型要与Repository泛型一致。3.ddl-auto在生产环境严禁使用create或update。本节小结与作业小结:ORM映射、注解配置、Repository使用。作业:1.创建一个Course实体(id,name,credit)。2.编写CourseRepository并测试插入一条数据。罗荣良JPA高级查询与关联映射本节学习目标1.掌握基于方法名的自动查询策略(MagicMethods)2.熟练使用@Query编写JPQL和原生SQL3.实现数据的分页与排序4.掌握实体间的三大关联关系:OneToOne,OneToMany,ManyToMany回顾与引入回顾:JpaRepository提供了save,findAll,findById。问题:如何查询“姓张且年龄大于18岁”的学生?答案:JPA的高级查询能力。魔法一:基于方法名的查询原理:SpringData根据方法名自动解析生成SQL。规则:find+By+属性名+条件关键字示例:findByName(Stringname)自动生成SQL:SELECT*FROMstudentWHEREname=?常用查询关键字速查表除了简单的相等查询,它还支持各种逻辑。大家看这:想要模糊查询?用Like或Containing。想要比较大小?用GreaterThan或LessThan。想要多条件组合?用And或Or。想要排序?用OrderBy。这些关键字就像积木一样,可以组合出非常复杂的查询条件。代码演示:方法名查询StudentRepository:findByName(Stringname)findByAgeGreaterThan(intage)findByNameLike(Stringpattern)List<Student>findByNameContaining(Stringname);List<Student>findByAgeGreaterThan(intage);魔法二:@Query注解查询痛点:方法名太长(findByNameAndAgeGreaterThanAndDepartmentOrderByCreateTimeDesc)难以阅读。解决:直接写查询语句。JPQL:面向对象的查询语言(操作Entity)。NativeSQL:原生数据库SQL(操作Table)。
代码演示:JPQLvsNativeSQLJPQL:@Query("SELECTsFROMStudentsWHEREs.age>18")SQL:@Query(value="SELECT*FROMstudentWHEREage>18",nativeQuery=true)强调:JPQL中Student是类名,不是表名。参数传递与数据修改参数绑定::name配合@Param("name")。数据修改:涉及UPDATE/DELETE时需加@Modifying和@Transactional。大数据量处理:分页与排序接口:PagingAndSortingRepository。参数:Pageable接口。构建:PageRequest.of(page,size,Sort...)。
Repository:Page<Student>findAll(Pageablepageable)Service:studentRepository.findAll(PageRequest.of(0,10))代码演示:分页查询实现实体关联关系:ER图解图示:学生<->饭卡(1:1)部门<->员工(1:N)学生<->课程(N:N)一对一(One-to-One)场景:Student与MealCard。注解:@OneToOne关键属性:@JoinColumn(name="...")(维护方)mappedBy(被维护方)@Entity
publicclassStudent{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
privateLongid;
privateStringname;
@OneToOne(mappedBy=“student”,cascade=CascadeType.ALL)
privateMealCardmealCard;
publicLonggetId(){
returnid;
}
。。。场景:Department(1)与Employee(N)。结构:在“多”的一方(Employee)存外键。注解:@ManyToOne(员工侧)+@OneToMany(部门侧)。一对多(One-to-Many)-最常用@Entity
publicclassArticle{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
privateLongid;
privateStringtitle;
privateStringcontent;
//mappedBy属性指定拥有关系的实体中的字段。
//CascadeType.ALL表示当删除文章时,相关的评论也会被删除。
@OneToMany(mappedBy="article",cascade=CascadeType.ALL,fetch=FetchType.LAZY)
privateList<Comment>comments;
publicArticle(){
this.comments=newArrayList<>();
}
关联关系的“所有权”(MappedBy)关联关系的“所有权”(MappedBy)|原则:外键在哪里,所有权就在哪里。解释:mappedBy="department"告诉JPA,“去Employee类里找department属性,它负责维护关系”。多对多(Many-to-Many)场景:Student与Course。结构:需要第三张中间表(student_course)。注解:@ManyToMany+@JoinTable。@Entity
@Table(name="students")
publicclassStudent{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
privateLongid;
privateStringname;
privateIntegerage;
@ManyToMany
@JoinTable(
name="student_course",
joinColumns=@JoinColumn(name="student_id"),
inverseJoinColumns=@JoinColumn(name="course_id")
)
privateSet<Course>courses=newHashSet<>();
级联操作(Cascade)与懒加载CascadeType.ALL:删了部门,底下的员工也被删除(慎用)。FetchType.LAZY:查部门时,不立即查员工(性能优化)。FetchType.EAGER:立即查。本节小结与作业小结:命名查询、@Query、三大关联关系。作业:实现“一个老师教多门课”(1:N)的关联映射,并编写查询接口。罗荣良MyBatisPlus与
代码生成器持久层的演进之路Stage1:JDBC(石器时代)手动开关连接,拼写SQL字符串,繁琐易错。Stage2:MyBatis(铁器时代)ORM映射,SQL与代码分离,但简单的CRUD还要手写XML。Stage3:MyBatisPlus(工业时代)只做增强不做改变。单表CRUD零SQL实现。MyBatis基础回顾:注解开发MyBatisPlus和MyBatis关系
@Mapper:标记接口。@Select("SELECT*FROMuser"
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年烟台房产政策考试试题及答案
- 2026年卫生资格药师考试试题及答案
- 2026年高考历年口语考试试题及答案
- 文档管理资料归档系统模板
- 节点进度保障承诺书范文4篇
- 建筑行业薪酬管理标准与实施
- 电子商务平台卖家运营策略
- 行政主管通过学习办公自动化提高办公效率指导书
- 小区停电事故紧急恢复预案
- 请求协助解决客户纠纷的回复函9篇
- GB/T 40815.6-2026电气和电子设备机械结构符合英制系列和公制系列机柜的热管理第6部分:户内机柜的空气再循环和旁路
- 安徽省“江南十校”2026届高三综合素质检测英语试题
- 2026年平安笔试测试题答案
- 雨课堂学堂在线学堂云《当代中国社会与文化:大湾区文化景观(暨南)》单元测试考核答案
- 外研版(2019)选择性必修 第三册Unit 4 A glimpse of the futureUnderstanding ideas课件(内嵌视频)
- 2024年贵州六盘水市公安局合同制留置看护人员招聘笔试参考题库附带答案详解
- 银行资产配置方案
- 安捷伦GC仪器操作步骤
- GFM阀控密封铅酸蓄电池安装维护手册
- 牙体代型制备与修整(口腔固定修复工艺课件)
- 美学第六讲日常生活美
评论
0/150
提交评论