jdbc多表关联查询,多表查询返回结果集处理方法。

 

不知什么原因原作者在csdn把这篇博客删了

来源见百度文库

https://wenku.baidu.com/view/438f408c03d276a20029bd64783e0912a2167c98.html

jdbc多表关联查询,多表查询返回结果集处理方法。

该功能常见于两表或者多表关联查询中使用,返回的查询结果是多个(或两个)表中的字段信息,无法使用单个模型来存储时使用,使用转换后,可以将查询结果使用json传递或页面之间的参数传递。

**

举例说明:

**

例如员工表(user)表结构是拥有user_id 、usernaem、email 、dept_id 等字段

部门表(dept)表结构拥有dept_id、dept_phone 、dept_name 等字段。

我们要通过sql查询出每个员工所在部门名称和部门电话 员工姓名 邮箱

String sql = “select username,email,dept_phone,dept_name from user u,dept d where u.dept_id=d.dept_id “;

创建和数据库一一对应的实体类User

public class User {

    public int user_id;

    public String usernaem;

    public String email;

    public int dept_id;

    //此处省略set get方法 toString 还有构造函数

}

public class Dept {

    public int dept_id;

    public String dept_phone;

    public String dept_name;
    
    //此处省略set get方法 toString 还有构造函数
}

 

很显然如果要将查询出来的通过DAO方法返回结果是无法实现的,此时有两个解决方法,一、可以通过通过构建一个复杂的Java实体类来实现,

二、通过将查询结果保存为Map集合,如果返回多调记录,则将map加入List中返回,

方法一:

例如:

public class UserDept {

    public int user_id;

    public String usernaem;

    public String email;


    public int dept_id;

    public String dept_phone;

    public String dept_name;


//此处省略set get方法 toString 还有构造函数

}

 

将查询的结果保存在UserDept 实体类中,但是这样的方式显然不灵活,如果遇到关联查询返会的信息非常多时,或者要多次查询每次返回不同的结果集合是就非常麻烦,每次都要写不同的实体类,显然这样做非常不利,而且维护成本也非常高。所以在此我推荐方法二:

方法二

新建类ModelConvert 包含以下两个方法,用于查询结果集转换

  • 该工具类为数据库关联模型查询工具转换

  • convertList方法 是将关联查询出来的结果通过map保存多条记录使用list存储

  • convertMap方法 是将单挑查询记录通过map保存进行值传递

