๐โโ๏ธ JPQL์ด๋,
์ํฐํฐ ๊ฐ์ฒด๋ฅผ ์ค์ฌ์ผ๋ก ๊ฐ๋ฐํ ์ ์๋ ๊ฐ์ฒด ์งํฅ ์ฟผ๋ฆฌ
- SQL๋ณด๋ค ๊ฐ๊ฒฐํ๋ฉฐ DBMS์ ์๊ด์์ด ๊ฐ๋ฐ์ด ๊ฐ๋ฅ
(๋ฐฉ์ธ์ ํตํด ํด๊ฒฐ๋๋ฉฐ ํด๋น DBMS์ ๋ง๋ SQL์ ์คํ. ํน์ DBMS์ ์์กด X)- JPQL์ find() ๋ฉ์๋๋ฅผ ํตํ ์กฐํ์ ๋ค๋ฅด๊ฒ ํญ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ SQL์ ์คํํด์ ๊ฒฐ๊ณผ๋ฅผ ์กฐํ
(์์์ฑ ์ปจํ ์คํธ์ ์ด๋ฏธ ์กด์ฌํ๋ฉด ๊ธฐ์กด ์ํฐํฐ๋ฅผ ๋ฐํํ๊ณ ์กฐํํ ๊ฒ์ ๋ฒ๋ฆผ)- JPQL์ ์ํฐํฐ ๊ฐ์ฒด๋ฅผ ๋์์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ์ง์ํ๊ณ SQL์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ์ ๋์์ผ๋ก ์ง์ํจ. ์ฆ, JPQL์ ๊ฒฐ๊ตญ SQL๋ก ๋ณํ๋จ
๐โ JPQL ์ฌ์ฉ ๋ฐฉ๋ฒ
- ์์ฑํ JPQL(๋ฌธ์์ด)์ em.createQuery ๋ฉ์๋๋ฅผ ํตํด ์ฟผ๋ฆฌ ๊ฐ์ฒด๋ก ๋ง๋ฌ. ์ฟผ๋ฆฌ ๊ฐ์ฒด๋ TypedQuery, Query๋ก ๋ ๊ฐ์ง๊ฐ ์กด์ฌ
-TypedQuery
: ๋ฐํํ ํ์ ์ ๋ช ํํ๊ฒ ์ง์ ํ๋ ๋ฐฉ์์ผ ๋ ์ฌ์ฉ(์ฟผ๋ฆฌ ๊ฐ์ฒด์ ๋ฉ์๋ ์คํ ๊ฒฐ๊ณผ๋ก ์ง์ ํ ํ์ ์ด ๋ฐํ๋จ)
-Query
: ๋ฐํํ ํ์ ์ ๋ช ํํ๊ฒ ์ง์ ํ ์ ์์ ๋ ์ฌ์ฉ(์ฟผ๋ฆฌ ๊ฐ์ฒด ๋ฉ์๋์ ์คํ ๊ฒฐ๊ณผ๋ก Object or Object[]์ด ๋ฐํ๋จ)- ์ฟผ๋ฆฌ ๊ฐ์ฒด์์ ์ ๊ณตํ๋ ๋ฉ์๋ getSingleResult() ๋๋ getResultList()๋ฅผ ํธ์ถํด์ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์กฐํ
-getSingleResult()
: ๊ฒฐ๊ณผ๊ฐ ์ ํํ ํ ํ์ผ ๊ฒฝ์ฐ ์ฌ์ฉ (์๊ฑฐ๋ ๋ง์ผ๋ฉด ์์ธ ๋ฐ์)
-getResultList()
: ๊ฒฐ๊ณผ๊ฐ 2ํ ์ด์์ผ ๊ฒฝ์ฐ ์ฌ์ฉํ๋ฉฐ ์ปฌ๋ ์ ์ ๋ฐํ (๊ฒฐ๊ณผ๊ฐ ์์ผ๋ฉด ๋น ์ปฌ๋ ์ ๋ฐํ)
createQuery()
getSingleResult()
@Test
public void TypedQuery๋ฅผ_์ด์ฉํ_๋จ์ผ๋ฉ๋ด_์กฐํ_ํ
์คํธ() {
// when
String jpql ="SELECT m.menuName FROM section01_menu AS m WHERE m.menuCode = 181";
TypedQuery<String> query = entityManager.createQuery(jpql, String.class);
String resultMenuName = query.getSingleResult();
// then
assertEquals("์ง์ฅ๋ฐ๋๋์ค๋ฌด๋", resultMenuName);
}
@Test
public void Query๋ฅผ_์ด์ฉํ_๋จ์ผ๋ฉ๋ด_์กฐํ_ํ
์คํธ() {
// when
String jpql ="SELECT m.menuName FROM section01_menu AS m WHERE m.menuCode = 181";
Query query = entityManager.createQuery(jpql); // ๊ฒฐ๊ณผ ๊ฐ์ ํ์
์ ๋ช
์ํ์ง ์์(์์ธก๋ถ๊ฐ์ด๊ธฐ ๋๋ฌธ)
Object resultMenuName = query.getSingleResult(); // ๊ฒฐ๊ณผ ๊ฐ์ Object๋ก ๋ฐํ ๋จ
// then
assertTrue(resultMenuName instanceof String); // String ํ์
์ ์ธ์คํด์ค์ธ์ง ํ์ธ
assertEquals("์ง์ฅ๋ฐ๋๋์ค๋ฌด๋", resultMenuName);
}
@Test
public void JPQL์_์ด์ฉํ_๋จ์ผํ_์กฐํ_ํ
์คํธ() {
// when
String jpql = "SELECT m FROM section01_menu AS m WHERE m.menuCode = 666";
TypedQuery<Menu> query = entityManager.createQuery(jpql, Menu.class); // ๋ฐํ ํ์
์ row์ ๋งคํํ ์ํฐํฐ ํ์
์ผ๋ก ์ค์
Menu foundMenu = query.getSingleResult();
// then
assertEquals(666, foundMenu.getMenuCode());
System.out.println(foundMenu);
}
๐ป Mini Console
Menu [menuCode=666, menuName=Owner์ฐ๋์งํฌ๋กํ, menuPrice=15000, categoryCode=4, orderableStatus=Y]
getResultList()
forEach()
@Test
public void TypedQuery๋ฅผ_์ด์ฉํ_์ฌ๋ฌํ_์กฐํ_ํ
์คํธ() {
// when
String jpql = "SELECT m FROM section01_menu AS m";
TypedQuery<Menu> query = entityManager.createQuery(jpql, Menu.class); // ๋ฐํ ํ์
์ row์ ๋งคํํ ์ํฐํฐ ํ์
์ผ๋ก ์ค์
List<Menu> foundMenuList = query.getResultList();
// then
assertNotNull(foundMenuList);
foundMenuList.forEach(System.out::println);
}
@Test
public void Query๋ฅผ_์ด์ฉํ_์ฌ๋ฌํ_์กฐํ_ํ
์คํธ() {
// when
String jpql = "SELECT m FROM section01_menu AS m";
Query query = entityManager.createQuery(jpql);
List<Menu> foundMenuList = query.getResultList(); // query๋ Object ํ์
์ด์ง๋ง, List<Menu>๋ก ๋ค์ด์บ์คํ
์์ผ์ ๊ทธ๋๋ก ๋ฐ๊ธฐ ๊ฐ๋ฅ
// then
assertNotNull(foundMenuList);
foundMenuList.forEach(System.out::println);
}
๐ป Mini Console
Menu [menuCode=61, menuName=์ง์ฅ๋ฐ๋๋์ค๋ฌด๋, menuPrice=20000, categoryCode=7, orderableStatus=Y]
Menu [menuCode=81, menuName=์น์ฆ๋ฅ์์ด์คํฌ๋ฆผ, menuPrice=7000, categoryCode=7, orderableStatus=Y]
Menu [menuCode=101, menuName=๋ฏธ๊ณต๊ฐ๊ณ์ ๋ฉ๋ด, menuPrice=10000, categoryCode=5, orderableStatus=Y]
...
@Test
public void distinct๋ฅผ_ํ์ฉํ_์ค๋ณต์ ๊ฑฐ_์ฌ๋ฌ_ํ_์กฐํ_ํ
์คํธ() {
// when
String jpql = "SELECT DISTINCT m.categoryCode FROM section01_menu AS m";
TypedQuery<Integer> query = entityManager.createQuery(jpql, Integer.class);
List<Integer> categoryCodeList = query.getResultList();
// then
assertNotNull(categoryCodeList);
categoryCodeList.forEach(System.out::println);
}
@Test
public void in_์ฐ์ฐ์๋ฅผ_ํ์ฉํ_์กฐํ_ํ
์คํธ() {
/* categoryCode๊ฐ 6, 10์ธ ๋ฉ๋ด ๋ชฉ๋ก ์กฐํ ์ถ๋ ฅ */
// when
String jpql = "SELECT m FROM section01_menu AS m WHERE m.categoryCode IN (6, 10)";
Query query = entityManager.createQuery(jpql);
List<Menu> menuList = query.getResultList();
// then
assertNotNull(menuList);
menuList.forEach(System.out::println);
}
@Test
public void like_์ฐ์ฐ์๋ฅผ_ํ์ฉํ_์กฐํ_ํ
์คํธ() {
/* ๋ง๋์ด ๋ค์ด๊ฐ๋ ๋ฉ๋ด๋ช
์ ๊ฐ์ง ๋ฉ๋ด ๋ชฉ๋ก ์กฐํ ์ถ๋ ฅ */
// when
String jpql = "SELECT m FROM section01_menu AS m WHERE menuName LIKE '%๋ง๋%'";
Query query = entityManager.createQuery(jpql);
List<Menu> menuList = query.getResultList();
// then
assertNotNull(menuList);
menuList.forEach(System.out::println);
}
setParameter()
๐โ ํ๋ผ๋ฏธํฐ ๋ฐ์ธ๋ฉ ํ๋ ๋ฐฉ๋ฒ
- ์ด๋ฆ ๊ธฐ์ค ํ๋ผ๋ฏธํฐ(named parameters)
:
๋ค์์ ์ด๋ฆ ๊ธฐ์ค ํ๋ผ๋ฏธํฐ๋ฅผ ์ง์ - ์์น ๊ธฐ์ค ํ๋ผ๋ฏธํฐ(positional parameters)
?
๋ค์์ ๊ฐ์ ์ฃผ๊ณ ์์น ๊ฐ์ 1๋ถํฐ ์์
@Test
public void ์ด๋ฆ_๊ธฐ์ค_ํ๋ผ๋ฏธํฐ_๋ฐ์ธ๋ฉ_๋ฉ๋ด_๋ชฉ๋ก_์กฐํ_ํ
์คํธ() {
// given
String menuNameParameter = "์น์ฆ๋ฅ์์ด์คํฌ๋ฆผ";
// when
String jpql = "SELECT m FROM section02_menu m WHERE m.menuName = :menuName";
List<Menu> menuList = entityManager.createQuery(jpql, Menu.class)
.setParameter("menuName", menuNameParameter) // jpql ์ฟผ๋ฆฌ๋ฌธ ์์ :menuName๊ณผ ๋์ผํ๊ฒ ์์ฑํด์ผํจ
.getResultList();
// then
assertNotNull(menuList);
menuList.forEach(System.out::println);
}
๐ป Mini Console
Menu [menuCode=81, menuName=์น์ฆ๋ฅ์์ด์คํฌ๋ฆผ, menuPrice=7000, categoryCode=7, orderableStatus=Y]
@Test
public void ์์น_๊ธฐ์ค_ํ๋ผ๋ฏธํฐ_๋ฐ์ธ๋ฉ_๋ฉ๋ด_๋ชฉ๋ก_์กฐํ_ํ
์คํธ() {
// given
String menuNameParameter = "์๋ณด์นด๋์ค๋ฌด๋";
// when
String jpql = "SELECT m FROM section02_menu m WHERE m.menuName = ?1";
List<Menu> menuList = entityManager.createQuery(jpql, Menu.class)
.setParameter(1, menuNameParameter) // jpql ์ฟผ๋ฆฌ๋ฌธ ์์ ?1์ ๋ค์ด๊ฐ ์์น ๋ฐ ๋ณ์ ์์ฑ
.getResultList();
// then
assertNotNull(menuList);
menuList.forEach(System.out::println);
}
๐ป Mini Console
Menu [menuCode=999, menuName=์๋ณด์นด๋์ค๋ฌด๋, menuPrice=20000, categoryCode=333, orderableStatus=Y]
๐โโ๏ธ Projection์ด๋,
SELECT ์ ์ ์กฐํํ ๋์์ ์ง์ ํ๋ ๊ฒ
(SELECT {ํ๋ก์ ์ ๋์} FROM)
๐โ ํ๋ก์ ์ ๋์์ ๋ฐฉ์
- ์ํฐํฐ ํ๋ก์ ์
- ์ํ๋ ๊ฐ์ฒด๋ฅผ ๋ฐ๋ก ์กฐํํ ์ ์์
- ์กฐํ๋ ์ํฐํฐ๋ '์์์ฑ ์ปจํ ์คํธ'๊ฐ ๊ด๋ฆฌ (์ํฐํฐ ํ๋ก์ ์ ๋ง!)
- ์๋ฒ ๋๋ ํ์ ํ๋ก์ ์
- ์ํฐํฐ์ ๊ฑฐ์ ๋น์ทํ๊ฒ ์ฌ์ฉ๋๋ฉฐ ์กฐํ์ ์์์ ์ด ๋ ์ ์์
=> from ์ ์ ์ฌ์ฉ ๋ถ๊ฐ- ์ฃผ๋ก ๋ง์ด ์ฌ์ฉํ๋ ์์๋ค๋ง์ ์กฐํํ ๋ ๋ง์ด ์ฌ์ฉ
- ์๋ฒ ๋๋ ํ์ ์ ์์์ฑ ์ปจํ ์คํธ์์ ๊ด๋ฆฌ๋์ง ์์
- ์ค์นผ๋ผ ํ์ ํ๋ก์ ์
- ์ซ์, ๋ฌธ์, ๋ ์ง ๊ฐ์ ๊ธฐ๋ณธ ๋ฐ์ดํฐ ํ์
- ์ค์นผ๋ผ ํ์ ์ ์์์ฑ ์ปจํ ์คํธ์์ ๊ด๋ฆฌ๋์ง ์์
- new ๋ช ๋ น์ด๋ฅผ ํ์ฉํ ํ๋ก์ ์
- ๋ค์ํ ์ข ๋ฅ์ ๋จ์ ๊ฐ๋ค์ DTO๋ก ๋ฐ๋ก ์กฐํํ๋ ๋ฐฉ์์ผ๋ก
new ํจํค์ง๋ช .DTO๋ช
์ ์ฐ๋ฉด ํด๋น DTO๋ก ๋ฐ๋ก ๋ฐํ๋ฐ์ ์ ์์- new ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ ํด๋์ค์ ๊ฐ์ฒด๋ ์ํฐํฐ๊ฐ ์๋๋ฏ๋ก ์์์ฑ ์ปจํ ์คํธ์์ ๊ด๋ฆฌ๋์ง ์์
@Test
public void ๋จ์ผ_์ํฐํฐ_ํ๋ก์ ์
_ํ
์คํธ() {
// when
String jpql = "SELECT m FROM section03_menu m";
List<Menu> menuList = entityManager.createQuery(jpql, Menu.class).getResultList();
// then
assertNotNull(menuList);
/* ์ํฐํฐ ํ๋ก์ ์
์ ์์์ฑ ์ปจํ
์คํธ์์ ๊ด๋ฆฌํ๋ ๊ฐ์ฒด๊ฐ ๋จ */
EntityTransaction tran = entityManager.getTransaction();
tran.begin();
menuList.get(1).setMenuName("test");
tran.commit();
}
/* BiDirectionCategory ์ํฐํฐ */
@Entity(name="section03_bidirection_category")
@Table(name="TBL_CATEGORY")
public class BiDirectionCategory {
@Id
@Column(name="CATEGORY_CODE")
private int categoryCode;
@Column(name="CATEGORY_NAME")
private String categoryName;
@Column(name="REF_CATEGORY_CODE")
private Integer refCategoryCode;
@OneToMany(mappedBy = "category")
private List<BiDirectionMenu> menuList;
/* ์์ฑ์, getter&setter, toString(๋ฐ๋์ menuList ์ถ๋ ฅ ๋ถ๋ถ์ ์ ๊ฑฐํ ๊ฒ) */
}
/* BiDirectionMenu ์ํฐํฐ */
@Entity(name="section03_bidirection_menu")
@Table(name="TBL_MENU")
public class BiDirectionMenu {
@Id
@Column(name="MENU_CODE")
private int menuCode;
@Column(name="MENU_NAME")
private String menuName;
@Column(name="MENU_PRICE")
private int menuPrice;
@ManyToOne
@JoinColumn(name="CATEGORY_CODE")
private BiDirectionCategory category;
@Column(name="ORDERABLE_STATUS")
private String orderableStatus;
/* ์์ฑ์, getter&setter, toString */
}
@Test
public void ์๋ฐฉํฅ_์ฐ๊ด๊ด๊ณ_์ํฐํฐ_ํ๋ก์ ์
_ํ
์คํธ() {
// given
int menuCodeParameter = 3;
// when
String jpql = "SELECT m.category FROM section03_bidirection_menu m WHERE m.menuCode = :menuCode";
BiDirectionCategory categoryOfMenu = entityManager.createQuery(jpql, BiDirectionCategory.class)
.setParameter("menuCode", menuCodeParameter)
.getSingleResult();
// then
assertNotNull(categoryOfMenu);
System.out.println(categoryOfMenu);
/* ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ์ ์๋ ์ํฐํฐ์ ๊ฒฝ์ฐ ์ญ๋ฐฉํฅ ๊ฐ์ฒด ๊ทธ๋ํ ํ์์ด ๊ฐ๋ฅ */
assertNotNull(categoryOfMenu.getMenuList());
categoryOfMenu.getMenuList().forEach(System.out::println);
}
๐ป Mini Console
BiDirectionMenu{menuCode=143, menuName='ํฌ๋ฆผ์น์ฆ๋ก', menuPrice=6000, category=BiDirectionCategory{categoryCode=10, categoryName='๊ธฐํ', refCategoryCode=2}, orderableStatus='Y'}
BiDirectionMenu{menuCode=2, menuName='์ฐ๋ญ๋ฝ์ด์ ค๋ฆฌ', menuPrice=5000, category=BiDirectionCategory{categoryCode=10, categoryName='๊ธฐํ', refCategoryCode=2}, orderableStatus='Y'}
...
@Embedded
@Embeddable
/* EmbeddedMenu ์ํฐํฐ */
@Entity(name="section03_embedded_menu")
@Table(name="TBL_MENU")
public class EmbeddedMenu {
@Id
@Column(name="MENU_CODE")
private int menuCode;
@Embedded // ๊ฐ ํ์
์ ์ฌ์ฉํ๋ ๊ณณ์ ์ ์
private MenuInfo menuInfo;
@Column(name="CATEGORY_CODE")
private int categoryCode;
@Column(name="ORDERABLE_STATUS")
private String orderableStatus;
/* ๊ธฐ๋ณธ ์
ํ
*/
}
/* MenuInfo ํด๋์ค */
/* ์๋ฒ ๋๋ ํ์
(embedded type, ๋ณตํฉ ๊ฐ ํ์
๋๋ ๋ด์ฅ ํ์
)
* ์๋ก์ด ๊ฐ ํ์
์ ์ง์ ์ ์ํ ๊ฒ์ผ๋ก ์ฃผ๋ก ๊ธฐ๋ณธ ๊ฐ ํ์
์ ๋ชจ์์ ๋ง๋ ํ๋์ ํ์
์ ๋งํจ.
* ์ํฐํฐ์ ํ๋ ์ค ์ผ๋ถ๋ถ์ ํ๋์ ์๋ฒ ๋๋ ํ์
์ผ๋ก ์ ์ํ๋ฉด ์์๋ณด๊ธฐ ์ฝ๊ณ , ์ฌ์ฌ์ฉ์ฑ์ด ๋๊ฒ ๋์์ธ ํ ์ ์์ด ์ ์ง๋ณด์์ ์ฉ์ด
* */
@Embeddable // ๊ฐ ํ์
์ ์ ์ํ๊ธฐ ์ํ ์ด๋
ธํ
์ด์
public class MenuInfo {
/* '๋ฉ๋ด๋ช
'๊ณผ '๊ฐ๊ฒฉ'์ด ๋ง์ด ์ฌ์ฉ๋๋ค๋ ๊ฐ์ ํ์ ์๋ฒ ๋๋ ํ์
์์ ์์ฑ */
@Column(name="MENU_NAME")
private String menuName;
@Column(name="MENU_PRICE")
private int menuPrice;
/* ๊ธฐ๋ณธ ์
ํ
*/
}
@Test
public void ์๋ฒ ๋๋_ํ์
_ํ๋ก์ ์
_ํ
์คํธ() {
// when
String jpql = "SELECT m.menuInfo FROM section03_embedded_menu m";
List<MenuInfo> menuInfoList = entityManager.createQuery(jpql, MenuInfo.class).getResultList();
// then
assertNotNull(menuInfoList);
menuInfoList.forEach(System.out::println);
}
๐ป Mini Console
MenuInfo [menuName=JPA์ฐ ์งฌ๋ฝ๋ง ๋ง๊ฑธ๋ฆฌ, menuPrice=15000]
MenuInfo [menuName=์๋ณด์นด๋์ค๋ฌด๋, menuPrice=20000]
MenuInfo [menuName=์ง์ฅ๋ฐ๋๋์ค๋ฌด๋, menuPrice=20000]
MenuInfo [menuName=์น์ฆ๋ฅ์์ด์คํฌ๋ฆผ, menuPrice=7000]
...
@Test
public void TypedQuery๋ฅผ_์ด์ฉํ_์ค์นผ๋ผ_ํ์
_ํ๋ก์ ์
_ํ
์คํธ() {
// when
String jpql = "SELECT c.categoryName FROM section03_category c";
List<String> categoryNameList = entityManager.createQuery(jpql, String.class).getResultList();
// then
assertNotNull(categoryNameList);
categoryNameList.forEach(System.out::println);
}
/* ์กฐํํ๋ ค๋ ์ปฌ๋ผ ๊ฐ์ด 1๊ฐ์ธ ๊ฒฝ์ฐ TypeQuery๋ก ๋ฐํ ํ์
์ ๋จ์ผ ๊ฐ์ ๋ํด ์ง์ ํ ์ ์์ง๋ง ๋ค์ค ์ด ์ปฌ๋ผ์ ์กฐํํ๋ ๊ฒฝ์ฐ ํ์
์ ์ง์ ํ์ง ๋ชป ํจ
* ๊ทธ๋๋ TypedQuery ๋์ Query๋ฅผ ์ฌ์ฉํ์ฌ Object[]๋ก ํ์ ์ ๋ณด๋ฅผ ๋ฐํ ๋ฐ์ ์ฌ์ฉ
* */
@Test
public void Query๋ฅผ_์ด์ฉํ_์ค์นผ๋ผ_ํ์
_ํ๋ก์ ์
_ํ
์คํธ() {
// when
String jpql = "SELECT c.categoryCode, c.categoryName FROM section03_category c";
List<Object[]> categoryList = entityManager.createQuery(jpql).getResultList();
// then
/* row : forEach๋ฅผ ์ฌ์ฉ ์, Object[]์ ํ ํ์ฉ ์ถ๋ ฅ์ด ๋๋ฏ๋ก ๊ทธ๊ฒ(row)์ for๋ฌธ์ผ๋ก ๋ค์ column ๊น์ง ์ถ๋ ฅ */
assertNotNull(categoryList);
categoryList.forEach(row -> {
for(Object column : row)
System.out.print(column + " ");
});
}
/* Object๋ฅผ ์ผ์ผํ ์ธ๋ฑ์ค๋ณ๋ก ์ฒ๋ฆฌํ๊ฑฐ๋ ๋ค์ด์บ์คํ
ํ๋ ๊ฒ์ ๋ฒ๊ฑฐ๋กญ๊ธฐ ๋๋ฌธ์ new ๋ช
๋ น์ด๋ฅผ ํ์ฉํ ํ๋ก์ ์
์ ๋ ๋ง์ด ํ์ฉ */
๐ป Mini Console
1 ์์ฌ 2 ์๋ฃ 3 ๋์ ํธ 4 ํ์ 5 ์ค์ 6 ์ผ์ 7 ํจ์ ...
/* CategoryInfo ํด๋์ค */
/* ์ด ํด๋์ค๋ ์ํฐํฐ๋ก ์ค์ ํ์ง ์์
* ๋ค๋ง ์ฌ๋ฌ ์ปฌ๋ผ ์ ๋ณด๋ฅผ ์๋ฏธ ์๋ ๋จ์๋ก ๋ฌถ๊ธฐ ์ํ ์ฉ๋์ ํด๋์ค ('4. new ๋ช
๋ น์ด๋ฅผ ํ์ฉํ ํ๋ก์ ์
'์ ์ฌ์ฉ๋จ) */
public class CategoryInfo {
private int categoryCode;
private String categoryName;
/* ๊ธฐ๋ณธ ์
ํ
*/
}
@Test
public void new_๋ช
๋ น์ด๋ฅผ_ํ์ฉํ_ํ๋ก์ ์
_ํ
์คํธ() {
// when
/* CategoryInfo ํด๋์ค์ ๋งค๊ฐ๋ณ์ ์์ฑ์๋ฅผ ํธ์ถํด์ ํด๋น ๊ฐ์ผ๋ก ๋ฐํ๋ฐ์
* (FROM ์ ์ ํด๋น ์ปฌ๋ผ์ด ์ค์ ๋ก ์กด์ฌํ๋ ์ํฐํฐ๋ช
์ ์์ฑ) */
String jpql = "SELECT new com.greedy.section03.projection.CategoryInfo(c.categoryCode, c.categoryName) FROM section03_category c";
List<CategoryInfo> categoryInfoList = entityManager.createQuery(jpql, CategoryInfo.class).getResultList();
// then
assertNotNull(categoryInfoList);
categoryInfoList.forEach(System.out::println);
}
๐ป Mini Console
CategoryInfo [categoryCode=1, categoryName=์์ฌ]
CategoryInfo [categoryCode=2, categoryName=์๋ฃ]
CategoryInfo [categoryCode=3, categoryName=๋์ ํธ]
...
setFirstResult()
setMaxResults()
@Test
public void ํ์ด์ง_API๋ฅผ_์ด์ฉํ_์กฐํ_ํ
์คํธ() {
// given
int offset = 15; // ์กฐํ๋ฅผ ๊ฑด๋ ๋ธ ํ์ ์ (limit์ด 5๋ผ๋ ๊ฐ์ ํ์, 0์ด๋ฉด ์ฒซ ํ์ด์ง, 5๋ฉด ๋ ๋ฒ์งธ ํ์ด์ง)
int limit = 5; // ์กฐํํ ํ์ ์
// when
String jpql = "SELECT m FROM section04_menu m ORDER BY m.menuCode DESC";
/* ์ฟผ๋ฆฌ ์คํ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด offset๊ณผ limit์ ํ์ฉํ๋ ๋ฌธ๋ฒ์ผ๋ก ์คํ๋์ด ์๋๋ฐ, ์ด๋ ์ค๋ผํด 12๋ฒ์ ์ดํ ์ถ๊ฐ๋ ๋ฌธ๋ฒ
* ์ค๋ผํด 11์ดํ ๋ฒ์ ์์๋ rownum์ ์ด์ฉํ ์ธ๋ผ์ธ๋ทฐ ๋ฐฉ์์ผ๋ก ์ฟผ๋ฆฌ๊ฐ ๋์ */
/* TypedQuery์ offset๊ณผ limit์ set ํ๊ธฐ */
List<Menu> menuList = entityManager.createQuery(jpql, Menu.class)
.setFirstResult(offset) // ์กฐํ๋ฅผ ์์ํ ์์น(0๋ถํฐ ์์)
.setMaxResults(limit) // ์กฐํํ ๋ฐ์ดํฐ์ ์
.getResultList();
// then
assertNotNull(menuList);
menuList.forEach(System.out::println);
}
๐ป Mini Console
Menu [menuCode=101, menuName=๋ฏธ๊ณต๊ฐ๊ณ์ ๋ฉ๋ด, menuPrice=10000, categoryCode=5, orderableStatus=Y]
Menu [menuCode=81, menuName=์น์ฆ๋ฅ์์ด์คํฌ๋ฆผ, menuPrice=7000, categoryCode=7, orderableStatus=Y]
Menu [menuCode=61, menuName=์ง์ฅ๋ฐ๋๋์ค๋ฌด๋, menuPrice=20000, categoryCode=7, orderableStatus=Y]
Menu [menuCode=21, menuName=๋๋ฏธ๋๋ฆฌ๋ฐฑ์ค๊ธฐ, menuPrice=5000, categoryCode=11, orderableStatus=Y]
Menu [menuCode=20, menuName=๋ง๋ผ๊น์ผํ๋ผ๋ด, menuPrice=22000, categoryCode=5, orderableStatus=Y]
๐โ JPQL์ ๊ทธ๋ฃนํจ์(COUNT, MAX, MIN, SUM, AVG) ์ฌ์ฉ ์ ์ฃผ์์ฌํญ
- ๊ทธ๋ฃนํจ์์ ๋ฐํ ํ์ ์ ๊ฒฐ๊ณผ ๊ฐ์ด ์ ์๋ฉด Long, ์ค์๋ฉด Double๋ก ๋ฐํ๋จ
- ๊ฐ์ด ์๋ ์ํ์์ count๋ฅผ ์ ์ธํ ๊ทธ๋ฃน ํจ์๋ null์ด ๋๊ณ count๋ง 0์ด ๋จ
๋ฐ๋ผ์ ๋ฐํ ๊ฐ์ ๋ด๊ธฐ ์ํด ์ ์ธํ๋ ๋ณ์ ํ์ ์ ๊ธฐ๋ณธ ์๋ฃํ์ผ๋ก ํ๊ฒ ๋๋ฉด, ์กฐํ ๊ฒฐ๊ณผ๋ฅผ ์ธ๋ฐ์ฑ ํ ๋ NPE๊ฐ ๋ฐ์ (Wrapper ํด๋์ค๋ก ๋ณ๊ฒฝํ ๊ฒ)- ๊ทธ๋ฃน ํจ์์ ๋ฐํ ์๋ฃํ์ Long or Doubleํ์ด๊ธฐ ๋๋ฌธ์ Having์ ์์ ๊ทธ๋ฃน ํจ์ ๊ฒฐ๊ณผ ๊ฐ๊ณผ ๋น๊ตํ๊ธฐ ์ํ ํ๋ผ๋ฏธํฐ ํ์ ์ Long or Double๋ก ํด์ผํจ
@Test
public void ํน์ _์นดํ
๊ณ ๋ฆฌ์_๋ฑ๋ก๋_๋ฉ๋ด_์_์กฐํ() {
// given
int categoryCodeParameter = 4;
// when
String jpql = "SELECT COUNT(m.menuPrice) FROM section05_menu m WHERE m.categoryCode = :categoryCode";
long countOfMenu = entityManager.createQuery(jpql, Long.class) /* ๋ฐํ๊ฐ์ ์ ์์ผํ
๋ Long */
.setParameter("categoryCode", categoryCodeParameter)
.getSingleResult();
// then
assertTrue(countOfMenu >= 0);
System.out.println(countOfMenu); /* ์๋ ์นดํ
๊ณ ๋ฆฌ๋ฅผ ์
๋ ฅํด๋ 0 ์ถ๋ ฅ (NPE ๋ฐ์ X) */
}
assertThrows()
assertDoesNotThrow()
@Test
public void count๋ฅผ_์ ์ธํ_๋ค๋ฅธ_๊ทธ๋ฃนํจ์์_์กฐํ๊ฒฐ๊ณผ๊ฐ_์๋_๊ฒฝ์ฐ_ํ
์คํธ() {
// given
int categoryCodeParameter = 2;
// when
String jpql = "SELECT SUM(m.menuPrice) FROM section05_menu m WHERE m.categoryCode = :categoryCode";
// then
/* NPE๊ฐ ๋ฐ์ํ๋ค๊ณ ์์ */
assertThrows(NullPointerException.class, () -> {
/* ๋ฐํ ๊ฐ์ ๋ด์ ๋ณ์์ ํ์
์ ๊ธฐ๋ณธ ์๋ฃํ์ผ๋ก ํ๋ ๊ฒฝ์ฐ Wrapper ํ์
์ ์ธ๋ฐ์ฑ ํ๋ ๊ณผ์ ์์ NPE๊ฐ ๋ฐ์ํ๊ฒ ๋จ */
long sumOfPrice = entityManager.createQuery(jpql, Long.class)
.setParameter("categoryCode", categoryCodeParameter)
.getSingleResult();
});
/* NPE๊ฐ ๋ฐ์ํ์ง์์์ ์์ */
assertDoesNotThrow(() -> {
/* ๋ฐํ ๊ฐ์ ๋ด๋ ๋ณ์๋ฅผ Wrapper ํ์
์ผ๋ก ์ ์ธํด์ผ null ๊ฐ์ด ๋ฐํ ๋์ด๋ NPE๊ฐ ๋ฐ์ํ์ง ์์ */
Long sumOfPrice = entityManager.createQuery(jpql, Long.class)
.setParameter("categoryCode", categoryCodeParameter)
.getSingleResult();
});
}
@Test
public void groupby์ ๊ณผ_having์ ์_์ฌ์ฉํ_์กฐํ_ํ
์คํธ() {
// given
long minPrice = 50000L; // ๊ทธ๋ฃน ํจ์์ ๋ฐํ ํ์
์ Long์ด๋ฏ๋ก ๋น๊ต๋ฅผ ์ํ ํ๋ผ๋ฏธํฐ๋ Long ํ์
์ ์ฌ์ฉํด์ผํจ
// when
String jpql = "SELECT m.categoryCode, SUM(m.menuPrice) "
+ " FROM section05_menu m "
+ " GROUP BY m.categoryCode "
+ " HAVING SUM(m.menuPrice) >= :minPrice";
List<Object[]> sumPriceOfCategoryList = entityManager.createQuery(jpql, Object[].class)
.setParameter("minPrice", minPrice)
.getResultList();
// then
assertNotNull(sumPriceOfCategoryList);
sumPriceOfCategoryList.forEach(row -> {
for(Object column : row) System.out.print(column + " ");
});
}
๐ป Mini Console
6 64000 7 77000 10 54000 4 80000
๐โ JOIN์ ์ข ๋ฅ
- ์ผ๋ฐ JOIN : ์ผ๋ฐ์ ์ธ SQL ์กฐ์ธ์ ์๋ฏธ(๋ด๋ถ ์กฐ์ธ, ์ธ๋ถ ์กฐ์ธ, ์ปฌ๋ ์ ์กฐ์ธ, ์ธํ ์กฐ์ธ)
- ํ์น JOIN : JPQL์์ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํด ์ ๊ณตํ๋ ๊ธฐ๋ฅ์ผ๋ก ์ฐ๊ด ๋ ์ํฐํฐ๋ ์ปฌ๋ ์ ์ ํ ๋ฒ์ ์กฐํ ๊ฐ๋ฅ
- ์ง์ฐ ๋ก๋ฉ์ด ์๋ ์ฆ์ ๋ก๋ฉ์ ์ํํ๋ฉฐJOIN FETCH
๋ช ๋ น์ด๋ฅผ ์ฌ์ฉ
/* Category ์ํฐํฐ */
@Entity(name="section06_category")
@Table(name="TBL_CATEGORY")
public class Category {
@Id
@Column(name="CATEGORY_CODE")
private int categoryCode;
@Column(name="CATEGORY_NAME")
private String categoryName;
@Column(name="REF_CATEGORY_CODE")
private Integer refCategoryCode;
@OneToMany(mappedBy = "category")
private List<Menu> menuList;
/* ์์ฑ์, getter&setter, toString(๋ฐ๋์ menuList ์ถ๋ ฅ ๋ถ๋ถ์ ์ ๊ฑฐํ ๊ฒ) */
}
/* Menu ์ํฐํฐ */
@Entity(name="section06_menu")
@Table(name="TBL_MENU")
public class Menu {
@Id
@Column(name="MENU_CODE")
private int menuCode;
@Column(name="MENU_NAME")
private String menuName;
@Column(name="MENU_PRICE")
private int menuPrice;
@ManyToOne
@JoinColumn(name="CATEGORY_CODE")
private Category category;
@Column(name="ORDERABLE_STATUS")
private String orderableStatus;
/* ์์ฑ์, getter&setter, toString(๋ฐ๋์ menuList ์ถ๋ ฅ ๋ถ๋ถ์ ์ ๊ฑฐํ ๊ฒ) */
}
@Test
public void ๋ด๋ถ์กฐ์ธ์_์ด์ฉํ_์กฐํ_ํ
์คํธ() {
/* Menu ์ํฐํฐ์ ๋ํ ์กฐํ๋ง ์ผ์ด๋๊ณ Category ์ํฐํฐ์ ๋ํ ์กฐํ๋ ๋์ค์ ํ์ํ ๋ ์ผ์ด๋จ
* select์ ๋์์ ์์ํํ์ฌ ๊ฐ์ ธ์ค์ง๋ง join์ ๋์์ ์์ํํ์ฌ ๊ฐ์ ธ์ค์ง ์์ */
// when
String jpql = "SELECT m FROM section06_menu m JOIN m.category c";
List<Menu> menuList = entityManager.createQuery(jpql, Menu.class).getResultList();
// then
assertNotNull(menuList);
menuList.forEach(System.out::println);
}
@Test
public void ์ธ๋ถ์กฐ์ธ์_์ด์ฉํ_์กฐํ_ํ
์คํธ() {
// when
String jpql = "SELECT m.menuName, c.categoryName"
+ " FROM section06_menu m"
+ " RIGHT JOIN m.category c"
+ " ORDER BY m.category.categoryCode"; /* category ํ๋์ categoryCode๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ๊ฐ๋ฅ */
List<Object[]> menuList = entityManager.createQuery(jpql, Object[].class).getResultList();
// then
assertNotNull(menuList);
menuList.forEach(row -> {
Stream.of(row).forEach(col -> System.out.print("[" + col + "]")); /* Object ๋ฐฐ์ด(row)์ ์คํธ๋ฆผ์ผ๋ก ๋ง๋ค๊ณ forEach๋ก ์ฒ๋ฆฌ */
System.out.println(); /* ํ๋์ ํ์ด ์ถ๋ ฅ๋๋ฉด ๊ฐํ */
});
}
๐ป Mini Console
[JPA์ฐ ์งฌ๋ฝ๋ง ๋ง๊ฑธ๋ฆฌ][ํจ์ ]
[์ง์ฅ๋ฐ๋๋์ค๋ฌด๋][ํจ์ ]
[์น์ฆ๋ฅ์์ด์คํฌ๋ฆผ][ํจ์ ]
[์ํผ์ค์ด๋ผ๋ผ][์ปคํผ]
...
@Test
public void ์ปฌ๋ ์
์กฐ์ธ์_์ด์ฉํ_์กฐํ_ํ
์คํธ() {
/* ์ปฌ๋ ์
์กฐ์ธ์ ์๋ฏธ์ ๋ถ๋ฅ ๋ ๊ฒ์ผ๋ก ์ปฌ๋ ์
์ ์ง๋๊ณ ์๋ ์ํฐํฐ๋ฅผ ๊ธฐ์ค์ผ๋ก ์กฐ์ธํ๋ ๊ฒ์ ๋งํจ */
// when
String jpql = "SELECT c.categoryName, m.menuName"
+ " FROM section06_category c"
+ " LEFT JOIN c.menuList m"; /* category ์ํฐํฐ์ menuList๋ผ๋ ์ปฌ๋ ์
์ ์กฐ์ธ */
List<Object[]> categoryList = entityManager.createQuery(jpql, Object[].class).getResultList();
// then
assertNotNull(categoryList);
categoryList.forEach(row -> {
Stream.of(row).forEach(col -> System.out.print("[" + col + "]")); /* Object ๋ฐฐ์ด(row)์ ์คํธ๋ฆผ์ผ๋ก ๋ง๋ค๊ณ forEach๋ก ์ฒ๋ฆฌ */
System.out.println(); /* ํ๋์ ํ์ด ์ถ๋ ฅ๋๋ฉด ๊ฐํ */
});
}
๐ป Mini Console
[ํจ์ ][JPA์ฐ ์งฌ๋ฝ๋ง ๋ง๊ฑธ๋ฆฌ]
[์ง์คํด][์๋ณด์นด๋์ค๋ฌด๋]
[ํจ์ ][์ง์ฅ๋ฐ๋๋์ค๋ฌด๋]
[ํจ์ ][์น์ฆ๋ฅ์์ด์คํฌ๋ฆผ]
@Test
public void ์ธํ์กฐ์ธ์_์ด์ฉํ_์กฐํ_ํ
์คํธ() {
/* ์ธํ ์กฐ์ธ์ ์กฐ์ธ๋๋ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๋ค ๋ฐํํ๋ ํฌ๋ก์ค ์กฐ์ธ๊ณผ ๊ฐ์
* FROM ์ ์ ์ํฐํฐ๋ฅผ ๋์ดํ๋ ๋ฐฉ์์ผ๋ก ํฌ๋ก์ค ์กฐ์ธ ์ฌ์ฉ ๊ฐ๋ฅ
* */
// when
String jpql = "SELECT c.categoryName, m.menuName"
+ " FROM section06_category c, section06_menu m"; /* FROM ์ ์ ๋ ์ํฐํฐ ๋ชจ๋ ์์ฑ */
List<Object[]> categoryList = entityManager.createQuery(jpql, Object[].class).getResultList();
// then
assertNotNull(categoryList);
categoryList.forEach(row -> {
Stream.of(row).forEach(col -> System.out.print("[" + col + "]")); /* Object ๋ฐฐ์ด(row)์ ์คํธ๋ฆผ์ผ๋ก ๋ง๋ค๊ณ forEach๋ก ์ฒ๋ฆฌ */
System.out.println(); /* ํ๋์ ํ์ด ์ถ๋ ฅ๋๋ฉด ๊ฐํ */
});
}
@Test
public void ํ์น์กฐ์ธ์_์ด์ฉํ_์กฐํ_ํ
์คํธ() {
/* ํ์น ์กฐ์ธ์ ํ๋ฉด ์ฒ์ SQL ์คํ ํ ๋ก๋ฉํ ๋ ์กฐ์ธ ๊ฒฐ๊ณผ๋ฅผ ๋ค ์กฐํํ ๋ค์ ์ฌ์ฉํ๋ ๋ฐฉ์์ด๊ธฐ ๋๋ฌธ์ ์ฟผ๋ฆฌ ์คํ ํ์๊ฐ ์ค์ด๋ค๊ฒ ๋จ
* ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ฑ๋ฅ ํฅ์ !
* */
// when
String jpql = "SELECT m FROM section06_menu m JOIN FETCH m.category c"; /* JOIN ๋ค์ FETCH ์ถ๊ฐ */
List<Menu> menuList = entityManager.createQuery(jpql, Menu.class).getResultList();
// then
assertNotNull(menuList);
menuList.forEach(System.out::println);
/* ๊ฒ์ ์กฐ๊ฑด(where์ )์์๋ง ์ฌ์ฉํ๋ค๋ฉด ๊ตณ์ด FETCH ์กฐ์ธ์ ์ฌ์ฉํ ํ์์์
* ํ์ง๋ง select์ ์์ ์กฐํํ ์ปฌ๋ผ์ด๋ผ๋ฉด FETCH ์กฐ์ธ์ ์ฌ์ฉํ์ฌ SELECT๋ฌธ ์ฒซ ์คํ ์, ํ๊บผ๋ฒ์ ์กฐํํด์ฌ ์ ์๋๋ก ํ์ฌ
* ์ฑ๋ฅ๋ฉด์์ ํจ์จ์ ์ผ ์ ์๋๋ก ํจ (์ฆ, ๋ชฉ์ ์ ๋ฐ๋ผ FETCH๊ฐ ํจ์จ์ ์ผ ์ ์์ง๋ง ํญ์์ ์๋) */
}
๐โโ๏ธ JPQL๋ SQL์ฒ๋ผ ์๋ธ ์ฟผ๋ฆฌ๋ฅผ ์ง์ํ์ง๋ง select, from ์ ์์๋ ์ฌ์ฉํ ์ ์๊ณ where, having์ ์์๋ง ์ฌ์ฉ ๊ฐ๋ฅ
@Test
public void ์๋ธ์ฟผ๋ฆฌ๋ฅผ_์ด์ฉํ_๋ฉ๋ด_์กฐํ_ํ
์คํธ() {
// given
String categoryNameParameter = "ํ์";
// when
String jpql = "SELECT m "
+ "FROM section07_menu m "
+ "WHERE m.categoryCode = (SELECT c.categoryCode "
+ "FROM section07_category c "
+ "WHERE c.categoryName = :categoryName)";
List<Menu> menuList = entityManager.createQuery(jpql, Menu.class)
.setParameter("categoryName", categoryNameParameter)
.getResultList();
// then
assertNotNull(menuList);
menuList.forEach(System.out::println);
}
๐โ ๋์ ์ฟผ๋ฆฌ? ์ ์ ์ฟผ๋ฆฌ?
- ๋์ ์ฟผ๋ฆฌ : ํ์ฌ ์ฌ์ฉ ์ค์ธ ๋ฐฉ์์ฒ๋ผ EntityManager๊ฐ ์ ๊ณตํ๋ ๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ JPQL์ ๋ฌธ์์ด๋ก ๋ฐํ์ ์์ ์ ๋์ ์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ๋ง๋๋ ๋ฐฉ์
(๋์ ์ผ๋ก ๋ง๋ค์ด์ง ์ฟผ๋ฆฌ๋ฅผ ์ํ ์กฐ๊ฑด์์ด๋ ๋ฐ๋ณต๋ฌธ์ ์๋ฐ ์ฝ๋๋ฅผ ์ด์ฉํ ์ ์์)- ์ ์ ์ฟผ๋ฆฌ : ๋ฏธ๋ฆฌ ์ฟผ๋ฆฌ๋ฅผ ์ ์ํ๊ณ ๋ณ๊ฒฝํ์ง ์๊ณ ์ฌ์ฉํ๋ ์ฟผ๋ฆฌ๋ฅผ ๋งํ๋ฉฐ ๋ฏธ๋ฆฌ ์ ์ํ ์ฝ๋๋ ์ด๋ฆ์ ๋ถ์ฌํด์ ์ฌ์ฉํ๊ฒ ๋จ
์ด๋ฅผ NamedQuery๋ผ๊ณ ํจ.์ด๋ ธํ ์ด์ ๋ฐฉ์
๊ณผxml ๋ฐฉ์
๋ ๊ฐ์ง๊ฐ ์๋๋ฐ ์ฟผ๋ฆฌ๊ฐ ๋ณต์กํ ์๋ก xml ๋ฐฉ์์ด ์ ํธ๋จ.
๐โ ๋์ SQL์ ์์ฑํ๊ธฐ์ JPQL์ ๋ง์ด ์ด๋ ค์. ์ปดํ์ผ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ด ์๋๊ธฐ ๋๋ฌธ์ ์ฟผ๋ฆฌ๋ฅผ ๋งค๋ฒ ์คํํด์ ํ์ธํด์ผํ๋ ๋ถํธํจ์ด ์์
Criteria
๋queryDSL
์ ํ์ฉํ๋ฉด ๋ณด๋ค ํธ๋ฆฌํ๊ฒ ์์ฑํ ์ ์์ผ๋ฉฐ, ์ฟผ๋ฆฌ ์์ฑ ์ ์ปดํ์ผ ์๋ฌ๋ก ์๋ชป ๋ ๋ถ๋ถ์ ํ์ธํ ์ ์์ด ์์ฑํ๊ธฐ๋ ํธํจ
๋ง์ด๋ฐํฐ์ค๋ฅผ ํผ์ฉํ๊ฑฐ๋ ๋ง์ด๋ฐํฐ์ค์ ๊ตฌ๋ฌธ ๋น๋ API๋ฅผ ํ์ฉํด๋ ์ข์
@Test
public void ๋์ ์ฟผ๋ฆฌ๋ฅผ_์ด์ฉํ_์กฐํ_ํ
์คํธ() {
// given
/* Menu ํ
์ด๋ธ์ ์๋ ๋ชจ๋ ๊ฐ ๊ฐ์ ธ์ด */
// String searchName = "";
// int searchCategoryCode = 0;
/* ์นดํ
๊ณ ๋ฆฌ ์๊ด์์ด ์น์ฆ๊ฐ ํฌํจ๋ ๋ชจ๋ ๋ฉ๋ด ๊ฐ์ ธ์ด */
// String searchName = "์น์ฆ";
// int searchCategoryCode = 0;
/* 7๋ฒ ์นดํ
๊ณ ๋ฆฌ์ ์น์ฆ๊ฐ ํฌํจ๋ ๋ฉ๋ด๋ค ๊ฐ์ ธ์ด */
String searchName = "์น์ฆ";
int searchCategoryCode = 7;
// when
StringBuilder jpql = new StringBuilder("SELECT m FROM section08_menu m "); /* ์ด ๊ฐ์ผ๋ก ์ด๊ธฐํ ํด๋๊ณ ๋ค๋ฅธ ๊ตฌ๋ฌธ๋ค์ appendํ ๊ฒ */
if(searchName != null && !searchName.isEmpty() && searchCategoryCode > 0) {
jpql.append("WHERE ");
jpql.append("m.menuName LIKE '%' || :menuName || '%' ");
jpql.append("AND ");
jpql.append("m.categoryCode = :categoryCode ");
} else {
/* ๋ ์ค์ ํ๋๋ง ์์ ๊ฒฝ์ฐ */
if(searchName != null && !searchName.isEmpty()) {
jpql.append("WHERE ");
jpql.append("m.menuName LIKE '%' || :menuName || '%' ");
} else if(searchCategoryCode > 0) {
jpql.append("WHERE ");
jpql.append("m.categoryCode = :categoryCode ");
}
}
TypedQuery<Menu> query = entityManager.createQuery(jpql.toString(), Menu.class); /* jpql์ toString()ํ์ฌ ์ฟผ๋ฆฌ ๋ง๋ค๊ธฐ */
if(searchName != null && !searchName.isEmpty() && searchCategoryCode > 0) {
query.setParameter("menuName", searchName);
query.setParameter("categoryCode", searchCategoryCode);
} else {
/* ๋ ์ค์ ํ๋๋ง ์์ ๊ฒฝ์ฐ */
if(searchName != null && !searchName.isEmpty()) {
query.setParameter("menuName", searchName);
} else if(searchCategoryCode > 0) {
query.setParameter("categoryCode", searchCategoryCode);
}
}
List<Menu> menuList = query.getResultList();
// then
assertNotNull(menuList);
menuList.forEach(System.out::println);
}
@NamedQueries
@NamedQuery
name
query
/* Menu ์ํฐํฐ */
@Entity(name="section08_menu")
@Table(name="TBL_MENU")
/* ๋ค์๋์ฟผ๋ฆฌ ์ง์ */
@NamedQueries({
@NamedQuery(name="section08_menu.selectMenuList", query="SELECT m FROM section08_menu m")
})
public class Menu {
}
@Test
public void ์ด๋
ธํ
์ด์
_๊ธฐ๋ฐ_๋ค์๋์ฟผ๋ฆฌ๋ฅผ_์ด์ฉํ_์กฐํ_ํ
์คํธ() {
// when
/* createNamedQuery()๋ฅผ ์ฌ์ฉํ์ฌ ์ ํด๋ ๋ค์๋์ฟผ๋ฆฌ๋ฅผ name์ ๋ถ๋ฌ์ด */
List<Menu> menuList = entityManager.createNamedQuery("section08_menu.selectMenuList", Menu.class).getResultList();
// then
assertNotNull(menuList);
menuList.forEach(System.out::println);
}
์กฐ๊ธ ๋ ๋ณต์กํ ํํ์ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํด์ผํ๋ ๊ฒฝ์ฐ์๋ xml ๋ฐฉ์์ ๋ ์ ํธ
(๋ฌธ์์ด๋ก ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๊ธฐ ๋ณต์กํ๊ธฐ ๋๋ฌธ)
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm" version="2.1">
<named-query name="section08_menu.selectMenuNameByCode">
<query>
SELECT
m
FROM section08_menu m
WHERE m.menuCode = :menuCode
</query>
</named-query>
</entity-mappings>
@Test
public void xml_๊ธฐ๋ฐ_๋ค์๋์ฟผ๋ฆฌ๋ฅผ_์ด์ฉํ_์กฐํ_ํ
์คํธ() {
// given
int menuCodeParameter = 81;
// when
Menu foundMenu = entityManager.createNamedQuery("section08_menu.selectMenuNameByCode", Menu.class) /* xmlํ์ผ ์์ ์ฟผ๋ฆฌ๋ฌธ์ name ์์ฑ๊ณผ ์ผ์น์์ผ์ผํจ */
.setParameter("menuCode", menuCodeParameter)
.getSingleResult();
// then
assertNotNull(foundMenu);
System.out.println("foundMenu : " + foundMenu);
}