內容目錄
Many-To-One & One-To-Many 在 Model 上的設置
Model
在系統的實務運作上,一個員工與主管,主管與部屬是很基本的架構,也常會放在同一個表格 ( Table ) 中。
主管
基本的 Model 的設計應該是 @ManyToOne
,若只加入主管時, 如程式碼14-17。
@Entity @Table(schema = "SYS",name = "EMPLOYEE") @Data public class UserDetails implements java.io.Serializable { @Id @Column(name = "EMP_ID", unique = true, nullable = false, length = 30) private String empId; @Column(name = "EMP_JOB_TITLE", length = 12) private String empJobTitle; @Column(name = "MANAGER_ID", length = 30) private String managerId; @ManyToOne() @NotFound(action = NotFoundAction.IGNORE) @JoinColumn(name = "MANAGER_ID",insertable = false,updatable = false) private UserDetails manager; }
要注意,若資料庫是 Oracle 時,@Table(schema = "SYS")
中的 schema 要加入,以免找不到表格 ( Table )
說明:
如果最上層主管(Root)的MANAGER_ID 是 NULL 時,可以加入 annotation optional=true
@ManyToOne(optional = true, fetch = FetchType.LAZY) @JoinColumn(name = "MANAGER_ID",insertable = false,updatable = false)
如果最上層主管(Root)的MANAGER_ID,值不一定是 NULL,而是以 ROOT 或其它值代表為 Root 時,可以使用 @NotFound(action = NotFoundAction.IGNORE)
@ManyToOne() @NotFound(action = NotFoundAction.IGNORE) @JoinColumn(name = "MANAGER_ID",insertable = false,updatable = false)
這樣子就可以避免 NullPointerException
的錯誤
部屬
部屬的資料也是常需要知道的,在 Model 中的設計則應該是@OneToMany
。
@ToString.Exclude @OneToMany(fetch = FetchType.LAZY ,mappedBy="manager") private List<UserDetails> subordinates = new ArrayList<UserDetails>();
說明:
- @ToString.Exclude 可以避免
java.lang.StackOverflowError
的錯誤 - 在取部屬的資訊應使用 fetch = FetchType.LAZY ,並且在執行時應加入 @Transactional
整個 Model 程式碼
@Entity @Table(schema = "SYS",name = "EMPLOYEE") @Data public class UserDetails implements java.io.Serializable { @Id @Column(name = "EMP_ID", unique = true, nullable = false, length = 30) private String empId; @Column(name = "EMP_JOB_TITLE", length = 12) private String empJobTitle; @Column(name = "MANAGER_ID", length = 30) private String managerId; @ManyToOne() @NotFound(action = NotFoundAction.IGNORE) @JoinColumn(name = "MANAGER_ID",insertable = false,updatable = false) private UserDetails manager; @ToString.Exclude @OneToMany(fetch = FetchType.LAZY ,mappedBy="manager") private List<UserDetails> subordinates = new ArrayList<UserDetails>(); }
測試的程式
@SpringBootTest @Transactional public class BpmTest { @Autowired private UserDetailsRepository udRepo; @Test public void basicTest() { Optional<UserDetails> ud = udRepo.findByEmpId("0001"); if (ud.isPresent()) { System.out.println(ud.get().getEmpId()+":" +ud.get().getRealName()); System.out.println("Boss:"+ud.get().getManager()); List<UserDetails> lud = ud.get().getSubordinates(); for (UserDetails uds : lud) { System.out.println("Member:"+ uds); } } } }
參考
你必須 登入 才能發表評論。