SpringBoot JPA 基本使用 及 多表关联

举报
程序员-上善若水 发表于 2022/06/24 00:45:33 2022/06/24
【摘要】 一、JPA 对象-关系映射(Object/Relation Mapping,简称 ORM),是随着面向对象的软件开发方法发展而产生的。面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据...

一、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

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。