Life Developer
인생 개발자
Developer (136)
[JPA]프로젝션 - 어떻게 select를 할지

select 절에 조회할 대상을 지정하는 것을 프로젝션이라고 한다.

 

 

 

 

 

쿼리타입으로 조회

List<Member> members = em.createQuery("select m from Member m",
Member.class)
.getResultList();

for (Member member1 : members) {
System.out.println("member1 = " + member1.getAge());
}

 

 

 

Object[] 타입으로 조회

List resultList = em.createQuery("select m.age,m.username from Member m")
.getResultList();


Object o=resultList.get(0);
Object[] result=(Object[]) o
;
System.out.println("result = " + result[0]);
System.out.println("result = " + result[1]);

 

 

 

new 명령어로 조회

단순값을 원하는 대로 클래스 만들어서 DTO로 뽑는다.

ex)select new jpql.MemberDTD(m.username,m.age) from Member m

new 패키지명.클래스명(뽑을 대상들)~쿼리~

 

public class MemberDTD {
private String username;
private int age;

public MemberDTD(String username, int age) {
this.username = username;
this.age = age;
}

public MemberDTD() {
}

@Override
public String toString() {
return "MemberDTD{" +
"username='" + username + '\'' +
", age=" + age +
'}';
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

 

 

 

 

List<MemberDTD> members = em.createQuery("select new jpql.MemberDTD(m.username,m.age) from Member m",
MemberDTD.class)
.getResultList();

for (MemberDTD memberDTD : members) {
System.out.println("memberDTD = " + memberDTD);
}

'Developer' 카테고리의 다른 글

[JPA]JOIN  (0) 2020.09.21
[JPA]페이징  (0) 2020.09.21
[JPA]Native Query  (0) 2020.09.21
[JPA]QueryDSL - 동적쿼리 실무사용권장  (0) 2020.09.21
[JPA]Criteria  (0) 2020.09.21
  Comments,     Trackbacks
[JPA]Native Query

쌩 코드 날리기.


Member member = new Member();
member.setUserName("aaa");
em.persist(member);

List<Member> resultList = em.createNativeQuery("select member_id,city,street from member", Member.class).getResultList();
for (Member o : resultList) {
System.out.println("o = " + o.getId());
}

System.out.println(" ======================================================= ");
tx.commit(); //이시점에 DB 쿼리가 날라감

'Developer' 카테고리의 다른 글

[JPA]페이징  (0) 2020.09.21
[JPA]프로젝션 - 어떻게 select를 할지  (0) 2020.09.21
[JPA]QueryDSL - 동적쿼리 실무사용권장  (0) 2020.09.21
[JPA]Criteria  (0) 2020.09.21
[JPA]JPQL  (0) 2020.09.21
  Comments,     Trackbacks
[JPA]QueryDSL - 동적쿼리 실무사용권장

오픈소스가 있다. (사이트 있음)

 

동적쿼리 작성이 정말 편함.

 

단순하고 쉬움 (직관적)

 

실무사용 권장

'Developer' 카테고리의 다른 글

[JPA]프로젝션 - 어떻게 select를 할지  (0) 2020.09.21
[JPA]Native Query  (0) 2020.09.21
[JPA]Criteria  (0) 2020.09.21
[JPA]JPQL  (0) 2020.09.21
[JPA]테이블에 컬렉션을 저장한다-@ElementCollection,@CollectionTable  (1) 2020.09.20
  Comments,     Trackbacks
[JPA]Criteria

Criteria는 그냥 쿼리를 코드로 짜는 방법이다.

간단한것 같지만 엄청 어렵다..

실무에서 안쓰는 걸추천...

 

못알아봐서 유지보수가 어렵다.......

 

 

//Criteria 사용준비
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Member> query = cb.createQuery(Member.class);

//루트 클래스 (조회를 시작할 클래스)
Root<Member> m = query.from(Member.class);

//쿼리 생성
CriteriaQuery<Member> cq=query.select(m).where(cb.equal(m.get("userName"),"kim"));
List<Member> resultList = em.createQuery(cq).getResultList();

 

 

 

뭐 아래와 같은 식으로 동적쿼리도 짤수있다.

 

//Criteria 사용준비
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Member> query = cb.createQuery(Member.class);

//루트 클래스 (조회를 시작할 클래스)
Root<Member> m = query.from(Member.class);

//쿼리 생성
String username = "name";
CriteriaQuery<Member> cq = query.select(m);
if (username != null) {

cq = cq.where(cb.equal(m.get("userName"), "kim"));
}


List<Member> resultList = em.createQuery(cq).getResultList();

'Developer' 카테고리의 다른 글

[JPA]Native Query  (0) 2020.09.21
[JPA]QueryDSL - 동적쿼리 실무사용권장  (0) 2020.09.21
[JPA]JPQL  (0) 2020.09.21
[JPA]테이블에 컬렉션을 저장한다-@ElementCollection,@CollectionTable  (1) 2020.09.20
[JPA]@Embeddable 문제점  (0) 2020.09.20
  Comments,     Trackbacks
[JPA]JPQL

JPQL이란 테이블이 아닌 객체를 대상으로 검색하는 객체지향 쿼리다

 

 

ex)

List<Member> result = em.createQuery("select m from Member m where m.userName like '%kim%'",
Member.class).getResultList();
for (Member member : result) {
System.out.println("member = " + member);
}

 

 

 

===========================================================================

 

 

 

Member member = new Member();
member.setUsername("member1");
member.setAge(10);
em.persist(member);

TypedQuery<Member> query1 = em.createQuery("select m from Member m", Member.class);
TypedQuery<String> query2 = em.createQuery("select m.username from Member m",String.class);
Query query3 = em.createQuery("select m.username,m.age from Member m");

 

 

여러개 - getResultList()는 결과가 없어도 빈 리스트 가져옴

TypedQuery<Member> query1 = em.createQuery("select m from Member m", Member.class);
List<Member> resultList = query1.getResultList();

for (Member member1 : resultList) {
System.out.println("member1 = " + member1);
}

 

 

 

1개 - getSingleResult() 는 조심해야함. 정확하게 결과가 1개 나와야함

TypedQuery<Member> query1 = em.createQuery("select m from Member m where m.id=1", Member.class);
Member singleResult = query1.getSingleResult();
System.out.println("singleResult = " + singleResult.getUsername());

 

 

 

파라미터를 넘기기 - ' : ' 를 사용하고 체이닝기법을 사용하는게 깔끔하다.

Member member = new Member();
member.setUsername("member1");
member.setAge(10);
em.persist(member);

Member singleResult = em.createQuery("select m from Member m where m.username=:username", Member.class)
.setParameter("username", "member1").getSingleResult();
System.out.println("singleResult = " + singleResult.getAge());

 

 

 

 

