JPA是Java官方定义的一套与数据库交互的接口标准。Spring Data JPA 实现了它,并且整合了多种数据库,使得与数据库的交互变得简单。
使用Spring Data JPA的逻辑:
在springApplication设置里设置数据源(datasource);
编写一个实体类,其中的属性对应数据库表单的列;
为这个实体类添加注解,使其能够与数据表衔接;
定义Dao(Repository),使用它来与数据库进行交互。
一、导入包
首先用maven导入包:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
这里导入lombok,用于生成构造方法;导入mysql-connector,用于连接mysql数据库,与mysql交互这个是必须的。
二、创建数据库
在外部(cmd)登录mysql并使用SQL语句创建数据库jpatest
,新建一个表users
用来储存用户数据。
mysql> create table users (
-> id int,
-> name char(30),
-> password char(30),
-> userInfoId int);
然后用ALTER指令设置id为主键,并设置其为自增。
创建完成后可以用IDEA自带的database工具登录数据库并查看:
这里注意,IDEA的database窗口只是用于预览数据库和数据表,并不能让项目连上数据库。还需要手动设置datasource。
三、配置数据源
在Spring设置(application.properties
,一般在resources
目录下,也有一种写为yml形式)中添加如下语句以添加数据源:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/jpatest?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=password
这样就指定了一个数据源,其驱动为mysql驱动,数据库的url为mysql://localhost:3306/jpatest
,也就是jpatest
数据库。然后我们指定了用户名和密码。
四、创建实体类
对应我们的需求和数据库的各列,我们新建下面的User类:
import lombok.*;
import javax.persistence.*;
@Data
@RequiredArgsConstructor
@NoArgsConstructor
@Entity
@Table(name="users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@NonNull
private String name;
@NonNull
private String password;
@NonNull
@Column(name="userinfoid")
private int userInfoId;
}
下面对类上的注解进行说明。这些注解都是由javax.persistence
定义的。
@Data、@RequiredArgsConstructor 和@NoArgsConstructor
都是lambok提供的。@Data
提供getter和setter,@NoArgsConstructor
提供@Entity
要求的无参构造方法,而@RequiredArgsConstructor
则提供仅包含必须的几个属性(这里是除了id以外的属性,因为id我们希望它自动生成)的构造方法。
@RequiredArgsConstructor
只会识别带有lombok的@NonNull
注解或final
修饰符的属性。所以在相关属性上加上@NonNull
。
p.s. 好像很多人用
@RequiredArgsConstructor
不需要使用@NonNull,但我本地没办法不用@NonNull实现。
@Entity、@Id 和 @Table
@Entity
注解会将这个类表示为准备映射数据库的实体类,必须结合@Id注解使用。
@Id
所标注的属性会被识别为主键。一个表必须有主键,所以必须存在这个注解。
@GeneratedValue
用于给主键指定生成策略,一般用GenerationType.IDENTITY
来指定主键为自增。这里的注解设置必须和数据库一致,否则会出错。
@Table
用于标识需要对应的数据表名。如@Table(name="users")
表示对应的是数据源下的users
这个表。
@Column
这个注解用于属性上,可写可不写,用于指定这个属性所对应的列的名字。如果不写,那么指定的列默认是和这个属性名字相同的列。注意大小写是敏感的,要和数据库严格一致。
五、创建UserRespository
这就是所谓的Dao层,由Spring提供具体实现。我们在这里需要定义一个接口UserRespository
,继承Spring提供的接口JpaRepository< >
以使用Spring提供的方法。
@Repository
public interface UserRepository extends JpaRepository<User,Integer> {
}
说明:
JpaRepository< >
需要提供实体类和ID(主键)的类;- 为了之后让Spring托管这个类,加上
@Repository
注解使之被定义为一个bean; - 只要留空这个接口就可以使用了。
在留空这个接口的情况下,就可以执行save
,saveall
,delete
,find
等等的CRUD(增删查改)操作了。但是由于JpaRepository
实现的时候不知道你的类有哪些属性,所以要进行一些具体的操作,比如findByPassword
(根据密码查找用户),就必须要在这个接口下自定义一些方法来完成。
Spring Data的一个强大的功能在于,你只需要在接口定义这个方法,而不需要实际写代码来实现它,Spring框架会自动理解你的方法的目的,并自动帮你实现想要的操作。
例如,上面提到的findByPassword
可以直接用这样的方式实现:
UserRepository:
@Repository
public interface UserRepository extends JpaRepository<User,Integer> {
public User getByPassword(String passwd);
}
test():
user = userRepository.getByPassword("123");
虽然我们没有编写任何实现相关代码,但Spring仍通过解析方法名的意义帮你完成了你想要的操作。
除了匹配具体的数值,方法名的解析还支持值区间、包含、前缀等等非常丰富的匹配方法。这些方法在书写时IDEA都会提供补全的提示,非常方便。
当然,有时候我们还是会想用sql的方式进行操作,也可以使用@Query
注解实现。
例子:
@Query(value = "select u from User u where u.password='123'")
public User getByPassword2();
这个语法和原生的sql有所不同,需要单独查阅。