百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

SpringBoot之数据访问——访问SQL数据库!

liuian 2025-07-08 20:04 19 浏览

访问SQL数据库

SQL数据库主要指关系型数据库。本节主要讲解Spring Boot集成MySQL数据库的相关操作。Spring框架为MySQL数据库提供了广泛的技术支持,从封装了JDBC操作的JdbcTemplate,到支持ORM技术的Hibernate等。Spring Data是Spring的一个子项目,它提供了Repository接口,可以通过函数名直接完成SQL语句的查询。

JdbcTemplate模板类

Java的javax.sql.DataSource接口提供了处理数据库连接的标准方法,通过配置一个连接池提供数据库连接,Spring Boot可以完成一些自动配置。首选HikariCP连接池,也可使用Tomcat连接池,如果这两个连接池都不可用,则使用DBCP2。当然,开发者也可以自定义连接池,如采用阿里巴巴的Druid等。

Spring Boot提供了自动配置,因此开发者只需在配置文件中添加数据库的配置信息即可。Spring Boot提供了多种类型的连接池,如spring.datasource.hikari.*、spring.datasource.tomcat.*和spring.datasource.dbcp2.*等。

注意:如果不指定spring.datasource.url属性,则Spring Boot会自动配置内嵌的数据库。

一个简单的DataSoruce配置如下:

spring.datasource.url=jdbc:mysql://localhost/test

spring.datasource.username=dbuser

spring.datasource.password=dbpass

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.tomcat.max-wait=10000

spring.datasource.tomcat.max-active=50

spring.datasource.tomcat.test-on-borrow=true

原生的JDBC操作数据库需要自己创建连接,使用完之后还需要手动关闭。Spring框架为了提高开发效率,对JDBC进行了封装,即提供了JdbcTemplate类。JdbcTemplate是一个模板类,提供了操作数据库的基本方法,如插入、更新、删除及查询等操作,同时还封装了一些固定操作,如连接的创建与关闭。JdbcTemplate类提供了回调接口的方式,用于实现一些可变操作,如ConnectionCallback可以返回一个连接,StatementCallback可以返回一个Statement,还可以在回调接口做一些映射关系的逻辑处理。

JdbcTemplate模板类提供了以下几种类型的方法:

execute()方法:可以执行任何SQL语句,一般多用于执行DDL(做数据定义)类型的语句。

update()方法:执行新增、修改、删除等语句。

query()方法:执行与查询相关的语句。

call()方法:执行与数据库存储过程和函数相关的语句。

下面通过一个简单的示例展示JdbcTemplate的操作。

(1)定义一张user表,结构如下:

