jpa繼承實體類
現在實際開發中開始使用spring-boot 2.0,其中安全性元件security非常好用,集成了使用者驗證和許可權控制以及密碼加密。不過實際開發中使用者往往不只一種,比如一個專案中,使用者就包括teacher ,student。他們的屬性是不同的,放一個使用者表裡不合適,這就要用到entity的繼承。
entity的繼承有三種方式,我們這裡只說最適合上面這種情況的一種:聯合子類策略
先上程式碼:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class SysUser {
@Id
@GeneratedValue
protected Integer id;
protected String username;
protected String password;
protected String name;
setting,getting......
}
@Entity
public class Student extends SysUser {
private String banji;
setting,getting......
}
@Entity
public class Teacher extends SysUser{
private String job;
setting,getting......
}
資料庫裡會自動給我們建立三個表,sys_user,student,teacher。其中sys_user 表裡會有四個欄位,id,username,password,name student表裡會有兩個欄位,id,banji。teacher表裡會有兩個欄位id,job。那我們如何操作呢,還是先上持久層的程式碼。
@Repository
public interface UserRepository extends JpaRepository<SysUser, Integer> {
…
}
@Repository
public interface StudentRepository extends JpaRepository<Student, Integer> {
…
}
@Repository
public interface TeacherRepository extends JpaRepository<Teacher, Integer> {
…
}
持久層我們建了三個介面,分別對應上面三個表。先來看如何向資料庫裡寫資料吧。
@RunWith(SpringRunner.class)
@SpringBootTest
public class EntityApplicationTests {
@Autowired
private TeacherRepository teacherDAO;
@Autowired
private StudentRepository studentDAO;
@Autowired
private UserRepository userDAO;
@Autowired
private ObjectMapper mapper;
@Test public void contextLoads() { Teacher t1=new Teacher(); t1.setName("張老師"); t1.setUsername("t01"); t1.setPassword("1111"); t1.setJob("班主任"); teacherDAO.save(t1); Student s1=new Student(); s1.setName("李學生"); s1.setBanji("軟體1班"); s1.setUsername("20170101"); s1.setPassword("2222"); studentDAO.save(s1); }
}
上面測試類程式碼分別用spring 注入的teacherDAO,studentDAO向資料庫裡儲存了t1,s1兩個物件,其中t1是教師,s1是學生。那我們看一下資料庫,
sys_user表裡加了兩條記錄:
id name password username
1 張老師 1111 t01
2 李學生 2222 20170101
teacher 表裡加了一條記錄:
id job
1 班主任
student表裡加了一條記錄:
id banji
2 軟體1班
分析一下,teacher,和student表中的id其實是外來鍵,用來關聯sys_user表的主鍵id的。
如何讀呢?我們可以用上面持久層的任何一個介面去完成資料的讀取工作。修改測試類如下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class EntityApplicationTests {
@Autowired
private TeacherRepository teacherDAO;
@Autowired
private StudentRepository studentDAO;
@Autowired
private UserRepository userDAO;
@Autowired
private ObjectMapper mapper;
@Test
public void contextLoads() {
SysUser user=userDAO.findById(1).get();
Student s2=userDAO.findById(2).get();
try {
System.out.println(mapper.writeValueAsString(user));
System.out.println(mapper.writeValueAsString(s2));
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
執行後控制檯輸出為:
{“id”:1,“username”:“t01”,“password”:“1111”,“name”:“張老師”,“job”:“班主任”}
{“id”:2,“username”:“20170101”,“password”:“2222”,“name”:“李學生”,“banji”:“軟體1班”}
重點看第一行,這是在輸出user,可從輸出結果來看,這明顯是Teacher,完全可以強制成Teacher再用。
用上面的結構來作為security的使用者資料的儲存方式,可以完美解決多種使用者登入驗證的問題!