当前位置: 首页 > news >正文

SSM部分

声明式事务

从之前的事务控制的代码中可以看出,是有规律可循,代码的结构基本是确定的,所以框架就可以将固定模式的代码抽取出来,进行相关的封装。

封装起来后,我们只需要在配置文件中进行简单的配置即可完成操作。

  • 好处1:提高开发效率
  • 好处2:消除了冗余的代码
  • 好处3:框架会综合考虑相关领域中在实际开发环境下有可能遇到的各种问题,进行了健壮性、性 能等各个方面的优化

所以,我们可以总结下面两个概念:

  • 编程式:自己写代码实现功能
  • 声明式:通过配置让框架实现功能

基于注解的声明式事务

添加驱动依赖

 <dependencies><!-- 基于Maven依赖传递性,导入spring-context依赖即可导入当前所需所有jar包 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.1</version></dependency><!-- Spring 持久化层支持jar包 --><!-- Spring 在执行持久化层操作、与持久化层技术进行整合过程中,需要使用orm、jdbc、tx三个jar包 --><!-- 导入 orm 包就可以通过 Maven 的依赖传递性把其他两个也导入 --><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>5.3.1</version></dependency><!-- Spring 测试相关 --><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.3.1</version></dependency><!-- junit测试 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.31</version></dependency><!-- 数据源 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.0.31</version></dependency><!--       添加lombok驱动--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version></dependency></dependencies>

创建jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTime=UTC
jdbc.username=root
jdbc.password=root

配置文件

<?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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><!--    引入jdbc.properties--><context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder><!--配置德鲁伊--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"></property><property name="url" value="${jdbc.url}"></property><property name="username" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property></bean><bean class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean>
</beans>

创建数据库表

