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>
  • 增加配置
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语句
  • 编写实体类
@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;
}
  • 声明Repository
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
  • 启动类
@SpringBootApplication
@EnableJpaAuditing
public class JpaDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(JpaDemoApplication.class, args);
    }
}

启动后可以发现已经自动创建好表:

在这里插入图片描述

三、增删改查

  • 注入对象
@Resource
UserRepository userRepository;
  • 保存数据
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());
  • 查询数据
User user = new User();
user.setName("张三");
Example<User> example = Example.of(user);
List<User> all = userRepository.findAll(example);
System.out.println(all.toString());
  • 修改数据
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);
});
  • 删除数据
userRepository.deleteById(20);

四、存储对象

  • 增加对象
@Data
public class Hobby {
    private String name;
    private String context;
}
  • 增加改对象的 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);
    }
}
  • 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;
}
  • 启动项目,查看数据结构

在这里插入图片描述

  • 测试添加数据
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());

在这里插入图片描述

四、一对一关联

  • 修改 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;
}
  • 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;
}
  • 启动项目查看表结构

在这里插入图片描述

在这里插入图片描述

  • 测试增加数据
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());

在这里插入图片描述
在这里插入图片描述

  • 指定字段关联
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "id",referencedColumnName = "id",foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private Hobby hobby;

五、一对多关联

  • 增加实体
@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;
    }
}
  • 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;
}
  • 增加数据
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());

在这里插入图片描述

六、多对对关联

  • 修改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;

}
  • 保存数据
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());

查看数据库结构:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小毕超

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值