
QueryDSL?
오픈소스 프로젝트로 복잡한 Creteria를 대체하는 JPQL빌더이다.
복잡한 쿼리와 동적쿼리를 깔끔하게 해결해주고 쿼리를 자바 코드로 작성할 수 있다. 따라서 문법오류를 컴파일 단계에서 잡아줄 수 있다.
-Creteria는 Java코드를 이용해 JPQL을 작성할 수 있게 도와주는 타입 세이프(Type-Safe: 타입에 안정적 즉 어떠한 오퍼레이션(또는 연산)도 정의되지 않은 결과를 내놓지 않은 것이다. 예측불가능한 결과를 내지 않는 것을 뜻함)를 제공하는 쿼리이다. SQL 쿼리를 대체해 HQL, JPQL을 자바 코드로 이용해 작성할 수 있게 해 준다.
-JPQL는 JPA의 일부로 정의된 플랫폼 독립적인 객체지향 쿼리이다.
SQL에 크게 영향을 받아 SQL문과 비슷하지만 데이터베이스의 테이블에 직접 연결되는 것이 아니라
JPA 엔티티에 대해 동작한다.
●DB 'Company'에 대한 개체 등록 및 삭제/수정/조회 기능 만들기
1. 진행하고 있는 프로젝트에서 Companyservice단에서 상속된
BaseService에 QueryDSL의 개체를 등록한 후,
import java.io.Serializable;
public class BaseService<T, ID extends Serializable> extends AXBootBaseService<T, ID> {
protected QUserRole qUserRole = QUserRole.userRole;
protected QAuthGroupMenu qAuthGroupMenu = QAuthGroupMenu.authGroupMenu;
protected QCommonCode qCommonCode = QCommonCode.commonCode;
protected QUser qUser = QUser.user;
protected QProgram qProgram = QProgram.program;
protected QUserAuth qUserAuth = QUserAuth.userAuth;
protected QMenu qMenu = QMenu.menu;
protected QCommonFile qCommonFile = QCommonFile.commonFile;
protected QCompany qCompany = QCompany.company;
protected AXBootJPAQueryDSLRepository<T, ID> repository;
public BaseService() {
super();
}
public BaseService(AXBootJPAQueryDSLRepository<T, ID> repository) {
super(repository);
this.repository = repository;
}
}
2. CompanyService.java에 사용할 QueryDSL 기능을 추가함.
//QueryDSL
public List<Company> getByQueryDsl(RequestParams<Company> requestParams) {
String company = requestParams.getString("company", "");
String ceo = requestParams.getString("ceo", "");
String bizno = requestParams.getString("bizno", "");
BooleanBuilder builder = new BooleanBuilder();
if (isNotEmpty(company)) {
builder.and(qCompany.companyNm.eq(company));
}
if (isNotEmpty(ceo)) {
builder.and(qCompany.ceo.eq(ceo));
}
if (isNotEmpty(bizno)) {
builder.and(qCompany.bizno.eq(bizno));
}
List<Company> companyList = select()
.from(qCompany)
.where(builder)
.orderBy(qCompany.companyNm.asc())
.fetch();
return companyList;
}
@Transactional
public void saveByQueryDsl(List<Company> request) {
for (Company company: request) {
if (company.isCreated()) {
save(company);
} else if (company.isModified()) {
update(qCompany)
.set(qCompany.companyNm, company.getCompanyNm())
.set(qCompany.ceo, company.getCeo())
.where(qCompany.id.eq(company.getId()))
.execute();
} else if (company.isDeleted()) {
delete(qCompany)
.where(qCompany.id.eq(company.getId()))
.execute();
}
}
}
3. CompanyController.java에 @ApiImplicitParams(저장된 테이블 컬럼에 데이터 조회로 테스트할 수 있는 기능?)
@RequestMapping(value = "/QueryDsl", method = RequestMethod.GET, produces = APPLICATION_JSON)
@ApiImplicitParams({
@ApiImplicitParam(name = "company", value = "회사명", dataType = "String", paramType = "query"),
@ApiImplicitParam(name = "ceo", value = "대표자", dataType = "String", paramType = "query"),
@ApiImplicitParam(name = "bizno", value = "사업자번호", dataType = "String", paramType = "query")
})
public Responses.ListResponse list2(RequestParams<Company> requestParams) {
List<Company> list = companyService.getByQueryDsl(requestParams);
return Responses.ListResponse.of(list);
}
@RequestMapping(value = "/QueryDsl", method = {RequestMethod.PUT}, produces = APPLICATION_JSON)
public ApiResponse save2(@RequestBody List<Company> request) {
companyService.saveByQueryDsl(request);
return ok();
}
4. company.jsp에서 화면단에 해당하는 값을 추출하기 위해서 각 input태그에 NAME과 ID를 같은 이름으로
요소로 추가한다.
<div role="page-header">
<ax:form name="searchView0">
<ax:tbl clazz="ax-search-tbl" minWidth="500px">
<ax:tr>
<ax:td label='회사명' width="300px">
<input type="text" name="company" id="company" class="form-control" />
</ax:td>
<ax:td label='대표자' width="300px">
<input type="text" name="ceo" id="ceo" class="form-control" />
</ax:td>
<ax:td label='사업자번호' width="300px">
<input type="text" name="bizno" id="bizno" class="form-control" />
</ax:td>
</ax:tr>
</ax:tbl>
</ax:form>
<div class="H10"></div>
</div>
5. company.js에서 jsp에서 추가했던 name/id 요소로 값을 가져올 수 있게 소스코드를 추가.
fnObj.searchView = axboot.viewExtend(axboot.searchView, {
initView: function () {
this.target = $(document["searchView0"]);
this.target.attr("onsubmit", "return ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);");
this.company = $("#company");
this.ceo = $("#ceo");
this.bizno = $("#bizno");
},
getData: function () {
return {
pageNumber: this.pageNumber,
pageSize: this.pageSize,
company: this.company.val(),
ceo: this.ceo.val(),
bizno: this.bizno.val()
}
}
});
●데이터 수정 기능
1. company.js에서 PAGE_SAVE의 type : put영역에 querydsl 경로를 추가하여 수정기능을 완성한다.
PAGE_SAVE: function (caller, act, data) {
var saveList = [].concat(caller.gridView01.getData()); //modified삭제함
saveList = saveList.concat(caller.gridView01.getData("deleted"));
axboot.ajax({
type: "PUT",
// url: "/api/v1/company",
url: "/api/v1/company/QueryDsl",
data: JSON.stringify(saveList),
callback: function (res) {
ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);
axToast.push("저장 되었습니다");
}
});
},
●데이터 삭제기능
getData: function (_type) {
var list = [];
var _list = this.target.getList(_type);
if (_type == "modified" || _type == "deleted") {
list = ax5.util.filter(_list, function () {
// delete this.deleted;
// return this.key;
return this.id; // 객체안에는 key값이 없으므로 id값을 받아온다.
});
} else {
list = _list;
}
return list;
},
인텔리제이 커뮤니티 버전으로 화면단을 실시간 업데이트할 수 있는 dependency
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.12.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>'Programming👩🏻💻 > AxBoot' 카테고리의 다른 글
| Banner / Logging / Excel download (0) | 2021.04.30 |
|---|---|
| jsfiddle (0) | 2021.04.23 |
| *중요 디버깅, 단위테스트 (0) | 2021.04.22 |
| Mybatis연동 (0) | 2021.04.19 |
| Mac 맥) Maven 설치 및 환경 변수 설정 (0) | 2021.04.19 |