--Table structure for t_book
-- ----------------------------
DROP TABLE IF EXISTS `t_book`;
CREATE TABLE `t_book`  (`book_id` int NOT NULL AUTO_INCREMENT COMMENT '主键',`book_name` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '图书名称',`price` int NULL DEFAULT NULL COMMENT '价格',`stock` int UNSIGNED NULL DEFAULT NULL COMMENT '库存(无符号)',PRIMARY KEY (`book_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of t_book
-- ----------------------------
INSERT INTO `t_book` VALUES (1, '斗破苍\r\n穹', 80, 98);
INSERT INTO `t_book` VALUES (2, '斗罗大陆', 50, 99);SET FOREIGN_KEY_CHECKS = 1;
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user`  (`user_id` int NOT NULL AUTO_INCREMENT COMMENT '主键',`username` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '用户名',`balance` int UNSIGNED NULL DEFAULT NULL COMMENT '余额(无符号)',PRIMARY KEY (`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (1, 'admin', 20);
INSERT INTO `t_user` VALUES (2, '二哈', 9950);SET FOREIGN_KEY_CHECKS = 1;

创建测试代码

BookController

package com.hyh.spring.controller;import com.hyh.spring.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;/*** @version 1.0* @BelongsProject:IntelliJ IDEA* @BelongsPackage:com.hyh.spring.controller* @Author:hyhWTX* @ClassName:BookController* @CreateTime:2022年-12月-31日 21:49* @Description: TODO (一句话描述以下该类的功能)*/
@Controller
public class BookController {@Autowiredprivate BookService bookService;public  void  buyBook(Integer userId,Integer bookId  ){bookService.buyBook(userId,bookId);}
}

BookDao

package com.hyh.spring.dao;/*** @version 1.0* @BelongsProject:IntelliJ IDEA* @BelongsPackage:com.hyh.spring.dao* @Author:hyhWTX* @ClassName:BookDao* @CreateTime:2022年-12月-31日 21:50* @Description: TODO (一句话描述以下该类的功能)*/
public interface BookDao {/*** @Description:根据图书ID查询图书价格* @param bookId* @return Integer*/Integer getPriceByBookId(Integer bookId);/*** @Description:更新图书的库存* @param bookId*/void updateStock(Integer bookId);/*** @Description:更新用户的余额* @param userId* @param price*/void updateBalance(Integer userId, Integer price);
}

BookDaoImpl

package com.hyh.spring.dao.impl;import com.hyh.spring.dao.BookDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;/*** @version 1.0* @BelongsProject:IntelliJ IDEA* @BelongsPackage:com.hyh.spring.dao.impl* @Author:hyhWTX* @ClassName:BookDaoImpl* @CreateTime:2022年-12月-31日 21:50* @Description: TODO (一句话描述以下该类的功能)*/
@Repository
public class BookDaoImpl implements BookDao {@Autowiredprivate JdbcTemplate jdbcTemplate;@Overridepublic Integer getPriceByBookId(Integer bookId) {String sql ="select price from t_book where book_id = ?";return jdbcTemplate.queryForObject(sql,Integer.class,bookId);}@Overridepublic void updateStock(Integer bookId) {String sql = "update t_book set stock = stock-1 where book_id = ?";jdbcTemplate.update(sql,bookId);}@Overridepublic void updateBalance(Integer userId, Integer price) {String sql = "update t_user set balance  = balance -? where user_id = ?";jdbcTemplate.update(sql,price,userId);}
}

User

package com.hyh.spring.model;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @version 1.0* @BelongsProject:IntelliJ IDEA* @BelongsPackage:com.hyh.spring.model* @Author:hyhWTX* @ClassName:User* @CreateTime:2022年-12月-31日 18:21* @Description: TODO (一句话描述以下该类的功能)*/
//@Data:注解是lombok中的注解,用于针对属性自动生成set和get方法、无参数的构造方法、toString、equals、hashcode
@Data
//生成带有所有参数的构造方法
@AllArgsConstructor
//生成无参数的构造方法
@NoArgsConstructor
public class User {//用户idprivate Integer id;//用户姓名private String username;//用户密码private String password;//用户年龄private Integer age;//用户性别private String gender;//用户emailprivate String email;
}

BookService

package com.hyh.spring.service;/*** @version 1.0* @BelongsProject:IntelliJ IDEA* @BelongsPackage:com.hyh.spring.service* @Author:hyhWTX* @ClassName:BookService* @CreateTime:2022年-12月-31日 21:49* @Description: TODO (一句话描述以下该类的功能)*/
public interface BookService {/*** @Description: 买书* @param userId* @param bookId*/void buyBook(Integer userId, Integer bookId);
}

BookSerViceImpl

package com.hyh.spring.service.impl;import com.hyh.spring.dao.BookDao;
import com.hyh.spring.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.concurrent.TimeUnit;/*** @version 1.0* @BelongsProject:IntelliJ IDEA* @BelongsPackage:com.hyh.spring.service.impl* @Author:hyhWTX* @ClassName:BookSerViceImpl* @CreateTime:2022年-12月-31日 21:49* @Description: TODO (一句话描述以下该类的功能)*/
@Service
@Transactionalpublic class BookSerViceImpl implements BookService {@Autowiredprivate BookDao bookDao;@Overridepublic void buyBook(Integer userId, Integer bookId) {//查询图书的价格Integer price = bookDao.getPriceByBookId(bookId);//更新图书的库存,假设每次只买一本书bookDao.updateStock(bookId);//更新用户的余额bookDao.updateBalance(userId,price);}
}

相关文章:

SSM部分

声明式事务 从之前的事务控制的代码中可以看出&#xff0c;是有规律可循&#xff0c;代码的结构基本是确定的&#xff0c;所以框架就可以将固定模式的代码抽取出来&#xff0c;进行相关的封装。 封装起来后&#xff0c;我们只需要在配置文件中进行简单的配置即可完成操作。 …...

【Springboot系列】Springboot接管所有Controller,magic-api源码阅读

系列文章地址:Spring Boot学习大纲,可以留言自己想了解的技术点 最近在项目中使用了一个第三方的包 magic-api,节省了很多的时间,整体来说就是只用写sql就好了,不用写service,controller那些,全部统一处理了。 具体的使用大家可以搜索下,网上到处都是,建议去官网看。…...

二、LED子系统数据结构详解

个人主页&#xff1a;董哥聊技术我是董哥&#xff0c;嵌入式领域新星创作者创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01;文章目录1、核心数据结构1.1 gpio_led_platform_data1.2 gpio_leds_priv1.3 gpio_led1.4 gpio_led_data1.5 led_…...

Kubernetes(11):数据存储详解

在前面已经提到,容器的生命周期可能很短,会被频繁地创建和销毁。那么容器在销毁时,保存在容器中的数据也会被清除。这种结果对用户来说,在某些情况下是不乐意看到的。为了持久化保存容器的数据,kubernetes引入了Volume的概念。 Volume是Pod中能够被多个容器访问的共享目录…...

随想录Day43--动态规划: 1049. 最后一块石头的重量 II , 494. 目标和 , 474.一和零

最后一块石头重量转化为将一个集合分隔成两个集合&#xff0c;两个集合之间的差值最小&#xff0c;就是最后剩下最小的石头重量。这里可以求集合的一个平均值&#xff0c;如果正好等于平均值&#xff0c;说明可以抵消&#xff0c;这时候重量为0&#xff0c;如果不行&#xff0c…...

Qt中对TCP粘包的处理

当时用TCP协议传输数据时&#xff0c;经常出现粘包的现象 当服务器向客户端发送数据之后&#xff0c;客户端还没有接收数据的时候&#xff0c;这段时间数据在什么地方&#xff1f; 1、服务器&#xff1f;服务器已经发出数据了 2、网线&#xff1f;数据应该在内存&#xff0c;怎…...

贪心-单调递增的数字

当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c;返回 小于或等于 n 的最大数字&#xff0c;且数字呈 单调递增 。 示例 1: 输入: n 10 输出: 9示例 2: 输入: n 1234 输出: 1234示例 3: 输入…...

你真的会用搜索引擎吗?

作为一名在校大学生&#xff0c;对于搜索资料这一件事深有体会&#xff0c;特别是在期末考试突击的时候&#xff0c;如何利用搜索引擎&#xff0c;快速找到自己想要的知识&#xff0c;快速理解这个知识点&#xff0c;想必是每位大学生的必备技能了。 我们在学习一个知识点的过…...

KDCJ-20kV冲击耐压测试仪

一、产品简介 KDCJ-20kV冲击耐压测试仪是电力设备高压试验的基本项目之一&#xff0c;电力设备在设计、制造及修缮之后都要求进行冲击试验以验证或检验。因此&#xff0c;冲击电压试验设备有着广泛的应用&#xff0c;在工厂、研究机构及大专院校的高压试验室中都可以看到不同规…...

【Mybatis源码分析】TypeAliasRegistry源码分析

TypeAliasRegistry源码分析一、引入类型别名二、typeAlias 的三种配置方式三、TypeAliasRegistry源码分析三种配置方式源码解析校验过程Mybatis默认的别名配置四、总结一、引入类型别名 当配置 XML 文件&#xff0c;需要指明Java类型时&#xff0c;类型别名可替代Java类型的全…...

节点高负载

如何判断节点高负载? 可以通过 top 或 uptime 来确定 load 大小,如果 load 小于 CPU 数量,属于低负载,如果大于 CPU 数量 2~3 倍,就比较高了,当然也看业务敏感程度,不太敏感的大于 4 倍算高负载。 排查思路 观察监控:通常不是因为内核 bug 导致的高负载,在卡死之前…...

动态规划(一) part1

T1:一个数组 中的最长 升序 子序列 的长度 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组…...

Ubuntu显卡报错:Failed to initialize NVML Driver/library version mismatch

问题描述 输入指令nvidia-smi的时候&#xff0c;出现如下&#xff1a; Failed to initialize NVML: Driver/library version mismatch看起来好像是版本不匹配&#xff0c;在网上查了很多都没有解决问题&#xff0c;重启也不行&#xff0c;结果证明最好的办法是重新安装cuda。…...

JAVA企业电子采购系统源码:采购过程更规范,更透明

满足采购业务全程数字化&#xff0c; 实现供应商管理、采购需求、全网寻源、全网比价、电子招 投标、合同订单执行的全过程管理。 电子招标采购&#xff0c;是指在网上寻源和采购产品和服务的过程。对于企业和企业主来说&#xff0c;这是个既省钱又能提高供应链效率的有效方法…...

5.5G产业再提速!高通5GAdvanced-ready芯片商用终端下半年面世

MWC2023大会召开在即&#xff0c;5GAdvanced产业再添重磅消息&#xff01;2月15日&#xff0c;高通宣布推出全球首个5GAdvanced-ready基带芯片——骁龙X755G调制解调器及射频系统&#xff0c;支持毫米波和Sub-6GHz频段&#xff0c;带来网络覆盖、时延、能效和移动性等全方位的提…...

基于B站王阿华的视频——为什么当下自媒体都在制造焦虑以及如何摆脱

观后笔记2.0——一些深入的思考 1.情绪大约在两千万年前&#xff0c;哺乳脑统治期间诞生。 2.情绪分为积极情绪和负面情绪。决定某种情绪的出现取决于安全感等级。 自媒体制造负面情绪&#xff0c;想尽办法挑起情绪&#xff0c;吸引流量 安全感充足时&#xff0c;由积极情绪…...

一、Docker介绍:

Docker官方网站&#xff1a;https://www.docker.com/ Docker容器技术是虚拟化技术的一个分支&#xff0c;虚拟化技术一般分为两种&#xff1a; 硬件级虚拟化&#xff08;hardware-level-virtualization&#xff09; &#xff1a;是运行在硬件之上的虚拟化技术&#xff0c;它的核…...

Vue进阶(一篇进入Vue3的世界)

文章目录一、初识Vue3二、Vue3新语法糖setup三、响应式数据函数3.1 ref函数3.2 reactive函数3.3 ref和reactive函数的异同四、Vue3的响应式原理五、语法更新5.1 Vue3使用computed计算属性5.2 Vue3使用watch监视属性的注意点5.2.1 监视ref对象5.2.2 监视reactive对象5.2.3 监视嵌…...

功能测试的分类,分别有什么作用?

目录 前言 一、链接测试 二、表单测试 三、搜索测试 四、删除测试 五、cookies/session测试 六、数据库测试 七、峰值测试/容量测试 八、相容性测试/安全测试 前言 功能测试主要包括链接测试、表单测试、搜索测试、删除测试、cookies、session测试、数据库测试等部分…...

51单片机学习笔记_14 红外遥控

红外传感器 遥控器通过红外 LED 发送调制后的信号&#xff0c;开发板上的红外接收模块接收遥控器的红外线。 单工异步&#xff0c;940nm 波长&#xff08;还有一种 250nm 的N&#xff0c;可见光&#xff09;&#xff0c;EC 通信标准。 38KHz&#xff1a;红外线频率。 IN&…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...