在写一个小项目时,出现的问题,用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.实体类有无参构造