CREATE TABLE `user` (

`user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',

`user_name` varchar(128) NOT NULL COMMENT '用户昵称',

`login_name` varchar(128) NOT NULL COMMENT '登录账户',

`user_head_img` varchar(256) DEFAULT NULL COMMENT '用户头像',

`last_login_time` int(11) DEFAULT NULL COMMENT '上次登录时间'

PRIMARY KEY (`user_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

(2)使用JdbcTemplate需要依赖spring-boot-starter-jdbc和mysql-connector-java包。配置文件application.yml如下:

spring:

datasource:

url: jdbc:mysql://localhost:3306/test_db?

useUnicode=true&character

Encoding=UTF8&characterSetResults=UTF8&serverTimezone=UTC

username: root

password: test1111

driver-class-name: com.mysql.cj.jdbc.Driver

(3)定义实体类User,代码如下:

//声明实体类User

public class User {

private Integer userId;

//用户ID

private String userName;

//用户名

private String loginName;

//登录名

private Integer lastLoginTime;

//登录时间

private String userHeadImg;

//用户头像

public Integer getUserId() {

return userId;

}

public void setUserId(Integer userId) {

this.userId = userId;

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName == null ? null :

userName.trim();

}

public String getLoginName() {

return loginName;

}

public void setLoginName(String loginName) {

this.loginName = loginName == null ? null :

loginName.trim();

}

public Integer getLastLoginTime() {

return lastLoginTime;

}

public void setLastLoginTime(Integer lastLoginTime) {

this.lastLoginTime = lastLoginTime;

}

public String getUserHeadImg() {

return userHeadImg;

}

public void setUserHeadImg(String userHeadImg) {

this.userHeadImg = userHeadImg == null ? null :

userHeadImg.

trim();

}

}

(4)定义Dao层的类UserDao,在其中使用JdbcTemplate操作MySQL数据库,代码如下:

//声明UserDao

@Repository

public class UserDao {

@Autowired

private JdbcTemplate jdbcTemplate; //JdbcTemplate注入

public String add(User user){

//insert语句

String sql = "insert into user(user_name, login_name,

last_

login_time, user_head_img) value (?, ?, ?, ?)";

try {

jdbcTemplate.update(sql,user.getUserName(),user.getLogin

Name(),user.getLastLoginTime(),user.getUserHeadImg());

return "1";

} catch (DataAccessException e) {

e.printStackTrace();

return "0";

}

}

public User findOne(Integer userId){

//查询语句

String sql = "select * from user where user_id = " +

userId;

List<User> userList = jdbcTemplate.query(sql, new

BeanProperty

RowMapper<>(User.class));

return userList.get(0);

}

public String update(User user){

//更新语句

String sql = "update user set user_name = ?,

login_name = ? where

user_id = ?";

try {

jdbcTemplate.update(sql, user.getUserName(),

user.get

LoginName(), user.getUserId());

return "1";

} catch (DataAccessException e) {

return "0";

}

}

public String delete(Integer userId){

//删除语句

String sql = "delete from user where user_id = ?";

try {

jdbcTemplate.update(sql, userId);

return "1";

} catch (DataAccessException e) {

return "0";

}

}

public List<User> findAll(){

//查询多条语句

String sql = "select * from user";

List<User> query = jdbcTemplate.query(sql, new

BeanProperty

RowMapper<>(User.class));

return query;

}

}

(5)定义Service层的类UserService,代码如下:

@Service

public class UserService {

@Autowired

private UserDao userDao;

//添加方法

public String add(User user){

return userDao.add(user);

}

//查询方法

public User findOne(Integer userId){

return userDao.findOne(userId);

}

//更新方法

public String update(User user){

return userDao.update(user);

}

//删除操作

public String delete(Integer userId){

return userDao.delete(userId);

}

//查询列表方法

public List<User> findAll(){

return userDao.findAll();

}

}

(6)定义Controller层的类HiController,代码如下:

@RestController

@RequestMapping("/hi")

public class HiController {

@Autowired

private UserService userService;

//新增用户接口

@PostMapping("/add")

public String add(@RequestBody User user){

return userService.add(user);

}

//查询用户接口

@GetMapping("/findOne")

public User findOne(Integer userId){

return userService.findOne(userId);

}

//更新用户接口

@PostMapping("/update")

public String update(@RequestBody User user){

return userService.update(user);

}

//删除用户接口

@DeleteMapping("/delete")

public String delete(Integer userId){

return userService.delete(userId);

}

//查询多条用户信息接口

@GetMapping("/findAll")

public List<User> findAll(){

return userService.findAll();

}

}

启动服务后,可以使用Postman以POST方式访问
http://localhost:8080/hi/add接口,在请求Body中增加如下信息:

{

"userName":"张三",

"loginName":"zhangsan",

"lastLoginTime":"1599032640",

"userHeadImg":"https://image.xxx.com/xxx.jpg"

}

访问
http://localhost:8080/hi/findAll接口,即可查看刚才插入的用户信息。同样,访问
http://localhost:8080/hi/update接口可以更新用户信息,访问http://localhost:8080/ hi/delete?userId=130接口可以删除用户信息。

Spring Data JPA组件

当开发一个小型项目或者一些工具时可以使用JdbcTemplate模板类,如果开发的是一个大型项目,推荐使用实现了ORM持久化的框架,如Hibernate或MyBatis。本节主要介绍集成了Hibernate的SpringData JPA组件,它基于ORM框架,实现了JPA标准并简化了持久层操作,可以让开发人员用极其简单的方式完成对数据库的访问与操作。

