หน้าเว็บ

วันจันทร์ที่ 30 กันยายน พ.ศ. 2556

custom JSF primefaces lazyLoad with Spring data

บทความที่เกี่ยวข้อง  Lazy load primefaces

        พอดี ผมเองก็ใช้ JSF primeface ร่วมกับ spring data มาได้จะ 2 ปีแล้วครับ  ทุกๆ  โปรเจ็ค  ที่ต้องมีการเรียกใช้งาน lazy load  ร่วมกับ spring data เราต้องมา implement เองในบางส่วน  ซึ่งก็ต้อง implement ทุกๆ class ที่ทำหน้าที่เป็น lazy  หลังๆ เริ่มเบื่อ  เพราะ code มันซ้ำซ้อนในบางที่  ถามว่าเยอะมั้ย  ก็ไม่ได้เยอะมากครับ  แต่ผมอยากเขียนโดยไม่ต้องสนใจส่วนที่มันไม่เกี่ยวข้องกับ core business จริงๆ  คือ อยากให้มันง่าย  และสั้นที่สุดเท่าที่จะทำได้  ก็เลยมานั่งเขียน library ง่ายๆ เอาไว้ใช้เองนิดหน่อย  โดยใช้วิธีการ reflection แล้วก็ทำสิ่งเล็กๆ น้อยๆ ให้เสร็จสับเป็น spring data ทีเดียว  ก่อนที่จะเอาไปใช้งานจริงๆ  ครับ (ตัวอย่างการใช้งานอยู่ล่างสุด)

        จากบทความ  Lazy load primefaces  ถ้าเราเขียนโดยใช้ lazy load ของ primeface แบบธรรมดา  เราก็จะต้องเขียน code ยาวนิดนึงครับ  แต่ถ้าใช้ class ดังต่อไปนี้  ที่ผมเขียนไว้  code คุณจะเหลือแค่ไม่กี่บรรทัด
(เขียนไว้ใช้เองครับ  ซึ่งอาจจะไม่รองรับในทุกกรณี)

Library

LazyLoad.java
package com.blogspot.na5cent.web.lazyload;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.persistence.Id;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

/**
 *
 * @author redcrow
 */
public abstract class LazyLoad<T> extends LazyDataModel<T> {

    private static final Logger LOG = LoggerFactory.getLogger(LazyLoad.class);
    private List<T> list;
    private long totalElements;
    //

    @Override
    public T getRowData(String id) {
        if (list != null) {
            for (T instance : list) {
                Object instanceId = getIdOfInstance(instance);
                if (instanceId != null && id.equals(instanceId.toString())) {
                    return instance;
                }
            }
        }

        return null;
    }

    private Object getIdOfInstance(Object instance) {
        Object instanceId = null;
        try {
            Class instanceClass = instance.getClass();
            Field[] fields = instanceClass.getDeclaredFields();
            Field idField = null;
            for (Field field : fields) {
                if (field.isAnnotationPresent(Id.class)) {
                    idField = field;
                    break;
                }
            }

            if(idField != null){
                String idName = idField.getName();
                idName = idName.substring(0, 1).toUpperCase() + idName.substring(1);
                Method method = instanceClass.getDeclaredMethod("get" + idName);
                instanceId = method.invoke(instance);
            }
        } catch (Exception ex) {
            LOG.warn(null, ex);
        }

        return instanceId;
    }

    @Override
    public Object getRowKey(T instance) {
        return getIdOfInstance(instance);
    }

    @Override
    public void setRowIndex(final int rowIndex) {
        if (rowIndex == -1 || getPageSize() == 0) {
            super.setRowIndex(-1);
        } else {
            super.setRowIndex(rowIndex % getPageSize());
        }
    }

    /**
     *  callback method
     */
    public abstract Page<T> load(Pageable page);

    @Override
    public List<T> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
        Sort.Direction direction;
        if (sortOrder == SortOrder.ASCENDING) {
            direction = Sort.Direction.ASC;
        } else {
            direction = Sort.Direction.DESC;
        }

        Page<T> page = load(new PageRequest(first / pageSize, pageSize, direction, sortField));
        if (page != null) {
            list = page.getContent();
            totalElements = page.getTotalElements();
            this.setRowCount((int) totalElements);
        } else {
            list = new ArrayList<>();
            totalElements = 0L;
            setRowCount(0);
        }

        return list;
    }

    public List<T> getContents() {
        return list;
    }

    public long getTotalElements() {
        return totalElements;
    }
}

ตัวอย่างการใช้งาน เมื่อเรียกใช้ library (LazyLoad.java)


DoctorLazyLoad.java
package com.blogspot.na5cent.web.lazyload;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import com.blogspot.na5cent.api.model.Doctor;
import com.blogspot.na5cent.api.service.DoctorService;
import com.blogspot.na5cent.web.util.SpringUtils;

/**
 *
 * @author redcrow
 */
public class DoctorsLazyLoad extends LazyLoad<Doctor> {

    private DoctorService service = SpringUtils.getBean(DoctorService.class);
    
    @Override
    public Page<Doctor> load(Pageable page) {
        return service.findAll(page);
    }

}

(แบบเก่า) ถ้าเขียนแบบเดิมจะยาวประมาณนี้ (คนละ class แต่คล้ายๆ กัน)  

DoctorLazyLoad.java
package com.blogspot.na5cent.lazy;

import java.util.List;
import java.util.Map;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import com.blogspot.na5cent.model.Category;
import com.blogspot.na5cent.service.CategoryService;
import com.blogspot.na5cent.util.JSFSpringUtils;

/**
 *
 * @author Redcrow
 */
public class CategoryLazy extends LazyDataModel<Category> {
    //log

    static final Logger LOG = LoggerFactory.getLogger(CategoryLazy.class);
    private List<Category> categorys;
    private long totalElements;
    //services
    private CategoryService categoryService = JSFSpringUtils.getBean(CategoryService.class);


    public CategoryLazy() {
    }

    @Override
    public Category getRowData(String id) {
        for (Category cate : categorys) {
            if (cate.getId().toString().equals(id)) {
                return cate;
            }
        }

        return null;
    }

    @Override
    public Object getRowKey(Category cate) {
        return cate.getId();
    }

    @Override
    public void setRowIndex(final int rowIndex) {
        if (rowIndex == -1 || getPageSize() == 0) {
            super.setRowIndex(-1);
        } else {
            super.setRowIndex(rowIndex % getPageSize());
        }
    }

    @Override
    public List<Category> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
        Sort.Direction direction;
        if (sortOrder == SortOrder.ASCENDING) {
            direction = Sort.Direction.ASC;
        } else {
            direction = Sort.Direction.DESC;
        }

        Page page = categoryService.findAllPaging(new PageRequest(first / pageSize, pageSize, direction, sortField));
        categorys = page.getContent();
        totalElements = page.getTotalElements();
        this.setRowCount((int) page.getTotalElements());
        return categorys;
    }

    public List<Category> getContents() {
        return categorys;
    }

    public long getTotalElements() {
        return totalElements;
    }
}

ไม่มีความคิดเห็น:

แสดงความคิดเห็น