当前位置: 首页 > 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&…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...