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

IntelliJ+SpringBoot项目实战(四)--快速上手数据库开发

       对于新手学习SpringBoot开发,可能最急迫的事情就是尽快掌握数据库的开发。目前数据库开发主要流行使用Mybatis和Mybatis Plus,不过这2个框架对于新手而言需要一定的时间掌握,如果快速上手数据库开发,可以先按照本文介绍的方式使用JdbcTemplate进行数据库开发。另外不管用那种开发方式,都需要进行数据库链接的配置。

       本文数据库链接采用的阿里的druid数据源,数据库采用Mysql数据库。首先我们在application-dev.yml中配置数据库链接,这里定义了两个数据源,不过为了演示,两个数据源都指向的同一个数据库,下面是openjweb-sys工程下的application-dev.yml:

server:port: 8001spring:datasource:ds1:type: com.alibaba.druid.pool.DruidDataSourceurl: jdbc:mysql://localhost:3306/erpusername: rootpassword: rootds2:type: com.alibaba.druid.pool.DruidDataSourceurl: jdbc:mysql://localhost:3306/erpusername: rootpassword: root

在主工程的pom.xml中引入了druid依赖和springframework的jdbc依赖:

<!--druid--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.23</version>
</dependency>
<!--jdbc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency>

因为考虑到不是每个子工程都需要链接mysql数据库,所以mysql的依赖放在openjweb-sys的pom.xml中,不过考虑到配置类的都放到starter模块里,所以openjweb-sys里配置了依赖datasource-openjweb-starter:

<dependency><groupId>org.openjweb</groupId><artifactId>datasource-openjweb-starter</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency>

而在datasource-openjweb-starter的pom.xml里引入了mysql依赖:

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.connector.version}</version><scope>runtime</scope>
</dependency>

其中${mysql.connector.version}在主工程的pom.xml中的配置:

<mysql.connector.version>8.0.27</mysql.connector.version>

接下来就可以开发数据库配置类和调用示例,首先在openjweb-sys的org.openjweb.sys.config下面开发一个DataSourceConfig类:

