SpringBoot JPA 基本使用 及 多表关联
一、JPA
对象-关系映射(Object/Relation Mapping,简称 ORM),是随着面向对象的软件开发方法发展而产生的。面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。
JPA 由 EJB 3.0 软件专家组开发,作为 JSR-220 实现的一部分。但它又不限于 EJB 3.0,你可以在 Web 应用、甚至桌面应用中使用。JPA 的宗旨是为 POJO 提供持久化标准规范,由此可见,经过这几年的实践探索,能够脱离容器独立运行,方便开发和测试的理念已经深入人心了。Hibernate3.2+、TopLink 10.1.3 以及 OpenJPA 都提供了 JPA 的实现。Sun 引入新的 JPA ORM 规范出于两个原因:其一,简化现有 Java EE 和 Java SE 应用开发工作;其二,Sun 希望整合 ORM 技术,实现天下归一。
二、SpringBoot 集成 JPA
- 引入pom 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 增加配置
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/testdb?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
type: com.alibaba.druid.pool.DruidDataSource
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver #驱动
jpa:
hibernate:
ddl-auto: update #自动更新
show-sql: true #日志中显示sql语句
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 编写实体类
@Data
@Entity
@Table(name = "user")
@EntityListeners(AuditingEntityListener.class)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", unique = true, nullable = true, length = 20)
private String name;
@Column(name = "age", nullable = true, length = 4)
private Integer age;
@Column
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime birthday;
@Column
@CreatedDate
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;
@Column
@LastModifiedDate
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime updateTime;
@Version
private Integer version;
//忽略字段
@Transient
private String phone;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 声明Repository
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
- 1
- 2
- 3
- 启动类
@SpringBootApplication
@EnableJpaAuditing
public class JpaDemoApplication {
public static void main(String[] args) {
SpringApplication.run(JpaDemoApplication.class, args);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
启动后可以发现已经自动创建好表:
三、增删改查
- 注入对象
@Resource
UserRepository userRepository;
- 1
- 2
- 保存数据
User user = new User();
user.setName("张三");
user.setAge(18);
user.setBirthday(LocalDateTime.parse("2022-06-18 12:56:36", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
User save = userRepository.save(user);
System.out.println(save.toString());
- 1
- 2
- 3
- 4
- 5
- 6
- 查询数据
User user = new User();
user.setName("张三");
Example<User> example = Example.of(user);
List<User> all = userRepository.findAll(example);
System.out.println(all.toString());
- 1
- 2
- 3
- 4
- 5
- 修改数据
Optional<User> byId = userRepository.findById(20);
if (!byId.isPresent()) {
return "查询数据为空!";
}
byId.ifPresent(u -> {
u.setName("李四");
LocalDateTime localDateTime = u.getBirthday();
System.out.println(localDateTime.toString());
System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
userRepository.save(u);
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 删除数据
userRepository.deleteById(20);
- 1
四、存储对象
- 增加对象
@Data
public class Hobby {
private String name;
private String context;
}
- 1
- 2
- 3
- 4
- 5
- 增加改对象的 Converter 类
public class HobbyConverter implements AttributeConverter<Hobby, String> {
@Override
public String convertToDatabaseColumn(Hobby attribute) {
return JSONObject.toJSONString(attribute);
}
@Override
public Hobby convertToEntityAttribute(String dbData) {
return JSONObject.parseObject(dbData, Hobby.class);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- User实体中增加字段
@Data
@Entity
@Table(name = "user")
@EntityListeners(AuditingEntityListener.class)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", unique = true, nullable = true, length = 20)
private String name;
@Column(name = "age", nullable = true, length = 4)
private Integer age;
@Column
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime birthday;
@Column
@CreatedDate
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;
@Column
@LastModifiedDate
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime updateTime;
@Version
private Integer version;
//忽略字段
@Transient
private String phone;
//存储对象
@Convert(converter = HobbyConverter.class)
@Column(columnDefinition = "mediumtext")
private Hobby hobbyValue;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 启动项目,查看数据结构
- 测试添加数据
User user = new User();
user.setName("张三");
user.setAge(18);
user.setBirthday(LocalDateTime.parse("2022-06-18 12:56:36", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
Hobby hobby = new Hobby();
hobby.setName("小龙虾");
hobby.setContext("小龙虾哈哈哈");
user.setHobbyValue(hobby);
User save = userRepository.save(user);
System.out.println(save.toString());
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
四、一对一关联
- 修改 Hobby 对象使其成为实体
@Data
@Entity
@Table(name = "hobby")
public class Hobby {
@Id
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@GeneratedValue(generator = "system-uuid")
private String id;
private String name;
private String context;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- User 实体增加字段
@Data
@Entity
@Table(name = "user")
@EntityListeners(AuditingEntityListener.class)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", unique = true, nullable = true, length = 20)
private String name;
@Column(name = "age", nullable = true, length = 4)
private Integer age;
@Column
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime birthday;
@Column
@CreatedDate
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;
@Column
@LastModifiedDate
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime updateTime;
@Version
private Integer version;
//忽略字段
@Transient
private String phone;
//存储对象
@Convert(converter = HobbyConverter.class)
@Column(columnDefinition = "mediumtext")
private Hobby hobbyValue;
// 映射实体
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private Hobby hobby;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 启动项目查看表结构
- 测试增加数据
User user = new User();
user.setName("张三1");
user.setAge(18);
user.setBirthday(LocalDateTime.parse("2022-06-18 12:56:36", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
Hobby hobby = new Hobby();
hobby.setName("小龙虾");
hobby.setContext("小龙虾哈哈哈");
user.setHobbyValue(hobby);
user.setHobby(hobby);
User save = userRepository.save(user);
System.out.println(save.toString());
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 指定字段关联
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "id",referencedColumnName = "id",foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private Hobby hobby;
- 1
- 2
- 3
五、一对多关联
- 增加实体
@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
public class UserInfo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private Long userId;
@Column
private String phone;
@Column
private String mail;
public UserInfo(String phone, String mail) {
this.phone = phone;
this.mail = mail;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- User 实体增加字段
@Data
@Entity
@Table(name = "user")
@EntityListeners(AuditingEntityListener.class)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", unique = true, nullable = true, length = 20)
private String name;
@Column(name = "age", nullable = true, length = 4)
private Integer age;
@Column
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime birthday;
@Column
@CreatedDate
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;
@Column
@LastModifiedDate
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime updateTime;
@Version
private Integer version;
//忽略字段
@Transient
private String phone;
//存储对象
@Convert(converter = HobbyConverter.class)
@Column(columnDefinition = "mediumtext")
private Hobby hobbyValue;
// 映射实体
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private Hobby hobby;
//映射多实体
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "userId", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private List<UserInfo> userInfoList;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 增加数据
User user = new User();
user.setName("张三3");
user.setAge(18);
user.setBirthday(LocalDateTime.parse("2022-06-18 12:56:36", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
Hobby hobby = new Hobby();
hobby.setName("小龙虾");
hobby.setContext("小龙虾哈哈哈");
user.setHobby(hobby);
user.setHobbyValue(hobby);
List<UserInfo> list = new ArrayList<>();
list.add(new UserInfo("110","110@qq.com"));
list.add(new UserInfo("120","120@qq.com"));
user.setUserInfoList(list);
User save = userRepository.save(user);
System.out.println(save.toString());
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
六、多对对关联
- 修改User实体,添加字段
@Data
@Entity
@Table(name = "user")
@EntityListeners(AuditingEntityListener.class)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", unique = true, nullable = true, length = 20)
private String name;
@Column(name = "age", nullable = true, length = 4)
private Integer age;
@Column
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime birthday;
@Column
@CreatedDate
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;
@Column
@LastModifiedDate
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime updateTime;
@Version
private Integer version;
//忽略字段
@Transient
private String phone;
//多对对关联
@ManyToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
@JoinColumn(name = "userId", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private List<UserInfo> userInfos;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 保存数据
User user = new User();
user.setName("张三20");
user.setAge(18);
user.setBirthday(LocalDateTime.parse("2022-06-18 12:56:36", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
List<UserInfo> list = new ArrayList<>();
list.add(new UserInfo("110","110@qq.com"));
list.add(new UserInfo("120","120@qq.com"));
user.setUserInfos(list);
User save = userRepository.save(user);
System.out.println(save.toString());
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
查看数据库结构:
文章来源: blog.csdn.net,作者:小毕超,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq_43692950/article/details/107443104
- 点赞
- 收藏
- 关注作者
评论(0)