创建 Spring Boot 项目并实现连接操作MySQL数据库
-
- 准备
-
- MySQL
- Maven
- `idea`所需插件下载
- `idea`创建项目
-
- 配置 `Server URL`
- 填写项目相关信息
- 创建项目成功(运行并测试)
- `idea`测试能否正常连接`MySQL`
- 创建数据库表
- 添加项目内连接`MySQL`的配置
-
- 搜索连接`MySQL`使用的依赖包
- 编写连接数据库配置文件
- 利用插件`EasyCode`快速创建操作数据库相关代码
-
- 查看创建完成后的项目目录结构
- 解决项目中导入库报错问题
- 最终`pom.xml`
- 访问接口
-
- 请求失败
- 重新运行并请求
- 完整源码
-
- 目录结构
- 引入依赖:`user/pom.xml`
- 服务相关配置:`user/src/main/resources/application.yml`
- 入口:`user/src/main/java/com/example/user/UserApplication.java`
- (User)表控制层:`user/src/main/java/com/example/user/controller/UserController.java`
- (User)表服务接口:`user/src/main/java/com/example/user/service/UserService.java`
- (User)表服务实现类:`user/src/main/java/com/example/user/service/impl/UserServiceImpl.java`
- (User)表数据库访问层:`user/src/main/java/com/example/user/dao/UserDao.java`
- (User)实体类:`user/src/main/java/com/example/user/entity/User.java`
- SQL:`user/src/main/resources/mapper/UserDao.xml`
准备
MySQL
命令
$ docker pull mysql
$ docker run --name local-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql
Maven
相关地址
下载地址:
https://maven.apache.org/
maven配置方法地址:
https://developer.aliyun.com/mvn/guide
仓库搜索地址:
https://mvnrepository.com/
https://repo.maven.apache.org/
maven
本地配置conf/settings.xml
localRepository>${user.home}/Documents/AAA-PLee/maven/repositorylocalRepository>
mirror>
id>aliyunmavenid>
mirrorOf>*mirrorOf>
name>阿里云公共仓库name>
url>https://maven.aliyun.com/repository/publicurl>
mirror>
下载idea
并配置本地环境maven
Maven
构建生命周期
-
Maven
的构建生命周期
包括三个阶段
:clean
、build
和site
-
clean
:清理项目,删除之前的编译结果和构建产生的文件。 -
build
:构建项目,包括编译、测试、打包等操作。 -
site
:生成项目文档和报告,例如测试报告、代码覆盖率报告等。
-
- 每个阶段都包含了一些插件和目标,
Maven
会按照预定义的顺序依次执行。例如,在build
阶段,Maven
会依次执行以下目标:-
validate
:验证项目是否正确。 -
compile
:编译项目源代码。 -
test
:运行项目的测试用例。 -
package
:将项目打包成jar或war文件。 -
verify
:验证打包结果是否正确。 -
install
:将打包结果安装到本地Maven仓库。 -
deploy
:将打包结果部署到远程Maven仓库。
-
idea
所需插件下载
EasyCode
用于快速生成与数据库相关的项目目录和代码
MyBatisPlus
用于
java
与sql.xml
之间的跳转
idea
创建项目
配置 Server URL
地址:https://start.aliyun.com/
填写项目相关信息
创建项目成功(运行并测试)
idea
测试能否正常连接MySQL
创建数据库表
添加项目内连接MySQL
的配置
搜索连接MySQL
使用的依赖包
编写连接数据库配置文件
在pom.xml
中引入MySQL依赖包
(别忘了Load Maven Changes
)
dependency>
groupId>com.mysqlgroupId>
artifactId>mysql-connector-jartifactId>
dependency>
创建并编写application.yml
路径:
user/src/main/resources/application.yml
server:
port: 8000
spring:
application:
name: user-service
datasource:
url: jdbc:mysql://127.0.0.1:3306/java_app
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
利用插件EasyCode
快速创建操作数据库相关代码
查看创建完成后的项目目录结构
Java
应用程序通常使用以下几个组件来组织代码
这些组件之间的关系通常是
Controller
调用Service
,Service
定义impl
文件夹内的业务实现类
,业务实现类
调用DAO
,DAO
操作Mapper
中的SQL语句
,Entity
表示数据库表结构实体类
简单来说,
Controller
用于接收用户请求,Service
实现业务逻辑,DAO
操作数据库,Entity
表示数据库表结构
在
/service/impl/xxx.java
中实现具体业务逻辑在
/resources/mapper/xxx.xml
中添加操作数据的sql
语句
-
Controller
:控制器,用于接收用户请求并调用相应的处理方法来处理请求,然后返回响应结果。通常使用Spring MVC
框架来实现。 -
Service
:服务层,用于实现业务逻辑,调用DAO
进行数据操作。通常包含接口和实现类。 -
DAO
:数据访问对象,用于操作数据库。通常使用MyBatis
、Hibernate
等框架来实现。 -
Entity
:实体类,用于表示数据库中的表结构。通常包含类属性和对应的getter/setter
方法。
解决项目中导入库报错问题
利用 https://mvnrepository.com/
搜索解决
dependencies>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-webartifactId>
dependency>
dependency>
groupId>com.mysqlgroupId>
artifactId>mysql-connector-jartifactId>
dependency>
dependency>
groupId>org.springframework.datagroupId>
artifactId>spring-data-commonsartifactId>
version>3.1.0version>
dependency>
dependency>
groupId>org.mybatisgroupId>
artifactId>mybatisartifactId>
version>3.5.6version>
dependency>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-testartifactId>
scope>testscope>
dependency>
dependencies>
尝试运行(报错:没有引入对应版本)
dependency>
groupId>org.springframework.datagroupId>
artifactId>spring-data-commonsartifactId>
dependency>
尝试运行(缺少 @MapperScan
注解)
注意:
尽量选择使用量大的依赖包
dependency>
groupId>org.mybatis.spring.bootgroupId>
artifactId>mybatis-spring-boot-starterartifactId>
version>2.2.2version>
dependency>
// user/src/main/java/com/example/user/UserApplication.java
package com.example.user;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
@MapperScan(basePackages = "com.example.user.dao")
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
- @SpringBootApplication注解是一个组合注解,它的作用是标记一个Spring
Boot应用程序的主类。它包括三个注解:@Configuration
,@EnableAutoConfiguration
和@ComponentScan
- @Configuration:将该类标记为Spring应用程序上下文中的一个bean定义的源。即在该类中定义的bean可以被Spring容器管理。
- @EnableAutoConfiguration:自动配置Spring Boot应用程序所需的Bean。
- @ComponentScan:扫描应用程序中的其他组件,例如控制器、服务和存储库。
- @MapperScan是MyBatis框架中的一个注解,它的作用是扫描指定的包路径,找到所有标记了@Mapper注解的接口,并将这些接口创建成MyBatis的Mapper接口实现类
- 可以在需要使用Mapper的地方自动注入这些Mapper实现类的实例,从而方便地访问数据库。
尝试运行(运行成功,若运行后立即结束,有可能为未引入spring-boot-starter-web
包)
尝试引入即可
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-webartifactId>
dependency>
最终pom.xml
dependencies>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-webartifactId>
dependency>
dependency>
groupId>com.mysqlgroupId>
artifactId>mysql-connector-jartifactId>
dependency>
dependency>
groupId>org.springframework.datagroupId>
artifactId>spring-data-commonsartifactId>
dependency>
dependency>
groupId>org.mybatisgroupId>
artifactId>mybatisartifactId>
version>3.5.6version>
dependency>
dependency>
groupId>org.mybatis.spring.bootgroupId>
artifactId>mybatis-spring-boot-starterartifactId>
version>2.2.2version>
dependency>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-testartifactId>
scope>testscope>
dependency>
dependencies>
访问接口
请求失败
解决报错(告诉MyBatis
去哪里找SQL
语句)
mybatis:
mapper-locations: classpath:**/mapper/*.xml
重新运行并请求
完整源码
目录结构
引入依赖:user/pom.xml
project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
modelVersion>4.0.0modelVersion>
groupId>com.examplegroupId>
artifactId>userartifactId>
version>0.0.1-SNAPSHOTversion>
name>username>
description>userdescription>
properties>
java.version>1.8java.version>
project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
spring-boot.version>2.6.13spring-boot.version>
properties>
dependencies>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-webartifactId>
dependency>
dependency>
groupId>com.mysqlgroupId>
artifactId>mysql-connector-jartifactId>
dependency>
dependency>
groupId>org.springframework.datagroupId>
artifactId>spring-data-commonsartifactId>
dependency>
dependency>
groupId>org.mybatisgroupId>
artifactId>mybatisartifactId>
version>3.5.6version>
dependency>
dependency>
groupId>org.mybatis.spring.bootgroupId>
artifactId>mybatis-spring-boot-starterartifactId>
version>2.2.2version>
dependency>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-testartifactId>
scope>testscope>
dependency>
dependencies>
dependencyManagement>
dependencies>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-dependenciesartifactId>
version>${spring-boot.version}version>
type>pomtype>
scope>importscope>
dependency>
dependencies>
dependencyManagement>
build>
plugins>
plugin>
groupId>org.apache.maven.pluginsgroupId>
artifactId>maven-compiler-pluginartifactId>
version>3.8.1version>
configuration>
source>1.8source>
target>1.8target>
encoding>UTF-8encoding>
configuration>
plugin>
plugin>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-maven-pluginartifactId>
version>${spring-boot.version}version>
configuration>
mainClass>com.example.user.UserApplicationmainClass>
skip>trueskip>
configuration>
executions>
execution>
id>repackageid>
goals>
goal>repackagegoal>
goals>
execution>
executions>
plugin>
plugins>
build>
project>
服务相关配置:user/src/main/resources/application.yml
server:
port: 8000
spring:
application:
name: user-service
datasource:
url: jdbc:mysql://127.0.0.1:3306/java_app
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:**/mapper/*.xml
入口:user/src/main/java/com/example/user/UserApplication.java
package com.example.user;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
@MapperScan(basePackages = "com.example.user.dao")
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
(User)表控制层:user/src/main/java/com/example/user/controller/UserController.java
package com.example.user.controller;
import com.example.user.entity.User;
import com.example.user.service.UserService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* (User)表控制层
*
* @author makejava
* @since 2023-06-12 14:13:44
*/
@RestController
@RequestMapping("user")
public class UserController {
/**
* 服务对象
*/
@Resource
private UserService userService;
/**
* 分页查询
*
* @param user 筛选条件
* @param pageRequest 分页对象
* @return 查询结果
*/
@GetMapping
public ResponseEntityPageUser>> queryByPage(User user, PageRequest pageRequest) {
return ResponseEntity.ok(this.userService.queryByPage(user, pageRequest));
}
/**
* 通过主键查询单条数据
*
* @param id 主键
* @return 单条数据
*/
@GetMapping("{id}")
public ResponseEntityUser> queryById(@PathVariable("id") String id) {
return ResponseEntity.ok(this.userService.queryById(id));
}
/**
* 新增数据
*
* @param user 实体
* @return 新增结果
*/
@PostMapping
public ResponseEntityUser> add(User user) {
return ResponseEntity.ok(this.userService.insert(user));
}
/**
* 编辑数据
*
* @param user 实体
* @return 编辑结果
*/
@PutMapping
public ResponseEntityUser> edit(User user) {
return ResponseEntity.ok(this.userService.update(user));
}
/**
* 删除数据
*
* @param id 主键
* @return 删除是否成功
*/
@DeleteMapping
public ResponseEntityBoolean> deleteById(String id) {
return ResponseEntity.ok(this.userService.deleteById(id));
}
}
(User)表服务接口:user/src/main/java/com/example/user/service/UserService.java
package com.example.user.service;
import com.example.user.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
/**
* (User)表服务接口
*
* @author makejava
* @since 2023-06-12 14:13:49
*/
public interface UserService {
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
User queryById(String id);
/**
* 分页查询
*
* @param user 筛选条件
* @param pageRequest 分页对象
* @return 查询结果
*/
PageUser> queryByPage(User user, PageRequest pageRequest);
/**
* 新增数据
*
* @param user 实例对象
* @return 实例对象
*/
User insert(User user);
/**
* 修改数据
*
* @param user 实例对象
* @return 实例对象
*/
User update(User user);
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
boolean deleteById(String id);
}
(User)表服务实现类:user/src/main/java/com/example/user/service/impl/UserServiceImpl.java
package com.example.user.service.impl;
import com.example.user.entity.User;
import com.example.user.dao.UserDao;
import com.example.user.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import javax.annotation.Resource;
/**
* (User)表服务实现类
*
* @author makejava
* @since 2023-06-12 14:13:50
*/
@Service("userService")
public class UserServiceImpl implements UserService {
@Resource
private UserDao userDao;
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
@Override
public User queryById(String id) {
return this.userDao.queryById(id);
}
/**
* 分页查询
*
* @param user 筛选条件
* @param pageRequest 分页对象
* @return 查询结果
*/
@Override
public PageUser> queryByPage(User user, PageRequest pageRequest) {
long total = this.userDao.count(user);
return new PageImpl>(this.userDao.queryAllByLimit(user, pageRequest), pageRequest, total);
}
/**
* 新增数据
*
* @param user 实例对象
* @return 实例对象
*/
@Override
public User insert(User user) {
this.userDao.insert(user);
return user;
}
/**
* 修改数据
*
* @param user 实例对象
* @return 实例对象
*/
@Override
public User update(User user) {
this.userDao.update(user);
return this.queryById(user.getId());
}
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
@Override
public boolean deleteById(String id) {
return this.userDao.deleteById(id) > 0;
}
}
(User)表数据库访问层:user/src/main/java/com/example/user/dao/UserDao.java
package com.example.user.dao;
import com.example.user.entity.User;
import org.apache.ibatis.annotations.Param;
import org.springframework.data.domain.Pageable;
import java.util.List;
/**
* (User)表数据库访问层
*
* @author makejava
* @since 2023-06-12 14:13:45
*/
public interface UserDao {
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
User queryById(String id);
/**
* 查询指定行数据
*
* @param user 查询条件
* @param pageable 分页对象
* @return 对象列表
*/
ListUser> queryAllByLimit(User user, @Param("pageable") Pageable pageable);
/**
* 统计总行数
*
* @param user 查询条件
* @return 总行数
*/
long count(User user);
/**
* 新增数据
*
* @param user 实例对象
* @return 影响行数
*/
int insert(User user);
/**
* 批量新增数据(MyBatis原生foreach方法)
*
* @param entities List 实例对象列表
* @return 影响行数
*/
int insertBatch(@Param("entities") ListUser> entities);
/**
* 批量新增或按主键更新数据(MyBatis原生foreach方法)
*
* @param entities List 实例对象列表
* @return 影响行数
* @throws org.springframework.jdbc.BadSqlGrammarException 入参是空List的时候会抛SQL语句错误的异常,请自行校验入参
*/
int insertOrUpdateBatch(@Param("entities") ListUser> entities);
/**
* 修改数据
*
* @param user 实例对象
* @return 影响行数
*/
int update(User user);
/**
* 通过主键删除数据
*
* @param id 主键
* @return 影响行数
*/
int deleteById(String id);
}
(User)实体类:user/src/main/java/com/example/user/entity/User.java
package com.example.user.entity;
import java.io.Serializable;
/**
* (User)实体类
*
* @author makejava
* @since 2023-06-12 14:13:46
*/
public class User implements Serializable {
private static final long serialVersionUID = 264722085318530649L;
private String id;
private String name;
private Integer age;
private String sex;
private String phone;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
SQL:user/src/main/resources/mapper/UserDao.xml
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
mapper namespace="com.example.user.dao.UserDao">
resultMap type="com.example.user.entity.User" id="UserMap">
result property="id" column="id" jdbcType="VARCHAR"/>
result property="name" column="name" jdbcType="VARCHAR"/>
result property="age" column="age" jdbcType="INTEGER"/>
result property="sex" column="sex" jdbcType="VARCHAR"/>
result property="phone" column="phone" jdbcType="VARCHAR"/>
resultMap>
select id="queryById" resultMap="UserMap">
select
id, name, age, sex, phone
from user
where id = #{id}
select>
select id="queryAllByLimit" resultMap="UserMap">
select
id, name, age, sex, phone
from user
where>
if test="id != null and id != ''">
and id = #{id}
if>
if test="name != null and name != ''">
and name = #{name}
if>
if test="age != null">
and age = #{age}
if>
if test="sex != null and sex != ''">
and sex = #{sex}
if>
if test="phone != null and phone != ''">
and phone = #{phone}
if>
where>
limit #{pageable.offset}, #{pageable.pageSize}
select>
select id="count" resultType="java.lang.Long">
select count(1)
from user
where>
if test="id != null and id != ''">
and id = #{id}
if>
if test="name != null and name != ''">
and name = #{name}
if>
if test="age != null">
and age = #{age}
if>
if test="sex != null and sex != ''">
and sex = #{sex}
if>
if test="phone != null and phone != ''">
and phone = #{phone}
if>
where>
select>
insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into user(name, age, sex, phone)
values (#{name}, #{age}, #{sex}, #{phone})
insert>
insert id="insertBatch" keyProperty="id" useGeneratedKeys="true">
insert into user(name, age, sex, phone)
values
foreach collection="entities" item="entity" separator=",">
(#{entity.name}, #{entity.age}, #{entity.sex}, #{entity.phone})
foreach>
insert>
insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true">
insert into user(name, age, sex, phone)
values
foreach collection="entities" item="entity" separator=",">
(#{entity.name}, #{entity.age}, #{entity.sex}, #{entity.phone})
foreach>
on duplicate key update
name = values(name),
age = values(age),
sex = values(sex),
phone = values(phone)
insert>
update id="update">
update user
set>
if test="name != null and name != ''">
name = #{name},
if>
if test="age != null">
age = #{age},
if>
if test="sex != null and sex != ''">
sex = #{sex},
if>
if test="phone != null and phone != ''">
phone = #{phone},
if>
set>
where id = #{id}
update>
delete id="deleteById">
delete from user where id = #{id}
delete>
mapper>