Spring Data JPA同样实现了基本的CRUD方法,如增、删、改、查等。如果有个性化的查询,则需要自定义SQL语句。Spring Data JPA提供了以下几个核心接口:

Repository接口;

CrudRepository接口,继承自Repository;


PagingAndSortingRepository接口,继承自CrudRepository;

JpaRepository接口,继承自
PagingAndSortingRepository。

Spring Data JPA提供了很多注解来声明Entity实体类,如表4.1所示。

下面给出一个Spring Data JPA示例,Spring Boot工程依赖
spring-boot-starter-data-jpa模块。

(1)修改application.yml配置文件,代码如下:

spring:

datasource:

url: jdbc:mysql://localhost:3306/test_db?

useUnicode=true&character

Encoding=UTF8&characterSetResults=UTF8&serverTimezone=UTC

username: root

password: test1111

driver-class-name: com.mysql.cj.jdbc.Driver

jpa:

hibernate:

ddl-auto: update

show-sql: true

database-platform:

org.hibernate.dialect.MySQL5InnoDBDialect

注意:
spring.jpa.hibernate.ddl-auto的update属性用于根据model类自动更新表结构。

(2)声明实体类UserEntity,代码如下:

//定义UserEntity类

@Entity

@Table(name="user")

//表名

@Data

public class UserEntity {

@Id

//声明主键

//主键ID生成策略

@GeneratedValue(strategy = GenerationType.IDENTITY)

@Column(name="user_id") //对应的列

名user_id

private Integer userId;

@Column(name="user_name") //对应的列

名user_name

private String userName;

@Column(name="login_name") //对应的列

名login_name

private String loginName;

@Column(name="last_login_time") //对应的列

名last_login_time

private Integer lastLoginTime;

@Column(name="user_head_img") //对应的列

名user_head_img

private String userHeadImg;

}

(3)声明Dao层的类UserRepository,该类继承自JpaRepository,代码如下:

//继承JpaRepository

@Repository

public interface UserRepository extends

JpaRepository<UserEntity,

Integer> {

}

如果默认情况下无法满足查询需求,可以通过@Query注解来解决这个问题。例如下面的示例:

@Repository

public interface UserRepository extends

JpaRepository<UserEntity,

Integer> {

//自定义查询语句

@Query(value = "select * from user where user_id = ?",

nativeQuery

= true)

UserEntity queryByUserId(Integer userId);

}

如果需要更新,则需要注解@Modifying。

(4)声明Controller层的类,代码如下:

@RestController

@RequestMapping("/hi")

public class HiController {

@Autowired

private UserRepository userRepository; //注入

UserRepository对象

@GetMapping("/jpa/findOne")

public UserEntity jpaFindOne(Integer userId) {

//根据userId查询

Optional<UserEntity> optional =

userRepository.findById(userId);

if (optional.isPresent()) {

return optional.get();

} else {

return null;

}

}

@GetMapping("/jpa/findAll")

public Page<UserEntity> jpaFindAll() {

//分页查询

Pageable pageable = PageRequest.of(1,2,

Sort.by(Sort.Direction.

DESC,"userId"));

userRepository.findAll();

Page<UserEntity> page =

userRepository.findAll(pageable);

return page;

}

@PostMapping("/jpa/add")

public UserEntity jpaAdd(@RequestBody UserEntity

userEntity) {

//新增用户

UserEntity uEntity = userRepository.save(userEntity);

return uEntity;

}

@PostMapping("/jpa/update")

public UserEntity jpaUpdate(@RequestBody UserEntity

userEntity) {

//更新语句

UserEntity uEntity =

userRepository.saveAndFlush(userEntity);

return uEntity;

}

@DeleteMapping("/jpa/delete")

@Transactional

public String jpaDelete(Integer userId){

//根据userId删除信息

userRepository.deleteById(userId);

return "1";

}

@GetMapping("/jpa/query")

public UserEntity jpaQuery(Integer userId) {

//自定义查询语句

UserEntity userEntity =

userRepository.queryByUserId(userId);

return userEntity;

}

}