/* 用于将rs查询结果封装为List<Map<String, Object>>对象
*
* @param rs数据库查询结果
* @return 返回list map封装后的结果
*/
public static List<Map<String, Object>> convertList(ResultSet rs) {
    // 新建一个map list集合用于存放多条查询记录
    List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
    try {
        ResultSetMetaData md = rs.getMetaData();// 结果集(rs)的结构信息,比如字段数、字段名等。
        int columnCount = md.getColumnCount();// 取得查询出来的字段个数
        while (rs.next()) {// 迭代rs
            // 新建一个map集合 将查询出内容按照字段名:值 的键值对形式存储在map集合中
            Map<String, Object> rowData = new HashMap<String, Object>();
            for (int i = 1; i <= columnCount; i++) {// 循环所有查询出字段
                rowData.put(md.getColumnName(i), rs.getObject(i));
                // getColumnName(i) 获取第i个列名
                // getObject(i) 获取第i个对象的值
            }
            list.add(rowData);// 将map放入list集合中
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {// 关闭连接
        try {
            if (rs != null)
                rs.close();
            rs = null;
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    return list;
}



/*
* 用于将rs查询结果封装为Map<String, Object>对象(适合于只有一条查询记录)
*
* @param rs数据库查询结果
* @return 返回map封装后 字段名:值 的键值对结果
*/
public static Map<String, Object> convertMap(ResultSet rs) {
    Map<String, Object> map = new TreeMap<String, Object>();
    try {
        ResultSetMetaData md = rs.getMetaData();
        int columnCount = md.getColumnCount();
        while (rs.next()) {
            for (int i = 1; i <= columnCount; i++) {
                map.put(md.getColumnName(i), rs.getObject(i));
            }
        }
        return map;
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (rs != null)
                    rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return null;
}

 

 

通过以上两个方法将查询结果装换分别转换,就可以返回。

例如数据库操作DAO实现:

public List<Map<String, Object>> findAll() {

    Connection conn = null;

    try {

        conn = DBUtil.getConnection();

        // 通过sql关联查询出员工表信息和所在部门名称

        String sql = "select username,email,dept_phone,dept_name from user u,dept d where u.dept_id=d.dept_id ";

        PreparedStatement ps = conn.prepareStatement(sql);

        ResultSet rs = ps.executeQuery();

        List<Map<String, Object>> list = convertList(rs);

        return list;

    }catch (SQLException e1) {

        e1.printStackTrace();

        throw new RuntimeException("查询用户失败", e1);

    } finally {

        DBUtil.close(conn);

    }    

}

 

main方法调用测试:

public static void main(String[] args) {

    ModelConvert dao = new ModelConvert();

    List<Map<String, Object>> list = dao.findAll();

    for (int i = 0; i < list.size(); i++) {// 循环遍历

        Map<String, Object> map = list.get(i);

        // 以下将获得每个查询出来的字段的值

        System.out.print(map.get("username") + "\t");
    
        System.out.print(map.get("email") + "\t");
    
        System.out.print(map.get("dept_phone") + "\t");

        System.out.print(map.get("dept_name ") + "\t");

    }

}

 

使用servlet传递参数到页面:

jstl表达式获取关联查询结果

ModelConvert dao = new ModelConvert();

List<Map<String, Object>> listMap= dao.findAll();

request.setAttribute("listMap", listMap);

request.getRequestDispatcher("ELJstlDemo01.jsp").forward(request, response);

 

jstl调用显示页面:

<c:forEach items="${listMap}" var="user">

    <tr>

        <td>${user.username}</td>

        <td>${user.email}</td>

        <td>${user.dept_phone}</td>

        <td>${rs.dept_name}</td>

    </tr>

</c:forEach>

 

附上数据库连接工具类代码

数据库连接配置文件:

#Oracle Connection properties

## db params (no space)

#driver=oracle.jdbc.driver.OracleDriver

#url=jdbc:oracle:thin:@172.16.3.8:1521:orcl

#user=jsd1606

#pwd=jsd1606

## DataSource params

#initSize=1

#maxSize=3

#Mysql Connection properties

# db params (no space)

driver=com.mysql.jdbc.Driver

url=jdbc:mysql://localhost:3306/数据库名称?characterEncoding=utf8

user=root

pwd=root

# DataSource params

initSize=1

maxSize=3

 

数据库连接工具类:

package day01.util;


import java.io.IOException;

import java.sql.Connection;

import java.sql.SQLException;

import java.util.Properties;


import org.apache.commons.dbcp.BasicDataSource;


public class DBUtil {


    // 声明连接池

    private static BasicDataSource ds;


    static {

        // 读取连接参数

        Properties p = new Properties();

        try {

            p.load(DBUtil.class.getClassLoader().getResourceAsStream("db.properties"));

            // 数据库连接参数

            String driver = p.getProperty("driver");

            String url = p.getProperty("url");

            String user = p.getProperty("user");

            String pwd = p.getProperty("pwd");

            // 连接池参数

            String initSize = p.getProperty("initSize");

            String maxSize = p.getProperty("maxSize");

            // 创建连接池,并给它设置参数

            ds = new BasicDataSource();

            ds.setDriverClassName(driver);

            ds.setUrl(url);

            ds.setUsername(user);

            ds.setPassword(pwd);

            ds.setInitialSize(Integer.parseInt(initSize));

            ds.setMaxActive(Integer.parseInt(maxSize));

        } catch (IOException e) {

            e.printStackTrace();

            throw new RuntimeException("找不到文件", e);

        }

    }


    public static Connection getConnection() throws SQLException {

        return ds.getConnection();

    }


/**

* 归还连接: 连接池创建的连接,其close方法不再是 关闭连接,而是将连接归还给连接池, 连接池会将此连接数据清空并标识为空闲.

*/

public static void close(Connection conn) {

    if (conn != null) {

        try {

            conn.close();

        } catch (SQLException e) {

            e.printStackTrace();

            throw new RuntimeException("归还连接失败", e);

        }

    }
}


public static void main(String[] args) throws SQLException {
    
    System.out.println(getConnection());

}

}

 

到此就能实现数据库查询结果集的转换,如果有任何问题可以加我扣扣2551449109 ,大家以前探讨,虚心求教。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值