  Comments,     Trackbacks
[JPA]테이블에 컬렉션을 저장한다-@ElementCollection,@CollectionTable

웬만하면 다 Entity 객체 타입이다.

 

값타입 컬렉션은 진짜 정말 단순한거 저장하거나 할때 사용. 추적 필요없을때 사용하는거임.

 

값타입은 식별자가 없어서 엔티티에 의존한다.

 

공유되더라도 불변객체로 만드는게 안전하다.

 

정말 값타입이라 판단될때 사용하자.

 

Entity로 만들어서 사용하는것을 권장한다.

 

 

 

 

 

FK가진놈이 주인이라고 생각하고 Entity연관관계매핑을 해왔는데 그것과 헷갈린다.

 

자동으로 테이블을 생성해준다.

@ElementCollection을 써주고 @CollectionTable에 테이블 정보를 입력하면 된다.

아 ㅡㅡ 머리 빠개지네

 

 

@ElementCollection
@CollectionTable(name = "FAVORITE_FOOD",joinColumns = @JoinColumn(name="MEMBER_ID"))
@Column(name="FOOD_NAME")
private Set<String> favoriteFoods = new HashSet<>();

@ElementCollection
@CollectionTable(name = "ADDRESS",joinColumns = @JoinColumn(name="MEMBER_ID"))
private List<Address> addressHistory = new ArrayList<>();

 

 

 

 

중요한것은 값타입 이기 때문에 member만 persist 해도 전부 쿼리 때려버린다.

 

Member member = new Member();
member.setUserName("member1");
member.setHomeAddress(new Address("homecity", "street", "12312"));

member.getFavoriteFoods().add("치킨");
member.getFavoriteFoods().add("스파게티");
member.getFavoriteFoods().add("족발");

member.getAddressHistory().add(new Address("old1", "street", "12312"));
member.getAddressHistory().add(new Address("old2", "street", "12312"));

em.persist(member);

System.out.println(" ================================== ");

 

 

 

 

========================================================================

 

그럼 이 컬렉션들은 지연로딩일까??

그렇다.

 

아래코드를 실행하면 일단 member만 select 때리고, address와 food 관련 정보를 건드리면 select가 나간다.ㅋ

LAZY가 기억이 나는군.

 

Member member = new Member();
member.setUserName("member1");
member.setHomeAddress(new Address("homecity", "street", "12312"));

member.getFavoriteFoods().add("치킨");
member.getFavoriteFoods().add("스파게티");
member.getFavoriteFoods().add("족발");

member.getAddressHistory().add(new Address("old1", "street", "12312"));
member.getAddressHistory().add(new Address("old2", "street", "12312"));

em.persist(member);

em.flush();
em.clear();

System.out.println(" =========================START============================= ");
Member findMember = em.find(Member.class, member.getId());

List<Address> addressHistory = findMember.getAddressHistory();
for (Address address : addressHistory) {
System.out.println("address.getCity() = " + address.getCity());
}

Set<String> favoriteFoods = findMember.getFavoriteFoods();
for (String favoriteFood : favoriteFoods) {
System.out.println("favoriteFood= " + favoriteFood);
}

System.out.println(" ======================================================= ");
tx.commit(); //이시점에 DB 쿼리가 날라감

 

보니까 LAZY군

 

'Developer' 카테고리의 다른 글

[JPA]Criteria  (0) 2020.09.21
[JPA]JPQL  (0) 2020.09.21
[JPA]@Embeddable 문제점  (0) 2020.09.20
[JPA]공통된거 묶기-@Embedded, @Embeddable  (0) 2020.09.20
[JPA]불쌍한 고아객체..  (0) 2020.09.20
  Comments,     Trackbacks
[JPA]@Embeddable 문제점

만약

 

@Embedded
private Address homeAddress;

@Embedded
@AttributeOverrides({@AttributeOverride(name = "city", column = @Column(name = "city2")), @AttributeOverride(name = "zipcode", column = @Column(name = "zipcode2")),
@AttributeOverride(name = "street", column = @Column(name = "street2"))})
private Address workAddress;

 

이렇게 member 코드를 짜고

 

Address address = new Address("city", "street", "zipcode");

Member member1 = new Member();
member1.setUserName("member1");
member1.setHomeAddress(address);

em.persist(member1);

Address mAddress = new Address(address.getCity(),address.getStreet(),address.getZipcode());

Member member2 = new Member();
member2.setUserName("member2");
member2.setHomeAddress(mAddress);

em.persist(member2);

mAddress.setCity("new City");

 

이렇게 main으로 실행하면 같은 클래스를 바라보고 있지만 각각 변경이 가능하다.

 

객체는 주소값으로 저장하기 때문에 아예 객체를 하나 더 만들어서 set을 해주면 된다.

 

이렇게 안하면 값이 동시에 변경될수 있다.

 

참조를 막을수 있는 방법이 없다.

 

그래서 객체타입을 수정하지 못하게 만드는 방법으로 사용할수 있다.

 

불변객체로 만든다는 것이다.

 

생성자로 생성하고 setter 메서드에 private를 쓰던지 아예 setter를 안만들면 된다.

