JFinal使用技巧-Record转JavaBean以及List转JavaBea

这月新晋级奶爸了,代码写的都少了哈哈~~~

如题,当我们业务有涉及到复杂的数据组装和计算时,我都喜欢使用传统的JavaBean装载业务数据。里面可以写一些该业务的专有运算方法,又不会污染基础Model类,后续阅读业务代码也会清晰一点。

废话不多说,上石马:

import com.jfinal.plugin.activerecord.Record;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("unused")
public class RecordToBean {

    public static <T> T to(Record r, Class<T> clazz) {
        try {
            T ret = clazz.getDeclaredConstructor().newInstance();
            PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz, Object.class)//
                    .getPropertyDescriptors();
            for (PropertyDescriptor pd : pds) {
                Object value = getValue(r, pd);
                pd.getWriteMethod().invoke(ret, value);
            }
            return ret;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    public static <T> List<T> to(List<Record> list, Class<T> clazz) {
        try {
            Constructor<T> constructor = clazz.getDeclaredConstructor();
            PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz, Object.class)//
                    .getPropertyDescriptors();
            List<T> ret = new ArrayList<>(list.size());
            for (Record r : list) {
                T obj = constructor.newInstance();
                for (PropertyDescriptor pd : pds) {
                    Object value = getValue(r, pd);
                    pd.getWriteMethod().invoke(obj, value);
                }
                ret.add(obj);
            }
            return ret;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    private static Object getValue(Record r, PropertyDescriptor pd) {
        String key = pd.getName();
        Class<?> type = pd.getPropertyType();
        if (String.class.equals(type)){
            return r.getStr(key);
        }
        if (Integer.class.equals(type)){
            return r.getInt(key);
        }
        if (Boolean.class.equals(type)){
            return r.getBoolean(key);
        }
        if (java.math.BigDecimal.class.equals(type)){
            return r.getBigDecimal(key);
        }
        if (Long.class.equals(type)){
            return r.getLong(key);
        }
        if (java.math.BigInteger.class.equals(type)){
            return r.getBigInteger(key);
        }
        if (java.util.Date.class.equals(type)){
            return r.getDate(key);
        }
        if (Double.class.equals(type)){
            return r.getDouble(key);
        }
        if (Float.class.equals(type)){
            return r.getFloat(key);
        }
        if (java.time.LocalDateTime.class.equals(type)){
            return r.getLocalDateTime(key);
        }
        if (Short.class.equals(type)){
            return r.getShort(key);
        }
        if (Byte.class.equals(type)){
            return r.getByte(key);
        }
        if (Number.class.equals(type)){
            return r.getNumber(key);
        }
        return r.get(key);
    }

}

测试:

public static class MyBean{
    private String a;
    public void setA(String a) {
        this.a = a;
    }
    private BigDecimal b;

    public void setB(BigDecimal b) {
        this.b = b;
    }
    //get...
    @Override
    public String toString() {
        return "MyBean{" +
                "a='" + a + '\'' +
                ", b=" + b +
                '}';
    }
}

public static void main(String[] args) {
    Record r = new Record();
    r.set("a", "A");
    r.set("b", "888");
    MyBean t = RecordToBean.to(r, MyBean.class);
    System.out.println(t);

    List<Record> list = new ArrayList<>();
    list.add(r);
    list.add(r);
    List<MyBean> rs = RecordToBean.to(list, MyBean.class);
    System.out.println(rs);
}

结果:

image.png

非常方便!

常见用法:
List<Record> list = Db.templateByString(sql, Kv.create()).find();
List<MyBean> rs = RecordToBean.to(list, MyBean.class);


评论区

星矢

2023-03-24 17:50

先成json字符串,再通过json转成bean类, 不是更方便一些?

杜福忠

2023-03-24 22:38

@星矢 哪能更方便哦!Record转JSON字符串,是要取里面map,再转成字符串,再解析字符串,再转。。。哪有上面方便和性能可比,map》对象。JSON需要一个包,上面只有一个方法了

请问额qwe

2023-03-25 18:18

恭喜恭喜

山东小木

2023-03-26 12:28

废话不多说 实名收录到Jbolt

SuperEric

2023-03-26 17:43

实用,比我一顿转简洁多了。

l745230

2023-03-27 14:37

代码很好,但是我选择用hutool的BeanUtil.toBean(record.getColumns(), MyBean.class)

hhchor

2023-04-12 20:14

to方法遍历record列会好点,record有数据才写进bean里。现在bean的所有set方法都执行了一次,如果后续执行update极有可能报空指针

杜福忠

2023-04-12 22:19

@hhchor 在我这边业务查出的Record 字段可能会超出Bean属性,而Bean只取需要的数据。
而且Bean并没有update方法,它不是Model类。
如果自己业务不处理null的话,是可以对value判null后不执行invoke方法,提高性能。毕竟它只是一个方法,可以随意改造!

fmpoffice

2023-04-13 11:45

忠哥出品,永远精品

BigSnake1989

2023-04-23 13:17

@l745230 BeanUtil.copyProperties

热门分享

扫码入社