[java framework] JPA -- JPA mapping relationship

Keywords: Java Attribute Database SQL

1. One way one to many configuration

One way one to many is configured with the @ OneToMany tag. One party has a Set attribute associated with multiple parties. A Set can be a List or a Set, but the difference is that a List is ordered and a Set is not repeated.

Corresponding to the configuration of @ OneToMany on one side:

/**
 *  One way one to many: using JPA configuration
 */
@Entity
@Table(name = "t_productdir")
public class ProductDir {
    @Id
    @GeneratedValue
    private Integer id;

    @Column(name = "dName")
    private String dirName; //Product classification name

    /**
     *  One way one to many: use Set or List to maintain multi-party relationship in one party
     *  For a collection, you must first new it
     *
     *  For databases: no matter how many to one, or one to many, one-way or two-way,
     *  The database settings are all the same, which side is multi-party, and which side is the foreign key
     *  One way one to many, the default is lazy loading (lazy loading will be configured later)
     */
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "dir_id")
    @OrderBy("id desc") //Use when sorting is needed@OrderBy To get the value, use between multiple sorting attributes","Split, and be sure to use List aggregate
    private Set<Product> productSet = new HashSet<>(); //Collection default lazy load

    public ProductDir() {
    }

Performance: one way one to many sends the same number of SQL statements no matter whether it is configured to load lazily or urgently, with poor performance.

2. Two way one to many, many to one configuration

Two point one . basic configuration

Two way one to many and many to one need to configure properties on both sides at the same time. One party and many parties need to have associated properties (configure @ ManyToOne and @ OneToMany at the same time), and at the same time, one party abandons the relationship maintenance configuration mappedBy. The specific configuration is as follows:

Multi party products:

/**
 *  Two way one to many, many to one: using JPA configuration
 */
@Entity
@Table(name = "t_product")
public class Product {
    @Id
    @GeneratedValue
    private Integer id;

    @Column(name = "t_name")
    private String name; //Product name

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "dir_id")
    private ProductDir productDir;

    public ProductDir getProductDir() {
        return productDir;
    }

    public void setProductDir(ProductDir productDir) {
        this.productDir = productDir;
    }

    public Product() {
    }

}

Party ProductDir:

/**
 *  Two way one to many, many to one: using JPA configuration
 */
@Entity
@Table(name = "t_productdir")
public class ProductDir {
    @Id
    @GeneratedValue
    private Integer id;

    @Column(name = "dName")
    private String dirName; //Product classification name

    //mappedBy: One party gives up the relationship maintenance and gives the relationship maintenance to many parties. Pay attention to mappedBy Values in must be and Product in ProductDir The properties of
    //Note: use mappedBy Don't use it JoinColumn No need to maintain the relationship
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "productDir")
    //@JoinColumn(name = "dir_id")
   // @OrderBy("id desc") //Use when sorting is needed@OrderBy To get the value, use between multiple sorting attributes","Split, and be sure to use List aggregate
    private Set<Product> productSet = new HashSet<>(); //Collection default lazy load

    public ProductDir() {
    }

}

Two point two . cascade configuration

cascade is used to represent cascading on one party's multi-party attribute @ OneToMany, which is mainly configured in the following ways:

①    Cascade=CascadeType.PERSIST : cascade save;

②    Cascade=CascadeType.REMOVE : cascade delete (very dangerous);

③    Cascade=CascadeType.ALL : cascade addition, deletion and modification

3. One way many to many

For many to many relationship, we save 2 users and 3 roles to test many to many;

Users and roles are many to many relationships. A user corresponds to multiple roles, and a role can be played by multiple users.

Multi heap multi relation involves an intermediate table user_role,

One way relationship: multiple roles can be found through users, but roles cannot find corresponding users.

Three point one . one way many to many configuration

Main table: User user class

/**
 * Based on one-way many to many, you can find the corresponding role in the user side (the role cannot find the corresponding user). You only need to configure @ ManyToMany annotation mapping in the user side
 */
@Entity
@Table(name="t_user")
public class User {
    @GeneratedValue
    @Id
    private Long id;

    private String name;

    // @ManyToMany Note representation User It's the end of the many to many relationship.
    // @JoinTable The middle table relation of many to many relation is described. name Property specifies the middle table name,
    // joinColumns Define intermediate table and current class User Foreign key relationship of. inverseJoinColumns Defining intermediate tables and associated classes Role Foreign key relationship of.
    @ManyToMany
    @JoinTable(name = "t_user_role", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = {
            @JoinColumn(name = "role_id") })
    private Set<Role> roles = new HashSet<Role>();

    public User() {
    }

    public User(String name) {
        this.name = name;
    }
}

From table: Role role class

@Entity
@Table(name="t_role")
public class Role {
    @GeneratedValue
    @Id
    private Long id;

    private String name;

    public Role() {
    }

    public Role(String name) {
        this.name = name;
    }
}

Create test class accordingly:

