Spring Data JPA 진급 Specification 동적 조회
21959 단어 Spring
때때로 우 리 는 특정한 실 체 를 조회 할 때 주어진 조건 이 고정 되 지 않 을 때 해당 하 는 조회 문 구 를 동적 으로 구축 해 야 한다. Spring Data JPA 에서 Jpa SpecificationExecutor 인 터 페 이 스 를 통 해 조회 할 수 있다.JPQL 보 다 는 타 입 이 안전 하고 대상 지향 적 이라는 장점 이 있다.
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
/**
* JpaSpecificationExecutor
**/
public interface JpaSpecificationExecutor {
//
T findOne(Specification spec);
//
List findAll(Specification spec);
//
Page findAll(Specification spec, Pageable pageable);
//
List findAll(Specification spec, Sort sort);
//
long count(Specification spec);
}
Jpa SpecificationExecutor 에 대해 이 인 터 페 이 스 는 기본적으로 Specification 인 터 페 이 스 를 중심 으로 정 의 됩 니 다.Specification 구 조 는 검색 조건 이 라 고 간단하게 이해 할 수 있 습 니 다.
Specification 인터페이스 에 서 는 다음 과 같은 방법 만 정의 합 니 다.
//
/**
* root :Root , , root
* query : ,
* cb : ,
**/
public Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder cb);
1.1 Specifications 를 사용 하여 조건 조회 완료
// customerDao
@Autowired
private CustomerDao customerDao;
@Test
public void testSpecifications() {
// , Specification , toPredicate
Specification spec = new Specification() {
public Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder cb) {
//cb: , like:
//root: Customer custName
return cb.like(root.get("custName").as(String.class), " %");
}
};
Customer customer = customerDao.findOne(spec);
System.out.println(customer);
}
1.2 Specifications 기반 페이지 조회
@Test
public void testPage() {
//
Specification spec = new Specification() {
public Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder cb) {
return cb.like(root.get("custName").as(String.class), " %");
}
};
/**
*
* Pageable :
* PageRequest Pageable ,
* : ( 0 )
* :
*/
Pageable pageable = new PageRequest(0, 5);
/**
* , Spring Data Jpa page bean
* findAll
* : Specification
* :
*/
Page page = customerDao.findAll(spec,pageable);
}
Spring Data JPA 의 페이지 별 조 회 는 내부 에서 자동 으로 이 루어 지 는 패 키 징 과정 으로 Spring Data JPA 가 제공 하 는 pageBean 대상 을 되 돌려 줍 니 다.그 중의 방법 은 다음 과 같다.
//
int getTotalPages();
//
long getTotalElements();
//
List getContent();
1.3 방법 대응 관계 방법 명칭 Sql 대응 관계
equle filed = value
gt(greaterThan) filed > value
lt(lessThan) filed < value
ge(greaterThanOrEqualTo) filed >= value
le(lessThanOrEqualTo) filed <= value
notEqule filed != value
like filed like value
notLike filed not like value
제2 장 다 표 디자인
2.1 표 간 의 관계 구분
데이터베이스 에 여러 표 사이 에 세 가지 관계 가 존재 한다. 다 대 다, 한 쌍 다 와 한 쌍 의 관계 이다.주의: 한 쌍 의 다 관 계 는 두 가지 로 볼 수 있 습 니 다. 즉, 한 쌍 이 많 고 한 쌍 이 많 습 니 다.그 러 니까 네 가지 가 더 정확 해.
명확: 우 리 는 오늘 실제 개발 에서 자주 사용 하 는 관련 관계, 한 쌍 이 많 고 여러 쌍 이 많다.1 대 1 의 경우, 실제 개발 에 서 는 거의 사용 되 지 않 는 다.
2.2 JPA 프레임 워 크 에서 표 관계 에 대한 분석 절차
실제 개발 에서 우리 데이터 뱅 크 의 표 는 서로 관련 관계 가 있 을 수 밖 에 없고 조작 표를 할 때 여러 장의 표 조작 과 관련 될 수 있다.이러한 ORM 사상 을 실현 하 는 구조 에서 (예 를 들 어 JPA) 우 리 는 실체 류 를 조작 함으로써 데이터 베이스 시트 에 대한 조작 을 실현 할 수 있다.그래서 오늘 우리 의 학습 중점 은 배치 실체 간 의 관련 관 계 를 파악 하 는 것 이다.
STEP 1: 먼저 두 장의 표 간 의 관 계 를 확인한다.
만약 관계 가 틀 렸 다 면, 뒤에서 하 는 모든 조작 은 정확 할 수 없 을 것 이다.
두 번 째 단계: 데이터베이스 에서 두 장의 표 의 관 계 를 실현 합 니 다.
세 번 째 단계: 실체 류 에서 두 실체의 관 계 를 묘사 합 니 다.
네 번 째 단계: 실체 클래스 와 데이터베이스 시트 의 관계 맵 설정 (중점)
3 JPA 중 에 한 쌍 이 많아 요.
3.1 예시 분석
우리 가 채택 한 예 는 고객 과 연락처 이다.
고객: 한 회 사 를 말 합 니 다. 우 리 는 A 로 기록 합 니 다.
연락처: A 회사 의 직원 을 말 합 니 다.
아르 바 이 트 를 고려 하지 않 고 회사 와 직원 의 관 계 는 한 쌍 이 많다.
3.2 표 관계 구축
한 쌍 의 다 중 관계 에서 우 리 는 한 쪽 을 위주 표 라 고 부 르 고 많은 쪽 을 종 표 라 고 부 르 는 습관 이 있다.데이터베이스 에 한 쌍 이상 의 관 계 를 맺 으 려 면 데이터베이스 의 외부 키 로 제약 을 받 아야 한다.
무엇이 외 키 입 니까?표 에 열 이 있 는 것 을 말 합 니 다. 값 은 메 인 표 의 메 인 키 를 참조 하고 이 열 은 바로 외 키 입 니 다.
다음 그림 과 같이 다 중 데이터베이스 관계 의 구축
3.3 실체 류 관계 구축 및 맵 설정
실체 류 에서 고객 이 적은 쪽 이기 때문에 여러 개의 연락 처 를 포함해 야 하기 때문에 실체 류 는 고객 중 여러 개의 연락 처 를 나타 내야 한다. 코드 는 다음 과 같다.
/**
*
* JPA
* javax.persistence
*/
@Entity//
@Table(name="cst_customer")//
public class Customer implements Serializable {
@Id//
@GeneratedValue(strategy=GenerationType.IDENTITY)//
@Column(name="cust_id")// cust_id
private Long custId;
@Column(name="cust_name")// cust_name
private String custName;
@Column(name="cust_source")// cust_source
private String custSource;
@Column(name="cust_industry")// cust_industry
private String custIndustry;
@Column(name="cust_level")// cust_level
private String custLevel;
@Column(name="cust_address")// cust_address
private String custAddress;
@Column(name="cust_phone")// cust_phone
private String custPhone;
//
@OneToMany(targetEntity=LinkMan.class)
@JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id")
private Set linkmans = new HashSet(0);
public Long getCustId() {
return custId;
}
public void setCustId(Long custId) {
this.custId = custId;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public String getCustSource() {
return custSource;
}
public void setCustSource(String custSource) {
this.custSource = custSource;
}
public String getCustIndustry() {
return custIndustry;
}
public void setCustIndustry(String custIndustry) {
this.custIndustry = custIndustry;
}
public String getCustLevel() {
return custLevel;
}
public void setCustLevel(String custLevel) {
this.custLevel = custLevel;
}
public String getCustAddress() {
return custAddress;
}
public void setCustAddress(String custAddress) {
this.custAddress = custAddress;
}
public String getCustPhone() {
return custPhone;
}
public void setCustPhone(String custPhone) {
this.custPhone = custPhone;
}
public Set getLinkmans() {
return linkmans;
}
public void setLinkmans(Set linkmans) {
this.linkmans = linkmans;
}
@Override
public String toString() {
return "Customer [custId=" + custId + ", custName=" + custName + ", custSource=" + custSource
+ ", custIndustry=" + custIndustry + ", custLevel=" + custLevel + ", custAddress=" + custAddress
+ ", custPhone=" + custPhone + "]";
}
}
연락 처 는 많은 측 이기 때문에 실체 류 에서 나타 나 려 면 모든 연락 처 는 한 명의 고객 만 대응 할 수 있 고 코드 는 다음 과 같다.
/**
* ( )
*/
@Entity
@Table(name="cst_linkman")
public class LinkMan implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="lkm_id")
private Long lkmId;
@Column(name="lkm_name")
private String lkmName;
@Column(name="lkm_gender")
private String lkmGender;
@Column(name="lkm_phone")
private String lkmPhone;
@Column(name="lkm_mobile")
private String lkmMobile;
@Column(name="lkm_email")
private String lkmEmail;
@Column(name="lkm_position")
private String lkmPosition;
@Column(name="lkm_memo")
private String lkmMemo;
// :
@ManyToOne(targetEntity=Customer.class)
@JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id")
private Customer customer;// ,
public Long getLkmId() {
return lkmId;
}
public void setLkmId(Long lkmId) {
this.lkmId = lkmId;
}
public String getLkmName() {
return lkmName;
}
public void setLkmName(String lkmName) {
this.lkmName = lkmName;
}
public String getLkmGender() {
return lkmGender;
}
public void setLkmGender(String lkmGender) {
this.lkmGender = lkmGender;
}
public String getLkmPhone() {
return lkmPhone;
}
public void setLkmPhone(String lkmPhone) {
this.lkmPhone = lkmPhone;
}
public String getLkmMobile() {
return lkmMobile;
}
public void setLkmMobile(String lkmMobile) {
this.lkmMobile = lkmMobile;
}
public String getLkmEmail() {
return lkmEmail;
}
public void setLkmEmail(String lkmEmail) {
this.lkmEmail = lkmEmail;
}
public String getLkmPosition() {
return lkmPosition;
}
public void setLkmPosition(String lkmPosition) {
this.lkmPosition = lkmPosition;
}
public String getLkmMemo() {
return lkmMemo;
}
public void setLkmMemo(String lkmMemo) {
this.lkmMemo = lkmMemo;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
@Override
public String toString() {
return "LinkMan [lkmId=" + lkmId + ", lkmName=" + lkmName + ", lkmGender=" + lkmGender + ", lkmPhone="
+ lkmPhone + ", lkmMobile=" + lkmMobile + ", lkmEmail=" + lkmEmail + ", lkmPosition=" + lkmPosition
+ ", lkmMemo=" + lkmMemo + "]";
}
}
3.4 매 핑 의 주해 설명
@OneToMany:
:
:
targetEntityClass:
mappedBy: 。
cascade:
fetch:
orphanRemoval:
@ManyToOne
:
:
targetEntityClass:
cascade:
fetch:
optional: 。 false, 。
@JoinColumn
: 。
:
name:
referencedColumnName:
unique: 。
nullable: 。 。
insertable: 。 。
updatable: 。 。
columnDefinition: 。
3.5 한 쌍 이상 의 조작
3.5.1 추가
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class OneToManyTest {
@Autowired
private CustomerDao customerDao;
@Autowired
private LinkManDao linkManDao;
/**
*
* :
*
* :
*
* ( )
* ,
* :
* , , :
* 2 insert 1 update.
* 2 insert。
*
*/
@Test
@Transactional //
@Rollback(false)//
public void testAdd() {
Customer c = new Customer();
c.setCustName("TBD ");
c.setCustLevel("VIP ");
c.setCustSource(" ");
c.setCustIndustry(" ");
c.setCustAddress(" ");
c.setCustPhone("010-84389340");
LinkMan l = new LinkMan();
l.setLkmName("TBD ");
l.setLkmGender("male");
l.setLkmMobile("13811111111");
l.setLkmPhone("010-34785348");
l.setLkmEmail("[email protected]");
l.setLkmPosition(" ");
l.setLkmMemo(" ");
c.getLinkMans().add(l);
l.setCustomer(c);
customerDao.save(c);
linkManDao.save(l);
}
}
저 장 된 사례 를 통 해 우 리 는 양 방향 관 계 를 설정 한 후에 두 개의 insert 문 구 를 보 내 고 불필요 한 update 문 구 를 보 내 는 것 을 알 수 있 습 니 다. 그러면 우리 의 해결 은 생각 이 매우 간단 하고 한 측 이 유지 권 을 포기 하 는 것 입 니 다.
/**
*
*/
//@OneToMany(targetEntity=LinkMan.class)
//@JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id")
//
@OneToMany(mappedBy="customer")
3.5.2 삭제
@Autowired
private CustomerDao customerDao;
@Test
@Transactional
@Rollback(false)//
public void testDelete() {
customerDao.delete(1l);
}
삭제 작업 에 대한 설명 은 다음 과 같 습 니 다.
표 데이터 삭제: 언제든지 임의로 삭제 할 수 있 습 니 다.
메 인 테이블 데이터 삭제:
* 61557 은 표 데이터 1 에서 기본 적 인 상황 에서 외부 키 필드 를 null 로 설정 한 다음 에 메 인 표 데 이 터 를 삭제 합 니 다.데이터베이스 의 표 구조 에 있어 서 외부 키 필드 에 빈 제약 이 있 으 면 기본 적 인 상황 이 잘못 보 고 됩 니 다.2. 관련 관 계 를 유지 할 권 리 를 포기 하면 삭제 할 수 없습니다. (외부 키 필드 가 null 로 허용 되 는 지 여부 와 관계 가 없습니다) 삭제 할 때 표 의 외부 키 필드 를 업데이트 하지 않 기 때 문 입 니 다.3. 삭제 하려 면 직렬 연결 을 사용 하여 참조 삭제
표 데이터 참조 없 음: 마음대로 삭제
실제 개발 중, 등급 삭제 신중하게 사용 하 세 요!(한 쌍 이 많은 상황 에서)
3.5.3 레벨 연결 조작
연결 작업: 대상 을 조작 하 는 동시에 관련 대상 을 조작 하 는 것 을 말한다.
사용 방법: 작업 주체 의 주해 에 캐 스 케 이 드 만 설정 하면 됩 니 다.
/**
* cascade:
* CascadeType.MERGE
* CascadeType.PERSIST :
* CascadeType.REFRESH :
* CascadeType.REMOVE :
* CascadeType.ALL
*/
@OneToMany(mappedBy="customer",cascade=CascadeType.ALL)
4 JPA 중 에 다 대 다.
4.1 예시 분석
우리 가 채택 한 예 는 사용자 와 역할 이다.
사용자: 우리 반 의 모든 학우 들 을 말 합 니 다.
역할: 우리 반 친구 들 의 신분 정 보 를 말 합 니 다.
예 를 들 어 A 학생 은 제 학생 입 니 다. 그 중 에 한 신분 이 학생 입 니까? 아니면 집안 의 아이 입 니까? 그러면 그 는 자녀 입 니 다.
이 동시에 B 학생 은 학생 과 자녀의 신분 도 가진다.
그러면 어떤 학우 도 여러 가지 신분 을 가 질 수 있다.동시에 학생 이라는 신분 은 여러 학우 에 의 해 가 질 수 있다.
그래서 우 리 는 사용자 와 캐릭터 간 의 관계 가 많 고 많다 고 말한다.
4.2 표 관계 구축
여러 쌍 의 표 관 계 를 구축 하 는 것 은 중간 표 이다. 그 중에서 사용자 표 와 중간 표 의 관 계 는 한 쌍 이 많 고 캐릭터 표 와 중간 표 의 관계 도 한 쌍 이 많다. 다음 그림 과 같다.
4.3 실체 류 관계 구축 및 맵 설정
한 사용자 가 여러 개의 역할 을 가 질 수 있 기 때문에 사용자 실체 류 에 여러 개의 역할 의 정 보 를 포함해 야 한다. 코드 는 다음 과 같다.
/**
*
*/
@Entity
@Table(name="sys_user")
public class SysUser implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="user_id")
private Long userId;
@Column(name="user_code")
private String userCode;
@Column(name="user_name")
private String userName;
@Column(name="user_password")
private String userPassword;
@Column(name="user_state")
private String userState;
//
@ManyToMany(mappedBy="users")
private Set roles = new HashSet(0);
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUserCode() {
return userCode;
}
public void setUserCode(String userCode) {
this.userCode = userCode;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
public String getUserState() {
return userState;
}
public void setUserState(String userState) {
this.userState = userState;
}
public Set getRoles() {
return roles;
}
public void setRoles(Set roles) {
this.roles = roles;
}
@Override
public String toString() {
return "SysUser [userId=" + userId + ", userCode=" + userCode + ", userName=" + userName + ", userPassword="
+ userPassword + ", userState=" + userState + "]";
}
}
한 캐릭터 가 여러 사용자 에 게 부여 할 수 있 기 때문에 캐릭터 실체 류 에 여러 사용자 의 정 보 를 포함해 야 한다. 코드 는 다음 과 같다.
/**
*
*/
@Entity
@Table(name="sys_role")
public class SysRole implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="role_id")
private Long roleId;
@Column(name="role_name")
private String roleName;
@Column(name="role_memo")
private String roleMemo;
//
@ManyToMany
@JoinTable(name="user_role_rel",//
// user_role_rel sys_role role_id
joinColumns={@JoinColumn(name="role_id",referencedColumnName="role_id")},
// user_role_rel sys_user user_id
inverseJoinColumns={@JoinColumn(name="user_id",referencedColumnName="user_id")}
)
private Set users = new HashSet(0);
public Long getRoleId() {
return roleId;
}
public void setRoleId(Long roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleMemo() {
return roleMemo;
}
public void setRoleMemo(String roleMemo) {
this.roleMemo = roleMemo;
}
public Set getUsers() {
return users;
}
public void setUsers(Set users) {
this.users = users;
}
@Override
public String toString() {
return "SysRole [roleId=" + roleId + ", roleName=" + roleName + ", roleMemo=" + roleMemo + "]";
}
}
4.4 매 핑 의 주해 설명
@ManyToMany
:
:
cascade: 。
fetch: 。
targetEntity: 。 。
@JoinTable
:
:
nam:
joinColumns:
inverseJoinColumn:
@JoinColumn
: 。
:
name:
referencedColumnName:
unique: 。
nullable: 。 。
insertable: 。 。
updatable: 。 。
columnDefinition: 。
4.5 여러 쌍 의 조작
4.5.1 저장
@Autowired
private UserDao userDao;
@Autowired
private RoleDao roleDao;
/**
* :
*
* :
* 2 3
* 1 1 2 ( )
* 2 2 3 ( )
*
* :
* , , 。
* :
*
*/
@Test
@Transactional //
@Rollback(false)//
public void test1(){
//
SysUser u1 = new SysUser();
u1.setUserName(" 1");
SysRole r1 = new SysRole();
r1.setRoleName(" 1");
//
u1.getRoles().add(r1);
r1.getUsers().add(u1);
//
roleDao.save(r1);
userDao.save(u1);
}
다 중 (저장) 에서 쌍방 이 관 계 를 설정 하면 쌍방 이 모두 중간 표를 유지 하고 중간 표 에 데 이 터 를 삽입 하 는 것 을 의미 합 니 다. 중간 표 의 2 개의 필드 는 연합 메 인 키 이기 때문에 오 류 를 보고 하고 메 인 키 가 중복 되 며 저장 실패 문 제 를 해결 합 니 다. 어느 한 측 에서 중간 표 에 대한 유지 권 을 포기 하면 됩 니 다. 수 동적 인 측 에서 포기 하 는 것 을 추천 합 니 다. 설정 은 다음 과 같 습 니 다.
// ,
@ManyToMany(mappedBy="roles")
private Set users = new HashSet(0);
4.5.2 삭제
@Autowired
private UserDao userDao;
/**
*
* ,
*
* , ,
*/
@Test
@Transactional
@Rollback(false)//
public void testDelete() {
userDao.delete(1l);
}
5 Spring Data JPA 의 다 중 표 조회
5.1 대상 탐색 조회
대상 도 내 비게 이 션 검색 방식 은 이미 불 러 온 대상 에 따라 그의 관련 대상 으로 내 비게 이 션 하 는 것 이다.그것 은 클래스 와 클래스 간 의 관 계 를 이용 하여 대상 을 검색 한다.예 를 들 어 저 희 는 ID 조회 방식 을 통 해 고객 을 찾 을 수 있 습 니 다. Customer 류 의 getLinkmans () 방법 으로 이 고객 의 모든 연락 처 를 얻 을 수 있 습 니 다.대상 내 비게 이 션 조회 의 사용 요 구 는 두 대상 사이 에 반드시 관련 관계 가 있어 야 한 다 는 것 이다.
고객 을 조회 하여 이 고객 의 모든 연락 처 를 가 져 옵 니 다.
@Autowired
private CustomerDao customerDao;
@Test
// java , no session ,
@Transactional
public void testFind() {
Customer customer = customerDao.findOne(5l);
Set linkMans = customer.getLinkMans();//
for(LinkMan linkMan : linkMans) {
System.out.println(linkMan);
}
}
연락 처 를 조회 하여 이 연락처 의 모든 고객 을 가 져 옵 니 다.
@Autowired
private LinkManDao linkManDao;
@Test
public void testFind() {
LinkMan linkMan = linkManDao.findOne(4l);
Customer customer = linkMan.getCustomer(); //
System.out.println(customer);
}
대상 내 비게 이 션 조회 의 문제점 분석
문제 1: 우리 가 고객 을 조회 할 때 연락 처 를 조회 해 볼 까요?
분석: 만약 우리 가 조사 하지 않 는 다 면 사용 할 때 스스로 코드 를 쓰 고 방법 을 호출 하여 조회 해 야 한다.만약 우리 가 알 아 낸다 면, 사용 하지 않 을 때 또 서버 메모 리 를 헛되이 낭비 할 것 이다.
해결: 로드 지연 사상 을 사용 합 니 다.설정 을 통 해 우리 가 사용 해 야 할 때 진정한 조 회 를 시작 하도록 설정 합 니 다.
설정 방법:
/**
* @OneToMany fetch
* FetchType.EAGER :
* FetchType.LAZY :
*/
@OneToMany(mappedBy="customer",fetch=FetchType.EAGER)
private Set linkMans = new HashSet<>(0);
문제 2: 우리 가 연락 처 를 조회 할 때 고객 을 조회 해 낼 까요?
분석: 예 를 들 어 연락처 의 상세 한 정 보 를 조회 할 때 반드시 해당 연락처 의 소속 고객 을 볼 것 이다.만약 우리 가 조사 하지 않 는 다 면, 사용 할 때 는 스스로 코드 를 써 서 방법 을 호출 하여 조회 해 야 한다.만약 우리 가 알 아 낸다 면, 한 대상 은 너무 많은 메모 리 를 소모 하지 않 을 것 이다.그리고 대부분의 경우 우 리 는 사용 해 야 한다.
해결: 즉시 로드 하 는 사상 을 사용 합 니 다.설정 방식 을 통 해 표 의 실 체 를 조회 하면 메 인 표 의 실체 대상 을 동시에 찾 을 수 있 습 니 다.
구성 방식
/**
* @ManyToOne fetch
* FetchType.EAGER :
* FetchType.LAZY :
*/
@ManyToOne(targetEntity=Customer.class,fetch=FetchType.EAGER)
@JoinColumn(name="cst_lkm_id",referencedColumnName="cust_id")
private Customer customer;
5.2 Specification 조회 사용
/**
* Specification
*/
@Test
public void testFind() {
Specification spec = new Specification() {
public Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder cb) {
//Join , root
// , , (left,inner,right)
//JoinType.LEFT : ,JoinType.INNER: ,JoinType.RIGHT:
Join join = root.join("customer",JoinType.INNER);
return cb.like(join.get("custName").as(String.class)," 1");
}
};
List list = linkManDao.findAll(spec);
for (LinkMan linkMan : list) {
System.out.println(linkMan);
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[MeU] Hashtag 기능 개발➡️ 기존 Tag 테이블에 존재하지 않는 해시태그라면 Tag , tagPostMapping 테이블에 모두 추가 ➡️ 기존에 존재하는 해시태그라면, tagPostMapping 테이블에만 추가 이후에 개발할 태그 기반 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.