同样使用Postman进行测试,访问
http://localhost:8080/hi/jpa/findAll、
http://localhost:8080/hi/jpa/update、
http://localhost:8080/hi/jpa/delete?userId=2接口,完成查询、更新和删除等操作。

Spring Boot集成MyBatis

MyBatis同样是一款优秀的持久层框架,支持使用简单的XML文件或注解来配置和映射原生信息,从而将接口和Java的POJO对象映射成数据库中的记录。

Spring Boot也提供了MyBatis的集成模块,即mybatis-springboot-starter。

(1)通过MyBatis提供的mybatis-generator插件工具,可以帮助开发人员自动生成POJO类、Mapper文件和DAO类。具体的generatorConfig.xml配置文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE generatorConfiguration

PUBLIC "-//mybatis.org//DTD MyBatis Generator

Configuration

1.0//EN"

"http://mybatis.org/dtd/mybatis-generator

config_1_0.dtd">

<generatorConfiguration>

<context id="MySQL2Tables" targetRuntime="MyBatis3">

<commentGenerator>

<property name="suppressAllComments" value="true"

/>

<property name="addRemarkComments" value="true"

/>

</commentGenerator>

<!--数据源-->

<jdbcConnection

driverClass="com.mysql.cj.jdbc.Driver"

connectionURL="jdbc:mysql://localhost:3306/

test_db?

useUnicode=true&characterEncoding=UTF8&character

SetResults=UTF8&serverTimezone=UTC"

userId="root"

password="test1111">

</jdbcConnection>

<javaTypeResolver >

<property name="forceBigDecimals" value="false"

/>

</javaTypeResolver>

<javaModelGenerator

targetPackage="com.example.springboot.

model"

targetProject="src/main/java">

<property name="enableSubPackages" value="false"

/>

<property name="trimStrings" value="true" />

</javaModelGenerator>

<sqlMapGenerator

targetPackage="com.example.springboot.mapper"

targetProject="src/main/resources">

<property name="enableSubPackages" value="true"

/>

</sqlMapGenerator>

<javaClientGenerator type="XMLMAPPER"

targetPackage="com.

example.springboot.mapper"

targetProject="src/main/java">

<property name="enableSubPackages" value="true"

/>

</javaClientGenerator>

<table tableName="user">

</table>

</context>

</generatorConfiguration>

执行插件命令:

mvn org.mybatis.generator:mybatis-generator-maven

plugin:1.3.2:

generate

即可生成对应的User类、UserMapper.xml及UserMapper类。

(2)生成Dao层的类UserMapper,代码如下:

//定义UserMapper类

public interface UserMapper {

long countByExample(UserExample example);

int deleteByExample(UserExample example);

int deleteByPrimaryKey(Integer userId);

int insert(User record);

int insertSelective(User record);

List<User> selectByExample(UserExample example);

User selectByPrimaryKey(Integer userId);

int updateByExampleSelective(@Param("record") User

record, @Param

("example") UserExample example);

int updateByExample(@Param("record") User record,

@Param("example")

UserExample example);

int updateByPrimaryKeySelective(User record);

int updateByPrimaryKey(User record);

}

(3)在启动类上添加@MapperScan注解,可以自动注入相关的mapper类。具体代码如下:

//扫描mapper类

@MapperScan("com.example.springboot.mapper")

(4)生成Controller层的类HiController,通过MyBatis的方式获取,代码如下:

@RestController

@RequestMapping("/hi")

public class HiController {

@Resource

private UserMapper userMapper;

@GetMapping("/mybatis/findOne")

public User mybatisFindOne(Integer userId) {

//查询操作

User user = userMapper.selectByPrimaryKey(userId);

return user;

}

}

重新启动应用,在浏览器中访问
http://localhost:8080/hi/mybatis/findOne?userId=1,即可查询对应的信息。

相关推荐

教你把多个视频合并成一个视频的方法

一.情况介绍当你有一个m3u8文件和一个目录,目录中有连续的视频片段,这些片段可以连成一段完整的视频。m3u8文件打开后像这样:m3u8文件,可以理解为播放列表,里面是播放视频片段的顺序。视频片段像这...

