dbutils多表查询Bean映射问题

标题dbutils多表查询映射类中类

前言: 最近用dbutils做一些小功能的时候发现dbutils虽然可以进行多表查询 但是查询到的结果在BeanHandler 和BeanListHandler是无法映射的 但是确实可以把数据查出来,我在网上查了好多 目前也没有找到解决的办法 都是比较麻烦的,然后我想到的办法就是利用MapListHandler进行得到一个map集合 然后利用Beanutils.populate()方法进行映射
beanutils需要用到的jar包commons-beanutils-1.8.3.jar commons-logging-1.1.3.jar
我的类是:

// An highlighted block
public class Dept {
     
    private Integer did;
    private String dname;

    public Dept() {
     
    }

    public Integer getDid() {
     
        return did;
    }

    public void setDid(Integer did) {
     
        this.did = did;
    }

    public String getDname() {
     
        return dname;
    }

    public void setDname(String dname) {
     
        this.dname = dname;
    }

    @Override
    public String toString() {
     
        return "Dept{" +
                "did=" + did +
                ", dname='" + dname + '\'' +
                '}';
    }
}

Employee类

// An highlighted block

public class Employee1 {
     
    private Integer eid;
    private String ename;
    private Dept dept;
    private String regTime;

    public Employee1() {
     
    }

    public Employee1(Integer eid, String ename, Dept dept, String regTime) {
     
        this.eid = eid;
        this.ename = ename;
        this.dept = dept;
        this.regTime = regTime;
    }

    public Integer getEid() {
     
        return eid;
    }

    public void setEid(Integer eid) {
     
        this.eid = eid;
    }

    public String getEname() {
     
        return ename;
    }

    public void setEname(String ename) {
     
        this.ename = ename;
    }

    public Dept getDept() {
     
        return dept;
    }

    public void setDept(Dept dept) {
     
        this.dept = dept;
    }

    public String getRegTime() {
     
        return regTime;
    }

    public void setRegTime(String regTime) {
     
        this.regTime = regTime;
    }

    @Override
    public String toString() {
     
        return "Employee1{" +
                "eid=" + eid +
                ", ename='" + ename + '\'' +
                ", dept=" + dept +
                ", regTime='" + regTime + '\'' +
                '}';
    }
}

测试代码

// An highlighted block
  @Test
    public void text1() throws SQLException, InvocationTargetException, IllegalAccessException {
     
        QueryRunner queryRunner=new QueryRunner(new ComboPooledDataSource());
        String sql="select * from employee e left join dept d on e.did=d.did";
        List<Map<String, Object>> query = queryRunner.query(sql, new MapListHandler());//将查询到的所有信息每行以key-value的形式装到map里 然后把我多个map放到list集合中
        List<Employee1> emps=new ArrayList<>(); //对得到的结果进行处理然后放到集合返回
        for (Map<String, Object> map : query) {
     //遍历集合
            Employee1 emp=new Employee1();//把结果集封装到对象中
            Dept dept=new Dept();
            BeanUtils.populate(dept,map);//把属于dept对象的属性封装  切记 dept和employee属性名不能重复  如果不能避免请看下面一种情况
            emp.setDept(dept);//把封装好的dept加到employee类中
            BeanUtils.populate(emp,map);//把属于employee的对象属性封装
            emps.add(emp);//放入集合
        }
        for (Employee1 emp : emps) {
     
            System.out.println(emp);
        }
    }

结果图可见映射成功
![](https://img-blog.csdnimg.cn/20210116193339169.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0

如果遇到一对多的查询 我们一般是在集合当中封装一个集合类属性

// An highlighted block

public class Dept1 {
     
    private Integer did;
    private String dname;
    private List<Employee> empList;

    public Dept1() {
     
    }

    public Dept1(Integer did, String dname, List<Employee> empList) {
     
        this.did = did;
        this.dname = dname;
        this.empList = empList;
    }

    public Integer getDid() {
     
        return did;
    }

    public void setDid(Integer did) {
     
        this.did = did;
    }

    public String getDname() {
     
        return dname;
    }

    public void setDname(String dname) {
     
        this.dname = dname;
    }

    public List<Employee> getEmpList() {
     
        return empList;
    }

    public void setEmpList(List<Employee> empList) {
     
        this.empList = empList;
    }

    @Override
    public String toString() {
     
        return "Dept1{" +
                "did=" + did +
                ", dname='" + dname + '\'' +
                ", empList=" + empList +
                '}';
    }
}

我是把一对多查询分开然后进行的查询

// An highlighted block
@Test
    public void text3() throws SQLException {
     
        QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
        String sql="select * from dept";
        List<Dept1> dept1List = queryRunner.query(sql, new BeanListHandler<Dept1>(Dept1.class));//先查到所有的部门
        for (Dept1 dept1 : dept1List) {
     //然后遍历所有的部门根据部门id然后遍历部门的所有员工
            String sql1="select * from employee where did=?";
            List<Employee> query = queryRunner.query(sql1, new BeanListHandler<Employee>(Employee.class), dept1.getDid());
            dept1.setEmpList(query);
        }
        for (Dept1 dept1 : dept1List) {
     
            System.out.println(dept1);
        }

    }

但是有的时候我们会遇到设计数据库的人 把dept表的id 叫 id 然后把 employee表的id 也叫id 这样我们在建立实体类的时候如果在不变通就会无法用我们上面所说的第一种 我是把这两个id区分开 然后在对他们查询的时候进行别名 这个别名和实体类的属性名一样 这样我们通过 MapListHandler得到的key-value的key就会是我们起的别名了 然后不会重复的两个id

// An highlighted block
 @Test
    public void text2() throws SQLException, InvocationTargetException, IllegalAccessException {
     
        QueryRunner queryRunner=new QueryRunner(new ComboPooledDataSource());
        String sql="select eid id,ename name,did deptId,regTime time from employee";//查询的时候起别名防止两个表的id字段都叫id
        List<Map<String, Object>> query = queryRunner.query(sql, new MapListHandler());
        List<Employee2> emp2s=new ArrayList<>();
        for (Map<String, Object> map : query) {
     
           Employee2 emp=new Employee2();
           BeanUtils.populate(emp,map);
           emp2s.add(emp);
        }
        for (Employee2 emp2 : emp2s) {
     
            System.out.println(emp2);
        }
    }

希望能帮到大家 用用的大家多多点赞哦 嘿嘿!!!!

你可能感兴趣的:(java,封装,数据库)