jqgrid 페이징에서 local형식 외에(JSON...) 데이터로 구현을할때는 서버단에서 값을 계산해서 보내줘야 한다.
그리드 페이징 분리를 찾다가 그리드먼저 해결하자는 마음으로 먼저 해결하였다.
지금까지 내가 구현한 jqgrid는 페이징이 안되있었다. 페이지를 넘기면 처음 로딩된 데이터가 그대로 남아있었다.
그래서 서버단에서 페이지에따른 데이터값을 계산해서 보내기로 결정
1. 그리드를 실행하면은 records : 20,page :1, rows :5, total :20, sord :asc, sidx:name 값들이 넘어오는것을 이용
한 페이지에서 보여줄 데이터의 갯수는 rows이다. 총 레코드는 records(이건 db에서 계산해야함), 레코드 갯수에따른 총 페이지도 계산해야함
1 2 3 4 5 6 7 8 9 | --총 페이지수 <select id="totalCount" resultType="int" parameterType="int"> select round((count(*)/#{rows})+1) from employee </select> --총 레코드갯수 <select id="totalRecords" resultType="int" parameterType="int"> select count(*) from employee </select> | cs |
2. 위에거 계산한 값들은 jqgrid로 넘겨주어서 화면에 표시됨
3. 페이징을 위하여 쿼리를 수정
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | <select id="AllEmployeeList" resultMap="EmployeeMapper" parameterType="map"> <!-- 원래 쿼리 : 페이지에따른 값을 가져오는것이 아니라 그냥 전체를 가져옴 SELECT E.UCODE,E.DCODE,E.ENAME,E.NAME,E.BIRTHDAY,E.PHONE,E.EXNUM,E.EMAIL,E.ADDRESS,E.BIREDAY,E.NOTE, DE.DESCRIPTION AS DEPARTMENT, PO.DESCRIPTION AS POSITION, PR.DESCRIPTION AS PRESENT FROM CODE_TABLE PO,CODE_TABLE PR,CODE_TABLE DE ,EMPLOYEE E WHERE DE.CODE = E.DEPARTMENT AND PO.CODE = E.POSITION AND PR.CODE = E.PRESENT order by ${SIDX} <if test="SORD == ('asc')">ASC</if> <if test="SORD == ('desc')">DESC</if> --> -- 페이지값에따른 데이터를 가져옴 SELECT AAA.* FROM( SELECT ROW_NUMBER() OVER ( order by ${SIDX} <if test="SORD == ('asc')">ASC</if> <if test="SORD == ('desc')">DESC</if> ) RNUM, E.UCODE,E.DCODE,E.ENAME,E.NAME,E.BIRTHDAY,E.PHONE,E.EXNUM,E.EMAIL,E.ADDRESS,E.BIREDAY,E.NOTE, DE.DESCRIPTION AS DEPARTMENT, PO.DESCRIPTION AS POSITION, PR.DESCRIPTION AS PRESENT FROM CODE_TABLE PO,CODE_TABLE PR,CODE_TABLE DE ,EMPLOYEE E WHERE DE.CODE = E.DEPARTMENT AND PO.CODE = E.POSITION AND PR.CODE = E.PRESENT ) AAA WHERE AAA.RNUM BETWEEN ${startCount} AND ${endCount} </select> | cs |
1.ROW_NUMBER()을 사용해서 정렬된 그리드에 번호를 부여
※ ROW_NUMBER() 이용
페이징을 위해서는 정렬된 데이터값에 번호를 부여하여 데이터를 가져와야한다.
그리기 위해서는 오라클에선 ROW_NUMBER() 함수를 이용한다.
ROW_NUMBER() OVER(정렬) , RANK() OVER (정렬) : 정렬된 데이터값을 기준으로 번호를 부여함
SELECT USERID, SCORE, RANK() OVER (ORDER BY SCORE DESC) RANK FROM TMP_TABLE;
SELECT USERID, SCORE, ROW_NUMBER() OVER (ORDER BY SCORE DESC) RANK FROM TMP_TABLE;
이런식으로 사용
※
2. 페이지에따른 값을 가져와야하기 떄문에 BETWEEN 함수 사용
한 화면에서 보여줄 데이터값은 10개 때문에 1페이지에선 1~10까지에 데이터, 2페이지엔 11~20까지의 데이터 이런식으로
데이터를 가져와야함 => 그래서 BETWEEN 사용
그래서 시작값과 끝값을 계산해야함. (페이징 쿼리를 참고였다.)
controller에서
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | // 사원정보 jqgrid, json으로 변형한 데이터 @RequestMapping(value = "/gridView.do", method = RequestMethod.POST) @ResponseBody // json으로 변환 public HashMap<String, Object> gridView( EmployeeVO vo, Model model, @RequestParam(value = "page", required = false, defaultValue = "1") int page, @RequestParam(value = "rows", required = false, defaultValue = "20") int rows, @RequestParam(value = "total", required = false, defaultValue = "20") int total, @RequestParam(value = "records", required = false, defaultValue = "20") int records, @RequestParam(value = "sord", required = false, defaultValue = "sort") String sord, @RequestParam(value = "sidx", required = false) String sidx) { logger.info("사원정보jqgrid"); System.out.println("records :"+records+" page :"+page+", rows :"+rows+", total :"+total+", sord :"+sord+", sidx :"+sidx); // records : 20,page :1, rows :5, total :20, sord :asc, sidx:name //startCount와 endCount값을 계산 int startCount = (page - 1) * rows + 1; int endCount = page * rows; List<EmployeeVO> empVo = null; // empVo = employeeServiceimp.AllEmployeeList(); //map에 넣어 xml에서 매핑 HashMap<String, Object> order = new HashMap<String, Object>(); order.put("SORD", sord); order.put("SIDX", sidx); order.put("startCount", startCount); order.put("endCount", endCount); empVo = employeeServiceimp.AllEmployeeList(order); HashMap<String, Object> resMap = new HashMap<String, Object>(); total = employeeServiceimp.totalCount(rows); records = employeeServiceimp.totalRecords(); resMap.put("page", page); resMap.put("total", total); // 총페이지 resMap.put("records", records); // 총레코드 resMap.put("rows", empVo); return resMap; } |
완성~~ 이제 페이지를 넘기면은 해당 페이지에따른 값을 가져와서 뿌릴거임
- gridView
- 사원번호,이름,상세 검색
-----------------------------------------------------------------------------------------------------------------------------------------------------
2016.12.21
- 총 count구하기
사용자 이름,사원번호,상세검색에서 페이징 구현중 records의 값을 따로 구해야한는것을 깨닳음
int records = emp.size(); 로 했는데 emp의 갯수를 between start and end 으로 설정을 해놔서 (한페이지에 10개의 데이터가 보이도록)
검색된 데이터는 더 있더라고 10개의 데이터를 담기때문에 records=10으로 값이 주어졌었다.
그래서 count를 할수있는 쿼리를 찾다가 count over()을 발견...
참고 : http://javaexpert.tistory.com/503
1 2 3 4 5 6 7 | SELECT * FROM (SELECT ROW_NUMBER () OVER (ORDER BY 정렬 AS ROW_NUMBER, COUNT (*) OVER () AS row_count, 검색조건) WHERE 번호 BETWEEN 시작번호 AND 끝번호 | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <select id="userSearchDcode" resultMap="EmpSearchMapper" parameterType="map"> SELECT * FROM (SELECT ROW_NUMBER () OVER (ORDER BY ${sidx} <if test="sord == ('asc')">ASC</if> <if test="sord == ('desc')">DESC</if> ) AS ROW_NUMBER, COUNT (*) OVER () AS row_count, E.ENAME,E.NAME,E.DCODE,BIREDAY, DE.DESCRIPTION AS DEPARTMENT, PO.DESCRIPTION AS POSITION, PR.DESCRIPTION AS PRESENT FROM CODE_TABLE PO,CODE_TABLE PR, CODE_TABLE DE ,EMPLOYEE E WHERE DE.CODE = E.DEPARTMENT AND PO.CODE = E.POSITION AND PR.CODE = E.PRESENT AND DCODE like '%'||${DCODE}||'%') WHERE ROW_NUMBER BETWEEN ${startCount} AND ${endCount} </select> | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | - controller @RequestMapping(value = "/userSearchName.do", method = RequestMethod.POST, produces = "application/json; charset=UTF-8") public @ResponseBody HashMap<String, Object> userSearchName( @RequestParam String NAME, @RequestParam(value = "page", required = false) int page, // 그리드에서 전송된 page,rows,sort,sidx를 받자 @RequestParam(value = "rows", required = false) int rows, @RequestParam(value = "sord", required = false, defaultValue = "sort") String sord, @RequestParam(value = "sidx", required = false) String sidx) { int startCount = (page - 1) * rows + 1; // 시작번호와 끝번호를 계산 int endCount = page * rows; Map<String, Object> map = new HashMap<>(); // 쿼리에서필요한 데이터를 map에 담음 map.put("NAME", NAME); map.put("sidx", sidx); map.put("sord", sord); map.put("startCount", startCount); map.put("endCount", endCount); List<Emp_SearchVo> emp = null; emp = employeeServiceimp.userSearchName(map); //검색조건을 담은map을 파라미터로 쿼리를 실행후 결과를 list에담음 HashMap<String, Object> resMap = new HashMap<String, Object>(); //다시 그리드로 리턴하기위한 값들을 담기위해 map선언 int records; // 총 데이터수 if(emp.size()==0){ // 검색된 값이 없으면 총 데이터의수를 0으로 records = 0; }else{ records = emp.get(0).getRow_count(); // 검색된값이 1개라도 있으면 list에담겨있는 Row_count꺼내 records에 담음 } int total = (records/rows)+1; // 총 페이지수를 계산 if(records==10){ // 총 레코드의수가 10개일경우 10/10(rows:한 화면에 보여줄 데이터수)를 나누면 1이다 그런데 위에서 계산후에 1을 더하니까 그냥 total=1; // 레코드수가 10이면 total의수를 1로 } resMap.put("page", page); resMap.put("total", total); // 총페이지 resMap.put("records", records); // 총레코드 resMap.put("rows", emp); return resMap; } | cs |
'개발 > jqgrid' 카테고리의 다른 글
jqgrid 기본설정,옵션 (0) | 2016.12.22 |
---|---|
★jqgrid 페이징 분리 (0) | 2016.12.14 |
jqgrid loadComplete , gridComplete (0) | 2016.12.08 |
그리드 리로드 + 체크박스 유지 (0) | 2016.12.07 |
JQGRID (0) | 2016.12.06 |
댓글