  Comments,     Trackbacks
[JPA]공통된거 묶기-@Embedded, @Embeddable

사용전에 꼭 Equals와 hashcode 메서드를 만들어 동등성비교를 꼭 해야한다.

 

@Entity는 하지 않아 테이블로 생성하는게 아니다.

 

멤버에서 그룹짓고 싶은 놈들을 묶어 클래스에 다 짱박아두고 사용하는 전략.

 

사용법은 추가된 클래스에 @Embeddable을 입력,

그것을 쓸 Entity에 @Embedded를 입력해 멤버변수로 추가.

 

만약 똑같은 클래스를 사용하는 멤버변수를 선언하려면 아래처럼 @AttributeOverrides를 사용하여

컬럼명을 바꿔줘야함.

 

 

직접해보면

묶어서 클래스에 박아놓고,

 

@Embeddable
public class Address {
private String city;
private String street;
private String zipcode;

public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}

public Address() {
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

public String getStreet() {
return street;
}

public void setStreet(String street) {
this.street = street;
}

public String getZipcode() {
return zipcode;
}

public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
}

 

 

 

 

멤버에서 이렇게 추가해준다.

 

@Embedded
private Address homeAddress;

@Embedded
@AttributeOverrides({@AttributeOverride(name = "city", column = @Column(name = "city2"))@AttributeOverride(name = "zipcode", column = @Column(name = "zipcode2")),
@AttributeOverride(name = "street", column = @Column(name = "street2"))})
private Address workAddress;

  Comments,     Trackbacks