[SPRING] jqGrid를 사용하여 지연로드를 구현할 수 있습니까?
SPRINGjqGrid를 사용하여 지연로드를 구현할 수 있습니까?
5000 개 이상의 데이터 레코드가있는 표가 있습니다. 이 데이터는 매일 계속 증가하고 있습니다. 그리드가있는 페이지를로드 할 때 그리드가 한 번에 10 개의 행을 표시해야하는 데이터를 표시하기까지는 거의 1 분이 걸립니다.
이 jqGrid를 사용하여 지연로드를 구현할 수 있습니까?
이것이 JSon String을 생성하는 나의 액션이다.
@RequestMapping(value = "studentjsondata", method = RequestMethod.GET)
public @ResponseBody String studentjsondata(HttpServletRequest httpServletRequest) {
Format formatter = new SimpleDateFormat("MMMM dd, yyyy");
String column = "id";
if(httpServletRequest.getParameter("sidx") != null){
column = httpServletRequest.getParameter("sidx");
}
String orderType = "DESC";
if(httpServletRequest.getParameter("sord") != null){
orderType = httpServletRequest.getParameter("sord").toUpperCase();
}
int page = 1;
if(Integer.parseInt(httpServletRequest.getParameter("page")) >= 1){
page = Integer.parseInt(httpServletRequest.getParameter("page"));
}
int limitAmount = 10;
int limitStart = limitAmount*page - limitAmount;
List<Student> students = Student.findAllStudentsOrderByColumn(column,orderType,limitStart,limitAmount).getResultList();
List<Student> countStudents = Student.findAllStudents();
double tally = Math.ceil(countStudents.size()/10.0d);
int totalPages = (int)tally;
int records = countStudents.size();
StringBuilder sb = new StringBuilder();
sb.append("{\"page\":\"").append(page).append("\", \"records\":\"").append(records).append("\", \"total\":\"").append(totalPages).append("\", \"rows\":[");
boolean first = true;
for (Student s: students) {
sb.append(first ? "" : ",");
if (first) {
first = false;
}
sb.append(String.format("{\"id\":\"%s\", \"cell\":[\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\"]}",s.getId(), s.getId(), s.getFirstName(), s.getLastName(), formatter.format(s.getDateOfBirth().getTime()), s.getGender(), s.getMaritalStatus()));
}
sb.append("]}");
return sb.toString();
}
그리고 이것은 jqGrid가있는 페이지입니다.
$("#studentGrid").jqGrid({
url: '/starburst/programmes/studentjsondata',
datatype: 'json',
height: 'auto',
colNames:['id','First Name', 'Last Name', 'Date Of Birth', 'Gender', 'Marital Status'],
colModel:[
{name:'id',index:'id', width:15},
{name:'firstName',index:'firstName', width:30, formoptions:{elmprefix:'(*) '}, editable:true, edittype: 'text', editrules:{required:true}},
{name:'lastName',index:'lastName', width:30, formoptions:{elmprefix:'(*) '}, editable:true, edittype: 'text',editrules:{required:true}},
{name:'dateOfBirth',index:'dateOfBirth', width:30, formoptions:{elmprefix:'(*) '},editrules:{required:true}, editable:true, edittype: 'text',
editoptions: {
dataInit: function(element) {
$(element).datepicker({dateFormat: 'MM dd, yy'})
}
}
},
{name:'gender',index:'gender', width:30, formoptions:{elmprefix:'(*) '}, editable:true, editrules:{required:true}, edittype: 'select',
editoptions:{value:{}}
},
{name:'maritalStatus',index:'maritalStatus', width:30, formoptions:{elmprefix:'(*) '}, editable:true, editrules:{required:true}, edittype: 'select',
editoptions:{value:{}}
}
],
rowNum:10,
autowidth: true,
pager: '#pager',
sortname: 'id',
viewrecords: true,
sortorder: "desc",
caption:"Students",
emptyrecords: "Empty Records",
subGrid: true,
/* <![CDATA[ */
onSelectRow: function(id){
if((lastsel != 0)&&(id!==lastsel)){
$("#studentGrid").jqGrid('collapseSubGridRow', lastsel);
}
lastsel=id;
}/* ]]> */
});
$("#studentGrid").jqGrid('navGrid', "#pager", {edit:false,add:false,del:false,search:true},{ },{ },{ },
{
sopt:['eq', 'ne', 'lt', 'gt', 'cn', 'bw', 'ew'],
closeOnEscape: true,
multipleSearch: true,
아래 쿼리를 참조하십시오.
public static TypedQuery<tt.edu.sbcs.model.Student> findAllStudentsOrderByColumn(String column, String orderType, int limitStart, int limitAmount) {
EntityManager em = Programme.entityManager();
TypedQuery<Student> q = em.createQuery("SELECT o FROM Student AS o ORDER BY"+" "+column+" "+orderType, Student.class);
q.setFirstResult(limitStart);//used to skip the first "N" elements form the result set, it indexes results form zero
q.setMaxResults(limitAmount);
return q;
}
위 작업에서 설정 한 한도. 이 값은 10입니다.
해결법
-
==============================
1.좋아, 그래서 JPA를 기반으로 한 부분적인 대답이있다. (그러나 나는 그것을 Hibernate에 적용하는 것이 거의 중요하지 않다). 필요한 객체 만 가져 오려면 다음과 같이 할 수 있어야합니다.
좋아, 그래서 JPA를 기반으로 한 부분적인 대답이있다. (그러나 나는 그것을 Hibernate에 적용하는 것이 거의 중요하지 않다). 필요한 객체 만 가져 오려면 다음과 같이 할 수 있어야합니다.
Query query = em.createQuery("select o from " + "Student"+ " as o order by o.id"); query.setFirstResult(start); query.setMaxResults(end - start); return query.getResultList();
카운트의 경우, 이와 같이해야합니다 :
Number count = (Number) em.createQuery("select count(id) from " + "Student").getSingleResult(); if (count == null) { count = Integer.valueOf(0); } return count.intValue();
더 많은 정보가 있으면 편집 할 것입니다.
-
==============================
2.우선 1 분 안에 총 10 개의 행을로드하는 것이 매우 느립니다. 나는 서버 코드와 jqGrid가 병목 현상이 아니라고 생각한다.
우선 1 분 안에 총 10 개의 행을로드하는 것이 매우 느립니다. 나는 서버 코드와 jqGrid가 병목 현상이 아니라고 생각한다.
코드의 첫 번째 의심되는 행은 다음과 같습니다.
List<Student> countStudents = Student.findAllStudents();
학생 수를 늘릴 필요가 있지만 모든 학생의 모든 속성을 얻은 다음 두 줄에 countStudents.size ()를 사용하는 것으로 보입니다. 수행해야 할 최대 작업은 다음과 같습니다.
SELECT COUNT(*) FROM dbo.Students
이것 대신에 당신은 SELECT * FROM dbo.Students를 수행합니다.
코드가 1 분이 걸릴 경우 데이터베이스 또는 함수 findAllStudentsOrderByColumn의 구현에 심각한 문제가있을 수 있습니다. 아마도 엔티티 모델 또는 데이터베이스 모델을 나타내는 클래스가있을 것입니다. 성능이 매우 나빠진다면 데이터베이스 액세스를 매우 신중하게하는 코드를 검사하거나 데이터베이스 쿼리를 직접 지정할 수있는 데이터베이스에 대한 좀 더 직접적인 액세스를 고려해야합니다. 저는 Java 나 Spring 개발자가 아니지만, 분명히 말할 수 있습니다. 5000 행의 10 행 요청이 이미 너무 느린 것보다 1 초 이상 더 길면.
이드를 포함하여 하나의 테이블에서 일부 열을 반환해야하는 것처럼 보입니다. 그래서 SELECT와 같은 데이터를 얻을 수 있습니다.
SELECT TOP(10) id, firstName, lastName, dateOfBirth, gender, maritalStatus FROM dbo.Students ORDER BY id
데이터의 첫 페이지와 다음과 같은 것을 얻으려면
WITH GetAll (id, firstName, lastName, dateOfBirth, gender, maritalStatus) AS ( SELECT id, firstName, lastName, dateOfBirth, gender, maritalStatus FROM dbo.Students ORDER BY id ), GetTop (id, firstName, lastName, dateOfBirth, gender, maritalStatus) AS ( SELECT TOP(20) * FROM GetAll -- skip 2 pages per 10 rows ), GetNext (id, firstName, lastName, dateOfBirth, gender, maritalStatus) AS ( SELECT TOP(10) a.* FROM GetAll AS a LEFT OUTER JOIN GetTop AS t ON t.id = a.id WHERE t.id IS NULL ) SELECT * FROM GetNext
모든 다음 페이지. 공통 테이블 식 (CTE) 구문을 사용했지만 데이터베이스가 지원하지 않으면 하위 쿼리를 사용할 수 있습니다.
모든 열을 기준으로 정렬 할 수 있으므로 테이블의 모든 열에 INDEXes를 만들어 정렬 성능을 향상시켜야합니다. (필자는 Students 테이블이 초당 많은 변경으로 수정되지 않기 때문에 인덱스가 테이블의 성능을 저하시키지 않을 것이라고 생각합니다.)
고려해야 할 또 다른 사항은 직렬화를 JSON으로 변경하는 것입니다. String.format ( "\"% s \ ", someString)의 사용은 위험합니다. \와 이스케이프해야하는 문자가 있습니다. 코드를 안전하게 만들려면이 작업을 수행해야합니다. 일반적인 연습은 직렬화를 위해 여러분의 언어에 존재하는 몇 가지 표준 클래스를 사용하는 것입니다 (예를 들어 여기 또는 여기 참조).
다음 팁은 jsonReader : {cell : ""}을 사용하여 양식의 행에 대한 데이터를 반환하는 것입니다.
["%s", "%s", "%s", "%s", "%s", "%s"]
대신에
{"id":"%s", "cell":["%s", "%s", "%s", "%s", "%s", "%s"]}
id 값을 두 번 보내지 않고 문자열 "id" "cell"과 다른 불필요한 문자 ( '{', ':', ...)를 보내지 않습니다.
클라이언트 측에서 항상 gridview : true jqGrid 옵션을 사용해야합니다. jqGrid가 매우 빨리 수행되기 때문에 10 행의 데이터를 사용하면 심각한 차이가 나타나지 않지만 더 많은 행을 사용하면 차이가 명확 해집니다.
마지막 제안 : 포매터 : '날짜'를 사용하고 ISO 8601 형식으로 날짜를 보내야합니다 (예 : 2012-03-20).
from https://stackoverflow.com/questions/9790122/can-i-implement-lazy-loading-with-jqgrid by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] @Transactional이 클래스 수준에있을 때 읽기 전용을 사용하는 방법 (0) | 2019.05.20 |
---|---|
[SPRING] mysql : = 연산자를 만나면 Hibernate 예외가 발생한다. (0) | 2019.05.20 |
[SPRING] Spring Cloud Dataflow Type 변환이 프로세서 구성 요소에서 작동하지 않습니까? (0) | 2019.05.20 |
[SPRING] '중첩 된'주석을위한 Spring AOP point cut (0) | 2019.05.20 |
[SPRING] 스프링 부트가 작동하지 않는 @AuthenticationPrincipal (0) | 2019.05.20 |