package org.openjweb.sys.config;
import javax.sql.DataSource;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;import com.alibaba.druid.pool.DruidDataSource;@Slf4j
@Configuration
public class DataSourceConfig {@Primary@Bean(name = "dsOne")@ConfigurationProperties("spring.datasource.ds1")DataSource dsOne() {DruidDataSource ds1 = new DruidDataSource();return ds1;}//@Bean@Bean(name = "dsTwo")@ConfigurationProperties("spring.datasource.ds2")DataSource dsTwo() {DruidDataSource ds2 = new DruidDataSource();return ds2;}//为第一个数据源绑定一个事务管理器@Bean(name = "transactionManager1")public DataSourceTransactionManager dataSourceTransactionManagerOne(@Qualifier("dsOne") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}@Bean(name = "transactionManager2")public DataSourceTransactionManager dataSourceTransactionManagerTwo(@Qualifier("dsTwo") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}}

其中@ConfigurationProperties("spring.datasource.ds1")是自动从application-dev.yml的配置中读取ds1的设置注入到组件中,ds2同理。

然后开发JdbcTemplateConfig类:

package org.openjweb.sys.config;import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;

@Configurationpublic class JdbcTemplateConfig {private static JdbcTemplate  defaultJdbcTemplate  = null;public static JdbcTemplate  getDefaultJdbcTemplate(){return defaultJdbcTemplate;}@Bean(name = "jdbcTemplateOne")JdbcTemplate jdbcTemplateOne(@Qualifier("dsOne") DataSource dataSource) {JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);this.defaultJdbcTemplate = jdbcTemplate;return jdbcTemplate;//return new JdbcTemplate(dataSource);}@Bean(name = "jdbcTemplateTwo")JdbcTemplate jdbcTemplateTwo(@Qualifier("dsTwo") DataSource dataSource) {return new JdbcTemplate(dataSource);}}

在上面的类中定义了2个Bean,分别指向了dsOne和dsTwo两个数据源。

接下来可以利用这2个JdbcTemplate开发接口应用。

现在在openjweb-sys模块的org.openjweb.sys.api下创建一个演示接口类为DemoDBApi:

package org.openjweb.sys.api;import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.List;
import java.util.Map;/*** http://localhost:8001/demo/queryParam?parmName=version* */
@RestController
@RequestMapping("/demo")
@Slf4j
public class DemoDBApi {@Resource(name = "jdbcTemplateOne")private JdbcTemplate service;@Resource(name = "jdbcTemplateTwo")private JdbcTemplate service2;@GetMapping("queryParam")public JSONObject queryParam(@RequestParam(value = "parmName")String parmName){//查询countInteger count = service.queryForObject("select count(*) from comm_system_parms",Integer.class);JSONObject json = new JSONObject();json.put("num",count);//下面按查询条件查询--查单个值parmName = "version";//因为是演示程序,这里不从请求中获取参数String sql = "select parm_value from comm_system_parms where parm_name=?";String parmValue = service.queryForObject(sql,new Object[]{parmName},String.class);log.info(parmValue);//使用log.info需要在类前面加@Slf4j 注解//查询列表JSONArray jsonArray = new JSONArray();String parmLike ="version%";String sql1 = "select parm_name,parm_value from comm_system_parms where parm_name like ?";List<Map<String,Object>> list = service.queryForList(sql1,new Object[]{parmLike});if(list!=null&&list.size()>0){for (Map<String,Object> data:list   ) {JSONObject dataJson = new JSONObject();dataJson.put("parmName",data.get("parm_name")==null?"":data.get("parm_name").toString());dataJson.put("parmValue",data.get("parm_value")==null?"":data.get("parm_value").toString());jsonArray.add(dataJson);}}//如果结果集顶多一条记录,查询一条记录可使用queryForMapMap<String,Object> map = null;//这次使用第二个数据源(为了演示方便,链接配置实际指向一个数据库)map = service2.queryForMap("select * from comm_system_parms where parm_name=?",new Object[]{parmName});if(map!=null){log.info("map查到数据:");log.info(map.get("parm_value")==null?"":map.get("parm_value").toString());}json.put("count",count);json.put("data",jsonArray);return json;}
}

在上面的例子中分别演示了select count(*)、查询结果为单一字符串、查询结果为数据列表(queryForList)、查询结果为一条记录多个字段(queryForMap)等。查看演示效果可启动SpringBoot后访问:

http://localhost:8001/demo/queryParam?parmName=version

对于新手如果还不了解mybatis或mybatis-plus可使用jdbcTemplate进行快速开发,当然如果在生产环境中使用的话还要考虑到接口调用的权限。下面给出本示例的comm_system_parm表结构以方便大家使用:


CREATE TABLE `comm_system_parms` (
  `pk_id` varchar(40) NOT NULL,
  `row_id` varchar(40) NOT NULL,
  `sort_no` bigint(20) DEFAULT NULL,
  `create_dt` varchar(23) DEFAULT NULL,
  `update_dt` varchar(23) DEFAULT NULL,
  `create_uid` varchar(32) DEFAULT NULL,
  `update_uid` varchar(32) DEFAULT NULL,
  `data_flg` varchar(6) DEFAULT NULL,
  `flow_status` varchar(16) DEFAULT NULL,
  `obj_name` varchar(40) DEFAULT NULL,
  `master_row_id` varchar(40) DEFAULT NULL,
  `flow_trans_id` varchar(40) DEFAULT NULL,
  `parm_old_values` varchar(255) DEFAULT NULL,
  `parm_name` varchar(40) NOT NULL,
  `parm_desc` varchar(255) DEFAULT NULL,
  `parm_value` varchar(2000) DEFAULT NULL,
  PRIMARY KEY (`pk_id`),
  UNIQUE KEY `parm_name` (`parm_name`),
  KEY `idx_1730778572260000923` (`parm_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 

INSERT INTO `comm_system_parms` VALUES ('85', '61a31b6fae8c4cb5a3ff2e343e7402b1', NULL, '2012-05-01 18:32:59', '2016-05-25 09:35:01', 'admin', 'admin', NULL, '00', NULL, NULL, '1335868379171000735', NULL, 'version', '平台版本号', '3.6');

项目实例地址见github:https://github.com/openjweb/cloud/tree/mastericon-default.png?t=O83Ahttps://github.com/openjweb/cloud/tree/master

相关文章:

IntelliJ+SpringBoot项目实战(四)--快速上手数据库开发

对于新手学习SpringBoot开发&#xff0c;可能最急迫的事情就是尽快掌握数据库的开发。目前数据库开发主要流行使用Mybatis和Mybatis Plus,不过这2个框架对于新手而言需要一定的时间掌握&#xff0c;如果快速上手数据库开发&#xff0c;可以先按照本文介绍的方式使用JdbcTemplat…...

利用oss进行数据库和网站图片备份

1.背景 由于网站迁移到香港云 服务器&#xff0c;虽然便宜&#xff0c;但是宿主服务器时不时重启&#xff0c;为了预防不可控的因素导致网站资料丢失&#xff0c;所以想到用OSS 备份网站数据&#xff0c;bucket选择在香港地区创建&#xff0c;这样和你服务器传输会更快。 oss…...

Excel - VLOOKUP函数将指定列替换为字典值

背景&#xff1a;在根据各种复杂的口径导出报表数据时&#xff0c;因为关联的表较多、数据量较大&#xff0c;一行数据往往会存在三个以上的字典数据。 为了保证导出数据的效率&#xff0c;博主选择了导出字典code值后&#xff0c;在Excel中处理匹配字典值。在查询百度之后&am…...

实验室管理平台:Spring Boot技术构建

3系统分析 3.1可行性分析 通过对本实验室管理系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本实验室管理系统采用SSM框架&#xff0c;JAVA作为开发语言&a…...

操作系统进程和线程——针对实习面试

目录 操作系统进程和线程什么是进程和线程&#xff1f;进程和线程的区别&#xff1f;进程有哪些状态&#xff1f;什么是线程安全&#xff1f;如何实现线程安全&#xff1f;什么是线程安全&#xff1f;如何实现线程安全&#xff1f; 进程间的通信有哪几种方式&#xff1f;什么是…...

使用 cnpm 安装 Electron,才是正确快速的方法

当然&#xff0c;下面是总结的几种安装 Electron 的方法&#xff0c;包括使用 npm 和 cnpm&#xff0c;以及一些常见的问题解决技巧。 ### 1. 使用 npm 安装 Electron #### 步骤 1: 初始化项目 在你的项目目录中初始化一个新的 Node.js 项目&#xff1a; bash npm init -y …...

【人工智能】PyTorch、TensorFlow 和 Keras 全面解析与对比:深度学习框架的终极指南

文章目录 PyTorch 全面解析2.1 PyTorch 的发展历程2.2 PyTorch 的核心特点2.3 PyTorch 的应用场景 TensorFlow 全面解析3.1 TensorFlow 的发展历程3.2 TensorFlow 的核心特点3.3 TensorFlow 的应用场景 Keras 全面解析4.1 Keras 的发展历程4.2 Keras 的核心特点4.3 Keras 的应用…...

【第八课】Rust中的函数与方法

目录 前言 函数指针 函数当作另一个函数的参数 函数当作另一个函数的返回值 闭包 方法 关联函数 总结 前言 在前面几课中&#xff0c;我们都或多或少的接触到了rust中的函数&#xff0c;rust中的函数和其他语言的并没有什么不同&#xff0c;简单的语法不在这篇文章中赘…...

c语言学习25二维数组

1 二维数组 1.1二维数组认识 二维数组本质是一个数组。 举例&#xff1a; int a[10][3] 数组名 a&#xff1b; 元素个数10&#xff1b; 数组元素类型&#xff1a;int [3]; 数组元素下标&#xff1a;0~9 这是一个数组&#xff0c;有十个元素&#xff0c;每个元…...

如何理解Lua 使用虚拟堆栈

虚拟堆栈的基本概念 Lua使用虚拟堆栈来实现Lua和C&#xff08;或其他宿主语言&#xff09;之间的交互。这个虚拟堆栈是一个数据结构&#xff0c;用于存储Lua的值&#xff0c;如数字、字符串、表、函数等。它在Lua状态机&#xff08;lua_State&#xff09;内部维护&#xff0c;为…...

【倍数问题——同余系】

题目 代码 #include <bits/stdc.h> using namespace std; const int N 1e5 10, M 1e3 10; int maxx[M][4]; void consider(int r, int x) {if(x > maxx[r][1]){maxx[r][3] maxx[r][2];maxx[r][2] maxx[r][1];maxx[r][1] x;}else if(x > maxx[r][2]){maxx[…...

「San」监听DOM变化的方法

在 San框架 中监听组件内部字体大小并调整宽度&#xff0c;可以结合 自定义事件 或 数据绑定 来实现动态调整。San 框架没有直接的监听 DOM 尺寸变化的内置方法&#xff0c;但可以通过以下步骤实现&#xff1a; 方法一&#xff1a;使用 ResizeObserver 监听字体变化 在组件的 …...

如何选择服务器

如何选择服务器 选择服务器时应考虑以下几个关键因素&#xff1a; 性能需求。根据网站的预期流量和负载情况&#xff0c;选择合适的处理器、内存和存储容量。考虑网站是否需要处理大量动态内容或高分辨率媒体文件。 可扩展性。选择一个可以轻松扩展的服务器架构&#xff0c;以便…...

嵌入式驱动面试总结

操作系统&#xff1a; 中断的处理流程&#xff0c;中断处理需要注意些什么 软中断和硬中断区别 linux驱动用过那些锁&#xff0c;信号量&#xff0c;互斥锁 自旋锁和互斥锁的区别 二值信号量和互斥信号量有什么区别 进程锁怎么实现的&#xff0c;说一下流程&#xff1b; …...

Uniapp 简单配置鸿蒙

Uniapp 简单配置鸿蒙 前言下载并配置鸿蒙IDEHbuilder X 配置基本的信息生成相关证书登录官网获取证书IDE配置证书添加调试设备可能出现的问题前言 如今鸿蒙的盛起,作为多端开发的代表也是开始兼容鸿蒙应用的开发,接下来我将介绍如何在uniapp中配置鸿蒙。 注意:hbuilder X的…...

线程池的实现与应用

一、线程池 一种线程使用模式。线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能。而线程池维护着多个线程&#xff0c;等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用&#xff0c…...

基于Java Springboot单位考勤系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…...

近源渗透|HID ATTACK从0到1

前言 对于“近源渗透”这一术语&#xff0c;相信大家已经不再感到陌生。它涉及通过伪装、社会工程学等手段&#xff0c;实地侵入企业办公区域&#xff0c;利用内部潜在的攻击面——例如Wi-Fi网络、RFID门禁、暴露的有线网口、USB接口等——获取关键信息&#xff0c;并以隐蔽的…...

【linux】插入新硬盘如何配置:格式化、分区、自动挂载(Ubuntu)

文章目录 具体方法GPT分区表&#xff08;GUID Partition Table&#xff09;&#xff08;建议都用这种分区方法&#xff09;MBR分区表方法&#xff08;最大支持2TB分区&#xff09;&#xff08;Master Boot Record&#xff09; 附加&#xff1a;如何查看硬盘的型号另外&#xff…...

YOLOv8-ultralytics-8.2.103部分代码阅读笔记-block.py

block.py ultralytics\nn\modules\block.py 目录 block.py 1.所需的库和模块 2.class DFL(nn.Module): 3.class Proto(nn.Module): 4.class HGStem(nn.Module): 5.class HGBlock(nn.Module): 6.class SPP(nn.Module): 7.class SPPF(nn.Module): 8.class C1(nn.M…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...