Springboot下通过Jpa连接MySQL数据库实现ORM对象关系映射
1.1 依赖的搭建
要在Springboot中使用Jpa首先要引入项目依赖,这里以Maven为例:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
1.2 配置数据源
等到Maven Sync完成后,我们需要在application.properties文件中配置数据源。
# 注释: 在jdbc的url中,需要注意:
# 编码设置为utf-8
# 时区需要手动指定,否则在使用系统自动管理的Timestamp时会出现时间与北京时间相差11小时左右
spring.datasource.url=jdbc:mysql://数据库IP:端口/数据库名称?charset=utf8mb4&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.username=你的用户名
spring.datasource.password=你的密码
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 在Springboot版本>=2.0,请根据需要将数据库引擎切换为InnoDB
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
# 是否在控制台输出sql语句
spring.jpa.show-sql=true
# 自动生成ddl语句
# 这里需要解释一下常用参数:
# create: 每次加载Hibernate时删除数据库中所有的数据和表,再重新创建新的(慎用!)
# update: 当表不存在时自动创建数据表,当表存在时自动根据model更新表的结构,表中的数据保持不变。(常用)
# (注意:当model中的字段被删除时,update模式是不会删除字段的)
# validate: 每次加载Hibernate时比对表的结构,根据model自动做出修改,!但是新的表不会被创建!
spring.jpa.hibernate.ddl-auto=update
1.3 开始使用
1.3.1 数据实体类的创建
首先,需要创建数据实体类。这里以User表的实体类为例: (UsersDO.java)
package com.yeliheng.test.domain;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "users")
public class UsersDO {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column
private String nickname;
@Column
private String phone;
@Column
private String password;
@CreationTimestamp
private LocalDateTime createDateTime;
@UpdateTimestamp
private LocalDateTime updateDateTime;
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public LocalDateTime getCreateDateTime() {
return createDateTime;
}
public void setCreateDateTime(LocalDateTime createDateTime) {
this.createDateTime = createDateTime;
}
public LocalDateTime getUpdateDateTime() {
return updateDateTime;
}
public void setUpdateDateTime(LocalDateTime updateDateTime) {
this.updateDateTime = updateDateTime;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
这里对以上代码的关键点进行解释:
@Entity 注解:用于数据库的实体类均需要加上Entity注解
@Table 注解:顾名思义,这是一个表注解,可在name属性中赋值需要的表名。默认表名与类名相同
@Id : 表示主键ID,如果想让id自增则需要再加上@GeneratedValue(strategy = GenerationType.IDENTITY)注解
@Column 注解:表示这是一个字段
这里,我们希望将数据的创建时间与更新时间交给框架来管理,则我们需要加上@CreationTimestamp和@UpdateTimestamp注解。并将数据类型定义为LocalDateTime。
这样有什么好处?首先,我们无需在数据更新时自行去实现时间更新的逻辑,用户的注册时间以及更改时间完全交付给系统管理,提供很大的便利。其次,我们无需自行格式化时间戳,因为Jpa的时间戳与MySQL的时间戳有格式上的不同,在格式化的过程中,极其容易踩坑。
1.3.2 开始与数据库进行交互(Dao层的创建)
首先解释一下什么叫DAO层
DAO即Data Access Object,能够实现对数据持久化的访问。不止是数据库,持久化的数据例如文件的操作,都可在DAO层进行。也算是一种规范。简单地说,DAO层**用于隔离业务逻辑代码和数据访问代码,隔离不同数据的实现。
Jpa已经帮忙封装完Dao层的相关代码,所以,我们实现增删改查十分容易。只需要定义一个接口,这个接口继承自org.springframework.data.repository.Repository<T, ID> 接口,一句话即可完成初始化。T表示数据的实体类,例如我们的UsersDO类,ID表示实体类的主键类型。最后,别忘了加上@Respository这个注解,这个注解用于表示存储层Bean。代码如下:
package com.yeliheng.test.dao;
import com.yeliheng.test.domain.UsersDO;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UsersDao extends JpaRepository<UsersDO,Long> {
Boolean existsByPhone(String phone);
UsersDO findByPhone(String phone);
}
我们在定义完接口后,在接口中实现了两个方法:顾名思义,一个是通过手机号判断用户是否存在,一个是通过手机号查找用户。
就这么简单,Jpa就可以实现查询功能。
稍微提一下方法名称:
findByXXX:XXX表示你要查什么字段。你甚至可以findByXXXAndXXXAndXXXAndXXX......多少字段都没问题,中间用And进行连接。超级方便。
exists同理。
这里仅仅列举了两种操作,Jpa的接口功能十分强大, 可自行定制使用其他功能,例如排序、分页、多表联查等等等等...用户自行查表获取。
1.3.3 在service里调用
增
通俗易懂,直接上代码。
@Autowired
private UsersDao usersDao;
public void addUser(){
UsersDO usersDO = new UsersDO();
usersDO.setPhone("11111111111");
usersDO.setPassword("h3khj1¥sdjs%#0x/!%$#dsjd!a!/1#@!");
usersDao.save(usersDO);
}
删
@Autowired
private UsersDao usersDao;
public void deleteUser(){
UsersDO usersDO = usersDao.findByPhone("1111111111");
usersDao.delete(usersDO);
}
改
与增的方法相同,就是多一步查找出UsersDO的实例,再调用set方法进行设置,最后save即可。
@Autowired
private UsersDao usersDao;
public void updateUser(){
UUsersDO usersDO = usersDao.findByPhone("1111111111");
usersDO.setPhone("12222222222");
usersDao.save(usersDO);
}
查
@Autowired
private UsersDao usersDao;
public void queryUser(){
UsersDO usersDO = usersDao.findByPhone("1111111111");
}