零代码编程:用kimichat合并一个文件夹下的多个文件

一个文件夹里面有很多个srt字幕文件,如何借助kimichat来自动批量合并呢?在kimichat对话框中输入提示词:你是一个Python编程专家,完成如下的编程任务:这个文件夹:D:\downloa...

Java APT_java APT 生成代码

JavaAPT(AnnotationProcessingTool)是一种在Java编译阶段处理注解的工具。APT会在编译阶段扫描源代码中的注解,并根据这些注解生成代码、资源文件或其他输出,...

Unit Runtime:一键运行 AI 生成的代码,或许将成为你的复制 + 粘贴神器

在我们构建了UnitMesh架构之后,以及对应的demo之后,便着手于实现UnitMesh架构。于是,我们就继续开始UnitRuntime,以用于直接运行AI生成的代码。PS:...

挣脱臃肿的枷锁:为什么说Vert.x是Java开发者手中的一柄利剑?

如果你是一名Java开发者,那么你的职业生涯几乎无法避开Spring。它如同一位德高望重的老国王,统治着企业级应用开发的大片疆土。SpringBoot的约定大于配置、SpringCloud的微服务...

五年后,谷歌还在全力以赴发展 Kotlin

作者|FredericLardinois译者|Sambodhi策划|Tina自2017年谷歌I/O全球开发者大会上,谷歌首次宣布将Kotlin(JetBrains开发的Ja...

kotlin和java开发哪个好,优缺点对比

Kotlin和Java都是常见的编程语言,它们有各自的优缺点。Kotlin的优点:简洁:Kotlin程序相对于Java程序更简洁,可以减少代码量。安全:Kotlin在类型系统和空值安全...

移动端架构模式全景解析:从MVC到MVVM,如何选择最佳设计方案?

掌握不同架构模式的精髓,是构建可维护、可测试且高效移动应用的关键。在移动应用开发中,选择合适的软件架构模式对项目的可维护性、可测试性和团队协作效率至关重要。随着应用复杂度的增加,一个良好的架构能够帮助...

颜值非常高的XShell替代工具Termora,不一样的使用体验!

Termora是一款面向开发者和运维人员的跨平台SSH终端与文件管理工具,支持Windows、macOS及Linux系统,通过一体化界面简化远程服务器管理流程。其核心定位是解决多平台环境下远程连接、文...

预处理的底层原理和预处理编译运行异常的解决方案

若文章对您有帮助,欢迎关注程序员小迷。助您在编程路上越走越好![Mac-10.7.1LionIntel-based]Q:预处理到底干了什么事情?A:预处理,顾名思义,预先做的处理。源代码中...

为“架构”再建个模:如何用代码描述软件架构?

在架构治理平台ArchGuard中,为了实现对架构的治理,我们需要代码+模型描述所要处理的内容和数据。所以,在ArchGuard中,我们有了代码的模型、依赖的模型、变更的模型等,剩下的两个...

深度解析:Google Gemma 3n —— 移动优先的轻量多模态大模型

2025年6月,Google正式发布了Gemma3n,这是一款能够在2GB内存环境下运行的轻量级多模态大模型。它延续了Gemma家族的开源基因,同时在架构设计上大幅优化,目标是让...

比分网开发技术栈与功能详解_比分网有哪些

一、核心功能模块一个基本的比分网通常包含以下模块:首页/总览实时比分看板:滚动展示所有正在进行的比赛,包含比分、比赛时间、红黄牌等关键信息。热门赛事/焦点战:突出显示重要的、关注度高的比赛。赛事导航...

设计模式之-生成器_一键生成设计

一、【概念定义】——“分步构建复杂对象,隐藏创建细节”生成器模式(BuilderPattern):一种“分步构建型”创建型设计模式,它将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建...

构建第一个 Kotlin Android 应用_kotlin简介

第一步:安装AndroidStudio(推荐IDE)AndroidStudio是官方推荐的Android开发集成开发环境(IDE),内置对Kotlin的完整支持。1.下载And...