/**
     * Save 2 users and 3 roles (5)
     */
    @Test
public void persistUserTest() {
    User user1 = new User("user1");
    User user2 = new User("user2");

    Role role1 = new Role("role1");
    Role role2 = new Role("role2");
    Role role3 = new Role("role3");

    // Save middle table:Establish user to role relationship user1(role1,role2),user2(role1,role2,role3)(5 strip)
    user1.getRoles().add(role1);
    user1.getRoles().add(role2);
    user2.getRoles().add(role1);
    user2.getRoles().add(role2);
    user2.getRoles().add(role3);

    EntityManager entityManager = JPAUtil.getEntityManager();
    entityManager.getTransaction().begin();

    //Save user
    entityManager.persist(user1);
    entityManager.persist(user2);
    // Save role
    entityManager.persist(role1);
    entityManager.persist(role2);
    entityManager.persist(role3);

    entityManager.getTransaction().commit();
    JPAUtil.close(entityManager);
}

4. Two way many to many

Four point one . bidirectional multi heap multi configuration

Two way many to many is to configure @ ManyToMany annotation on both sides at the same time. The specific configuration is as follows:

One party Role configuration:

@Entity
@Table(name="t_role")
public class Role {
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Id
    private Long id;

    private String name;

    // @ManyToMany Note representation Role It's the end of the many to many relationship.
    @ManyToMany
    //joinColumns Represents the middle table and current Role Table's connection foreign key, inverseJoinColumns Represent multiple parties User Foreign key connection with intermediate table
    @JoinTable(name = "t_user_role", joinColumns = { @JoinColumn(name = "role_id") }, inverseJoinColumns = {
            @JoinColumn(name = "user_id") })
    private Set<User> userSet = new HashSet<>();

    public Role() {
    }

    public Set<User> getUserSet() {
        return userSet;
    }

    public void setUserSet(Set<User> userSet) {
        this.userSet = userSet;
    }

    public Role(String name) {
        this.name = name;
    }

}

Multi User configuration:

/**
 * Based on one-way many to many, you can find the corresponding role in the user side (the role cannot find the corresponding user). You only need to configure @ ManyToMany annotation mapping in the user side
 */
@Entity
@Table(name="t_user")
public class User {
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Id
    private Long id;

    private String name;

    // @ManyToMany Note representation User It's the end of the many to many relationship.
    // @JoinTable The middle table relation of many to many relation is described. name Property specifies the middle table name,
    // joinColumns Define intermediate table and current class User Foreign key relationship of. inverseJoinColumns Defining intermediate tables and associated classes Role Foreign key relationship of.
    @ManyToMany
    @JoinTable(name = "t_user_role", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = {
            @JoinColumn(name = "role_id") })
    private Set<Role> roles = new HashSet<Role>();

    public User() {
    }

    public User(String name) {
        this.name = name;
    }

}

5. One to one configuration

The one-to-one scenario is rarely used in the actual project. Here, take QQ and QQ space as an example. There is QQ space only when there is QQ.

Five point one . one to one foreign key

QQ class (primary 1)

@Entity
public class QQ {
  @Id
  @GeneratedValue
  private Long id;
  private String number;
  // one-on-one,One qq Number corresponds to one qq space
  @OneToOne(mappedBy="qq")
  private QQZone zone;
}

QQ space class (from 1)

@Entity
public class QQZone {
  @Id
  @GeneratedValue
  private Long id;
  private String name;
  // one-on-one,One qq Space belongs to one qq number
  // Default optional = true express qq_id Can be empty;conversely...
  @OneToOne(optional = false)
  // unique=true Ensures a one-to-one relationship
  @JoinColumn(name = "qq_id", unique = true)
  private QQ qq;
}

5.1.1 Save data test

public void persist() throws Exception {
    QQ qq = new QQ();
    qq.setNumber("123456");

    QQZone zone = new QQZone();
    zone.setName("Maple night");

    // Building relationships
    qq.setZone(zone);
    zone.setQq(qq);

    EntityManager entityManager = JPAUtils.getEntityManager();
    entityManager.getTransaction().begin();

    // Save primary one first
    entityManager.persist(qq);
    entityManager.persist(zone);

    entityManager.getTransaction().commit();
    entityManager.close();
}

Five point two . one to one primary key sharing

QQ space class (from 1)

@Entity
public class QQZone {
  @Id
  @GeneratedValue(generator = "fkGenerator")
  @GenericGenerator(name = "fkGenerator", strategy = "foreign", parameters = @Parameter(name = "property", value = "qq"))
  private Long id;
  private String name;
  // one-on-one,One qq Space input one qq number
  @OneToOne(optional = false)
  // If not, add QQZone When information, it will automatically QQZone A foreign key is added to the table qq_id
  @PrimaryKeyJoinColumn
  private QQ qq;
}

Posted by scott.stephan on Mon, 18 May 2020 10:53:00 -0700