使用BeanListHandler得到的对象出现属性值为空的问题

在写一个小项目时,出现的问题,用QueryRunner将对应的数据表封装到一个对应的JavaBean时,出现了对象的属性值为空

问题分析:当对象的属性名与对应的数据表的字段名不一样时,而出现此类问题

正确情况

Type:酒店房间的类型

package test;

public class Type {
    private int tid;
    private String name;
    private int price;

    public Type() {
    }

    public Type(int tid, String name, int price) {
        this.tid = tid;
        this.name = name;
        this.price = price;
    }

    public int getTid() {
        return tid;
    }

    public void setTid(int tid) {
        this.tid = tid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Type{" +
                "tid=" + tid +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

测试代码,查询所有: 

package test;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.sql.SQLException;
import java.util.List;

public class Test {
    public static void main(String[] args) throws SQLException {
        QueryRunner qr = new QueryRunner(DruidUtils.dataSource);
       String sql = "select * from type";
        List<Type> types = qr.query(sql, new BeanListHandler<Type>(Type.class));
        for (Type type : types) {
            System.out.println(type);
        }
    }
}

type表结构:

运行结果:

分析:两者的命名一一对应,自然不会出现问题 

错误情况,这里使用驼峰命名法

package test;

public class RoomType {
    private int tid;
    private String roomName;
    private int roomPrice;

   构造器,get,set,toString...

}
package test;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.sql.SQLException;
import java.util.List;

public class Test {
    public static void main(String[] args) throws SQLException {
        QueryRunner qr = new QueryRunner(DruidUtils.dataSource);
       String sql = "select * from type";
        List<Type> types = qr.query(sql, new BeanListHandler<Type>(Type.class));
        for (Type type : types) {
            System.out.println(type);
        }

        System.out.println("---------");
        List<RoomType> roomTypes = qr.query(sql, new BeanListHandler<RoomType>(RoomType.class));
        for (RoomType roomType : roomTypes) {
            System.out.println(roomType);
        }
    }
}

运行结果,保持数据表不变

 分析:驼峰命名的部分全部为空

深入了解

使用BeanListHandler可以从参数列表的Class看出,其底层的实现肯定是与反射有关,并且使用反射有三者办法去给属性赋值

1.通过有参构造器

2.通过对属性赋值

3.通过使用set方法

这里我们测试一下:

 1.通过对属性赋值

package test;

public class Type {
    private int tid;
    private String name;
    private int price;
    
    public Type() {
    }

    @Override
    public String toString() {
        return "Type{" +
                "tid=" + tid +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}
运行结果

不是通过这种方法

2. 通过有参构造器

package test;

public class Type {
    private int tid;
    private String name;
    private int price;

    public Type() {
    }

    public Type(int tid, String name, int price) {
        this.tid = tid;
        this.name = name;
        this.price = price;
    }

    @Override
    public String toString() {
        return "Type{" +
                "tid=" + tid +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}
运行结果

不是通过这种方法

 3.通过使用set方法

package test;

public class Type {
    private int tid;
    private String name;
    private int price;

    public Type() {
    }


    public void setTid(int tid) {
        this.tid = tid;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Type{" +
                "tid=" + tid +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}
运行结果

正确情况

 小总结

其底层的实现是用反射通过set方法去为属性赋值

 改变错误情况的set方法名

package test;

public class RoomType {
    private int tid;
    private String roomName;
    private int roomPrice;

    public RoomType() {
    }

    public RoomType(int tid, String roomName, int roomPrice) {
        this.tid = tid;
        this.roomName = roomName;
        this.roomPrice = roomPrice;
    }

    public int getTid() {
        return tid;
    }

    public void setTid(int tid) {
        this.tid = tid;
    }

    public String getRoomName() {
        return roomName;
    }

    public void setName(String roomName) {
        this.roomName = roomName;
    }

    public int getRoomPrice() {
        return roomPrice;
    }

    public void setPrice(int roomPrice) {
        this.roomPrice = roomPrice;
    }

    @Override
    public String toString() {
        return "RoomType{" +
                "tid=" + tid +
                ", roomName='" + roomName + '\'' +
                ", roomPrice=" + roomPrice +
                '}';
    }
}

 运行结果

正确情况

总结

面对此类问题时主要注意就可以了三点:

1.保持实体类的属性名和数据库的字段名称一致

2.定义实体类的set方法

3.实体类有无参构造

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值