【Spring】四,Spring与JPA

Spring与JPA

Spring Data是一个非常大的伞形项目,由多个子项目组成,其中大多数子项目都关注对不同的数据库类型进行数据持久化。比较流行的几个Spring Data项目包括:

  • Spring Data JPA:基于关系型数据库进行JPA持久化。 Spring Data MongoDB:持久化到Mongo文档数据库。
  • Spring Data Neo4j:持久化到Neo4j图数据库。 Spring Data Redis:持久化到Redis
  • key-value存储。 Spring Data Cassandra:持久化到Cassandra数据库。 Spring
  • Data为所有项目提供了一项最有趣且最有用的特性,就是基于repository规范接口自动生成repository的功能。

Sping Boot中使用JPA

在Spring Boot中使用JPA只需要引入相关的starter

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

配置文件中增加相关的配置

spring:
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update

将领域对象标注为实体

这里以用户与角色的多对多关系为例

@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
@Entity
@Table(name = "sys_user")
public class SysUser{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "user_id")
    private long userId;

    @Column(name = "user_name")
    private String userName;

    @Column(name = "gender")
    private String gender;

    @Column(name = "account",unique = true,nullable = false)
    private String account;

    @Column(name = "password",nullable = false)
    private String password;

    @Column(name = "city")
    private String city;

    @Column(name = "created_by")
    private String createdBy;

    @Column(name = "created_time")
    private Date createdTime;

    @Column(name = "updated_by")
    private String updatedBy;

    @Column(name = "updated_time")
    private Date updatedTime;

    @JsonIgnoreProperties("users")
    @ManyToMany(targetEntity = SysRole.class)
    @JoinTable(name = "sys_user_role",
            joinColumns = @JoinColumn(name = "user_id",referencedColumnName = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id",referencedColumnName = "role_id"))
    private List<SysRole> roles;

    @PrePersist
    void createdTime(){
        this.createdTime = new Date();
    }

}
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
@Entity
@Table(name = "sys_role")
public class SysRole{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "role_id")
    private long roleId;

    @Column(name = "role_name",nullable = false,unique = true)
    private String roleName;

    @Column(name = "created_by")
    private String createdBy;

    @Column(name = "created_time")
    private Date createdTime;

    @Column(name = "updated_by")
    private String updatedBy;

    @Column(name = "updated_time")
    private Date updatedTime;

    @JsonIgnoreProperties("roles")
    //mappedBy 放弃维护多对多关系
    @ManyToMany(targetEntity = SysUser.class,mappedBy = "roles")
    private List<SysUser> users;

    @PrePersist
    void createdTime(){
        this.createdTime = new Date();
    }

}

@Entity注解
将领域类声明为JPA实体。
@Id注解
领域类中标注@Id注解的属性对应数据库表中的主键字段。
@GeneratedValue(strategy = GenerationType.AUTO)
依赖数据库自动生成ID值。
@ManyToMany
user可以有多个role,而每个role可以被多个用户使用。
@PrePersist
对象持久化之前调用此方法,为对象中的属性赋值。一个领域类中只能有一个此注解。
@Table
对应数据库中表的名字。
@JoinTable
如果不想使用JPA自动生成的中间表,可以使用此注解自定义中间表的名字及相关字段的映射关系。
@JsonIgnoreProperties
解决双向关联时,生成JSON数据进入死循环的问题。
在SysUser中private List roles;字段上配置@JsonIgnoreProperties(“users”)代表的意思是:忽略roles中每个Role对象中的User对象,并不忽略User类中的roles属性。

声明Repository并继承JPA提供的Repository

public interface UserRepository extends CrudRepository<SysUser,Long> {

    SysUser findByAccount(String account);

    @Query(value = "SELECT a.account,a.user_name as userName FROM sys_user a,sys_role b,sys_user_role c " +
            "WHERE a.user_id = c.user_id " +
            "AND b.role_id = c.role_id " +
            "AND b.role_name = :roleName",nativeQuery = true)
    List<Map<String,Object>> findSysUserByRoleName(@Param("roleName") String roleName);

}

CrudRepository定义了很多用于CRUD(创建、读取、更新、删除)操作的方法。注意,它是参数化的,第一个参数是repository要持久化的实体类型,第二个参数是实体ID属性的类型。

不用编写实现类,当应用启动的时候,Spring Data JPA会在运行期自动生成实现类。

当创建repository实现的时候,Spring Data会检查repository接口的所有方法,解析方法的名称,并基于被持久化的对象来试图推测方法的目的。本质上,Spring Data定义了一组小型的领域特定语言(Domain-Specific Language,DSL),在这里持久化的细节都是通过repository方法的签名来描述的。

repository方法是由一个动词、一个可选的主题(Subject)、关键词By以及一个断言所组成的。详细的介绍可以查阅官方文档。

Spring Data会将get、read和find视为同义词,它们都是用来获取一个或多个实体的。另外,我们还可以使用count作为动词,它会返回一个int值,代表匹配实体的数量。

通过使用@Query,可以自己编写SQL。

完整的工程源码请访问:boot-integrate-jpa

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值