SpringBoot学习指南,超级全,真的细!挑战全篇无图教会你Java Springboot的使用。
考虑到大家学习的时间都比较碎片前面的9万字的文档确实阅读时间相对比较苛刻,故此将文档做一个分割,如果时间比较充足的小伙伴,建议还是直接阅读长篇这样学习会比较连贯
juejin.cn/post/730931...
SpringBoot整合Spring Data JPA(本章有兴趣可以看看,没兴趣可以略过)
介绍≈废话(你忍一下虽然文件有点大)
Spring Data JPA(Java Persistence API)是Spring Framework的一个子项目,用于简化数据持久化(数据库操作)的开发。它提供了一种更高级别的抽象,使开发者可以更容易地与关系数据库进行交互。Spring Data JPA通过使用注解和接口来定义数据模型和存储库,并自动生成与JPA(Java Persistence API)兼容的数据访问代码。
以下是Spring Data JPA的主要特点和用法:
- 简化数据持久化:Spring Data JPA简化了与数据库的交互,减少了手动编写JPA查询和数据访问代码的工作量。
- 自动化查询方法:Spring Data JPA根据方法命名规则自动生成查询,你只需要定义接口方法,而不需要实现查询逻辑。
- 支持JPA标准:Spring Data JPA与标准JPA兼容,支持JPA注解、Entity管理、持久化上下文等。
- 声明式事务管理:Spring Data JPA可以与Spring的事务管理机制集成,简化了事务处理。
- Repository接口 :Spring Data JPA的核心是Repository接口,你可以创建自定义的Repository接口,并继承
CrudRepository
或JpaRepository
来获得基本的CRUD操作。 - 自定义查询方法:你可以在Repository接口中声明自定义的查询方法,Spring Data JPA会根据方法名自动生成查询语句。
- 动态查询:Spring Data JPA支持构建动态查询,可以根据运行时条件来生成查询语句。
- 分页和排序:Spring Data JPA提供了分页和排序的支持,使得容易实现分页查询。
- 支持不同的数据库:Spring Data JPA支持多种关系数据库,包括MySQL、PostgreSQL、Oracle等。
- 集成Spring Boot:Spring Data JPA与Spring Boot集成良好,可以轻松配置和使用。
示例使用Spring Data JPA的典型步骤包括:
- 定义实体类,使用JPA注解来映射数据库表。
- 创建一个继承
JpaRepository
或CrudRepository
的Repository接口,定义数据操作方法。 - Spring Data JPA会根据方法名自动生成查询语句。
- 在Spring Boot应用程序中配置数据源和启用Spring Data JPA。
- 使用Repository接口的方法进行数据库操作。
Spring Data JPA是Spring生态系统中的一个有力工具,用于简化数据持久化的开发工作。它降低了开发者与数据库交互的复杂性,提高了开发效率。
好的,开始进入
正题。
1.我们新建Maven项项目
com.practice.springboot_jpa
xml
<groupId>com.practice</groupId>
<artifactId>springboot_jpa</artifactId>
<version>1.0-SNAPSHOT</version>
2.POM文件依赖
xml
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.practice</groupId>
<artifactId>springboot_jpa</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<!-- 所有的Spring boot项目都要继承这个父工程,父工程对所有的jar包进行管理-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.8</version>
</parent>
<dependencies>
<!-- Spring Web启动器 -->
<!--
框架提供了很多的启动器(起步依赖),其实就是一组jar包的名称。
web启动器:引入web开发相关的jar
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Lombok的主要作用是通过简化常见的Java代码模式,减少样板代码的编写,提高开发效率,
减少代码错误,增加代码的可读性和可维护性。它已经成为许多Java开发人员的常用工具之一,
并在许多开源项目和企业应用中广泛使用。-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version> <!-- 请检查并使用最新的版本 -->
<scope>provided</scope>
</dependency>
<!--
@ConfigurationProperties(prefix = "spring.jdbc.datasource")
需要配置spring-boot-configuration-processor依赖,用于生成metadata,否则会警告。
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!--使用自定义启动器,数据源启动器-->
<dependency>
<groupId>com.practice</groupId>
<artifactId>spring-boot-jdbc-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- 单元测试启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- springboot JPA的初始依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MySQL 连接驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>RELEASE</version>
</dependency>
<!-- Redis启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
</project>
3.新增application.yml配置文件
src/main/resources/application.yml
yml
logging:
level:
com.practice.dao: debug #Dao日志等级配置
spring:
datasource:
password:
username: root
#数据库连接地址和名称以及编码配置 时区配置
url: jdbc:mysql://127.0.0.1:3306/java?usenUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver #jdk8默认驱动
jpa:
database: mysql #持久化方案采用mysql
show-sql: true #控制台展示sql语句
generate-ddl: true #生成ddl语句打印在控制台中
hibernate:
ddl-auto: update #表不存在自动创建,表与类一致则不修改,类与表不一致则更新表结构
naming: #类使用驼峰命名方式表里可能是有下划线的
physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
server:
port: 9090 #端口号
4.新增dao包
src/main/java/com/practice/dao
(存放数据库交互操作)
5.新增pojo包
src/main/java/com/practice/pojo
(存放实体类当然有项目中有人起名叫daomian或entity或其他包名但是意在存放实体类)
5.1.新建User.java
src/main/java/com/practice/pojo/User.java
(User实体类)
java
package com.practice.pojo;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.io.Serializable;
/**
* Author :吴佳浩(Alben)
*
* effect:
*
* use the jap to do the O-R Mapping reflect
* purpose:可以进行正向的开发,通过实体类映射,可以动态创建表结构。生成DDL语句(Data Definition Language)
*
* explain this class:
*
* lombok Auto generate the Get and Set function
* Serializable继承json序列化的方法
* @Entity //声明这是一个实体类
* @Table(name = "jpa_user") //推荐使用jpa提供的注解(javax.persistence.*)声明表 User类和jpa_user做映射
* @Id //声明主键
* @GeneratedValue(strategy = GenerationType.IDENTITY) //是用于Java持久性编程中的注解,通常与JPA(Java Persistence API)一起使用,用于指定如何生成数据库表中的主键值。等与mysql中的auto_increment;
*
* @GeneratedValue(strategy = GenerationType.IDENTITY) 是用于Java持久性编程中的注解,通常与JPA(Java Persistence API)一起使用,用于指定如何生成数据库表中的主键值。
*
* @GeneratedValue 是一个注解,它用于指示主键生成策略。
*
* strategy = GenerationType.IDENTITY 是注解中的一个参数,它指定了主键生成策略。在这种情况下,GenerationType.IDENTITY 表示使用数据库的自增(或自动增加)功能来生成主键值。
*
* 在许多数据库管理系统中,可以配置表的主键列,使其在插入新记录时自动增加。这意味着每次插入新记录时,主键列的值都会自动增加,不需要手动指定主键值。GenerationType.IDENTITY 就是告诉JPA使用数据库的这种自动增加功能来生成主键值。
*
* 举例来说,如果你有一个实体类,其中的某个字段被注解为主键,并且使用了 @GeneratedValue(strategy = GenerationType.IDENTITY),当你将该实体保存到数据库时,主键字段的值将由数据库自动分配,而不需要在代码中明确指定。这对于自动管理主键值以及避免主键冲突非常有用。
*
* 需要注意的是,GenerationType.IDENTITY 主要适用于支持自增主键的数据库,如MySQL,但并不适用于所有数据库。在某些数据库中,可能需要使用不同的主键生成策略。
*
* @Column(name = "id",length = 11,unique = true,nullable = false)//@Column(name = "id", length = 11, unique = true, nullable = false):
*
* 这是一个注解,用于指定与数据库表中的列(column)相关的信息。下面是各个参数的解释:name = "id":指定数据库列的名称为 "id"。这表示在数据库表中将有一个名为 "id" 的列与这个属性进行映射。length = 11:指定了数据库列的长度为 11。
*
* 这表示 "id" 列将容纳最大长度为 11 的数据。unique = true:指定 "id" 列的数值必须是唯一的,不允许有重复的值。如果设置为 true,则该列的值在整个表中必须唯一。nullable = false:指定 "id" 列不允许包含空(null)值。
*
* 这意味着在插入数据时,必须为 "id" 列提供一个非空的值。
*
*/
@Getter
@Setter
@Entity
@Table(name = "jpa_user")
public class User implements Serializable {
@Id //声明主键
@GeneratedValue(strategy = GenerationType.IDENTITY) //是用于Java持久性编程中的注解,通常与JPA(Java Persistence API)一起使用,用于指定如何生成数据库表中的主键值。等与mysql中的auto_increment;
@Column(name = "id",length = 11,unique = true,nullable = false)
private Long id;
@Column( name = "username",length = 16)
private String username;
@Column( name = "password",length = 16)
private String password;
@Transient //临时字段,无需映射,不生成表字段
private String age;
// if you didn't set the column the Framework will Auto reflect the type and name.it's like @Column(name ="name",Length =8)
private String name;
}
写到这里我们来看一下当前关于jpa部分的项目结构
Linux
├── pom.xml
├── springboot_jpa.iml
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── practice
│ │ │ ├── dao
│ │ │ └── pojo
│ │ │ ├── User.java
│ │ │ └── pojo.md
│ │ └── resources
│ │ └── application.yml
│ └── test
│ └── java
└── target
.......
└──
6.新增UserDao.java
src/main/java/com/practice/dao/UserDao.java
(UserData---- Access Object,DAO)
仅需简单的继承即可获取大部分的CRUD的方法
java
package com.practice.dao;
import com.practice.pojo.User;
import org.springframework.data.jpa.repository.JpaRepository;
//仅需要继承父接口,JpaRepository<T, ID>父接口中已经提供了CRUD操作,自己无需声明这些方法。
public interface UserDao extends JpaRepository<User,Long> {
}
7.新增service包
src/main/java/com/practice/service
7.1定义UserService.java
src/main/java/com/practice/service/UserService.java
java
package com.practice.service;
import com.practice.pojo.User;
import java.util.List;
/**
* 用户服务接口,定义了对用户信息的基本操作。
*/
@Service
public interface UserService {
/**
* 获取所有用户信息。
*
* @return 包含所有用户信息的列表
*/
List<User> findUser();
/**
* 根据用户ID查找特定用户。
*
* @param id 用户ID
* @return 包含用户信息的User对象,如果未找到则返回null
*/
User findUserById(long id);
/**
* 保存新用户信息。
*
* @param user 包含新用户信息的User对象
*/
void saveUser(User user);
/**
* 更新现有用户信息。
*
* @param user 包含更新后用户信息的User对象
*/
void updateUser(User user);
/**
* 根据用户ID删除特定用户。
*
* @param id 要删除的用户ID
*/
void deleteUerById(Long id);
}
7.2创建impl目录用来存放server当中的接口实现
src/main/java/com/practice/service/impl
7.3创建UserServiceiml.java (实现UserService的接口)
java
package com.practice.service.impl;
import com.practice.dao.UserDao;
import com.practice.pojo.User;
import com.practice.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
public class UserServiceimpl implements UserService {
@Autowired
UserDao userDao;
@Override
public List<User> findUser() {
return userDao.findAll();
}
/**
* explain :
* 返回类型不同:
* * getReferenceById(id)返回的是一个可选的实体对象,该对象可以直接用来进行后续的操作,例如调用其方法或访问其字段等。
* * findById(id).get()返回的是一个实体对象,但该对象有可能为null,因此在使用前必须先检查其是否为null。
* 数据库查询方式不同:
* * getReferenceById(id)并不会立即执行数据库查询,而是在首次访问返回的对象时才去执行查询。
* 这种方式可以提高性能,因为它减少了不必要的数据库查询。
* * findById(id).get()则会立即执行数据库查询,并返回查询结果。如果查询结果不存在,则返回null。
* 综上所述,在选择使用哪种方法时,应根据具体的需求来进行选择。
* 如果你需要立即得到查询结果,并且不关心性能问题,那么可以使用findById(id).get();
* 如果你希望减少不必要的数据库查询,提高性能,那么可以使用getReferenceById(id)。
* @param id 用户ID
* @return User
*/
@Override
public User findUserById(long id) {
return userDao.getReferenceById(id);
}
@Override
public void saveUser(User user) {
//user对象主键值为null,进行保存操作
userDao.save(user);
}
@Override
public void updateUser(User user) {
//user对象含有主键值,进行更新操作
userDao.save(user);//一个方法两用
}
@Override
public void deleteUerById(Long id) {
userDao.deleteById(id);
}
}
8.声明controller包
src/main/java/com/practice/controller
(存放业务接口)
8.1声明UserController.java
src/main/java/com/practice/controller/UserController.java
java
package com.practice.controller;
import com.practice.pojo.User;
import com.practice.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController //组合两个注解 @Controller + @ResponseBody
@RequestMapping("/user") //the path group name
public class UserController {
@Autowired
UserService userServiceImpl;
@RequestMapping("/finAllUser")
public List<User> finAll(){
List<User> users =userServiceImpl.findUser();
return users;
}
}
9.声明程序主入口
src/main/java/com/practice/App.java
(程序主入口)
java
package com.practice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication//申明当前是一个springboot项目
public class App {
public static void main(String arg[]){
SpringApplication.run(App.class,arg);
}
}
当然这里简单的查询和分段式查询由业务层去组装数据是可以使用我们的JPA,复杂的多表查询等不建议使用。