使用JPA建模使用唯一键和序列号的现有表

时间:2018-09-25 16:45:29

标签: spring spring-data-jpa

我需要使用JPA访问一个相当简单的(旧版)表。该表包含有关可配置(应用程序)菜单的信息。主键是菜单名称(字符10)。还有另一列称为序列号(int)。它们在一起必须是唯一的。读取表时,只需按菜单名称读取,返回的记录必须按序列号顺序。

Name       Seq  Description ...
---------- ---  --------------------
MAINMENU     0  Create an order
MAINMENU     1  Update an order
MAINMENU     2  Log off
ADMINMENU    0  Add a new user
ADMINMENU    1  Work with all users

我想知道如何在JPA中最好地表达这一点。我是否应该在两个字段中都使用主键(嵌入?)?但是我不想在阅读时提供序列号。另一方面,菜单名称和序列号必须唯一。

任何建议都值得欢迎。谢谢。

1 个答案:

答案 0 :(得分:0)

我现在使用@IdClass定义组合键的方式。然后,我按照如下方式添加了findByNameOrderBySequence:

public interface MenuRepository extends JpaRepository<Menu, MenuKey> {
    List<Menu> findByNameOrderBySequence(String name);
}

到我的存储库类。实际上,它确实以正确的顺序检索了正确的菜单。

我创建了MenuKey.java来处理2个字段的键:

package com.mycomp.myproj.models;

import java.io.Serializable;

public class MenuKey  implements Serializable {
    private String name;
    private int sequence;

    public MenuKey() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSequence() {
        return sequence;
    }

    public void setSequence(int sequence) {
        this.sequence = sequence;
    }

    @Override
    public int hashCode() {
        return (name+sequence).hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof MenuKey)) {
            return false;
        }
        MenuKey mk = (MenuKey) obj;
        return mk.name.equals(name) && mk.sequence == sequence;
    }
}

然后我创建Menu.java来映射表并在@IdClass批注中引用MenuKey:

package com.mycomp.myproj.models;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;

@IdClass(MenuKey.class)
@Entity
@Table(name="MENUS")
public class Menu {
    @Id
    @Column(name = "MENU", nullable = false)
    private String name;

    @Id
    @Column(name = "SEQN", nullable = false)
    private int sequence;

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

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

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

    public String getNAme() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSequence() {
        return sequence;
    }

    // the other getters and setters etc.
}