求一Java递归算法

时间:2021-04-18 11:15:13
现有A、B、C三张表,B为A和C的关系表。
1.先根据传入的一个A表的AID在B表中查出flag为1的C表的CID(一对多关系),然后根据查询到的CID在B表中查询flag为2的A表的AID(一对多关系)。
2.根据1中查询到的AID再重复执行1中步骤,直到查询到的AID为空为止。
3.将所查询到的所有AID放入一个数组或者List中。请将上诉算法该如何实现,麻烦附上源码,谢谢! 

8 个解决方案

#1


引用
Quote:
求一Java递归算法
dfsdf 求一Java递归算法求一Java递归算法

#2


最简单的方法就是采用递归,但是性能很低下。

如果希望采用优化的方法来做的话,需要综合考虑很多因素,A、B、C表中的数据量各有多大,并发量有多大,数据库服务器内存多大,应用服务器内存多大等综合因素。如果数据量不大的情况下,不采用递归模式,大大减少数据库读取次数将能够大大提高性能。

#3


数据量不会很大,也就5000多条数据,而且我这个是jsp页面上的一个按钮来触发查询的,数据库的交互和读取次数也不会很多!

#4


不知道这样的DEMO行不行,没有使用递归,改一下SQL应该就可以测试了。
package com.cua.testdemo;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

public class Demo42 {

    private Connection conn = null;

    protected Connection getConn() {
        return conn;
    }

    protected void setConn(Connection conn) {
        this.conn = conn;
    }

    protected boolean closeConn() {
        boolean result = Boolean.TRUE;
        try {
            if (conn != null) conn.close();
        } catch (SQLException e) {
            result = Boolean.FALSE;
        }
        return result;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        Demo42 demo = new Demo42();
        try {
            // 连接数据库
            Class.forName("org.gjt.mm.mysql.Driver");
            demo.setConn(DriverManager.getConnection("jdbc:mysql://localhost:3306/ctc", "root", "root"));
            if (demo.getConn() == null) {
                System.out.println("Connection mysql failed!");
                System.exit(0);
            }
            // 所有的AID存放入数组
            MergeList<String> allaid = new MergeList<String>();
            // 初期传入的AID
            allaid.add("A0");
            int index = -1;
            while (++index < allaid.size()) {
                allaid.mergeAddAll(demo.getDataByAid(allaid.get(index)));
            }
            // 最终所有满足条件的AID,并格式化输出
            System.out.println(allaid.join());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (!demo.closeConn()) System.out.println("close connection failed!");;
        }
    }

    /**
     * 根据AID取数据库数据
     * @param aid
     * @return
     */
    public List<String> getDataByAid(String aid) {
        PreparedStatement pst = null;
        ResultSet result = null;
        List<String> list = null;
        try {
            pst = getConn().prepareStatement("SELECT AID FROM R_A2C WHERE CID IN (SELECT CID FROM R_A2C WHERE AID = ? AND FLAG = 1) AND FLAG = 2");
            pst.setString(1, aid);
            result = pst.executeQuery();
            if (!result.wasNull()) list = new ArrayList<String>();
            while (result.next()) {
                list.add(result.getString(1));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (result != null) result.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if (pst != null) pst.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return list;
    }
}

class MergeList<T> extends ArrayList<T> {
    private static final long serialVersionUID = 1L;

    public void mergeAdd(T o) {
        if (!super.contains(o)) super.add(o);
    }

    public void mergeAddAll(Collection<? extends T> c) {
        if (c.isEmpty()) return;
        for (Iterator<? extends T> it = c.iterator(); it.hasNext();) {
            this.mergeAdd(it.next());
        }
    }

    public String join() {
        return this.join(null);
    }

    public String join(String mark) {
        if (super.isEmpty()) return "";
        if (mark == null) mark = ",";
        StringBuffer buf = new StringBuffer();
        for (Iterator<T> it = super.iterator(); it.hasNext();) {
            buf.append(it.next()).append(mark);
        }
        buf.deleteCharAt(buf.length() - 1);
        return buf.toString();
    }
}

这是测试数据
CREATE TABLE R_A2C (
AID VARCHAR(10),
CID VARCHAR(10),
FLAG INTEGER
);
INSERT INTO R_A2C VALUES ('A0', 'B1', 1);
INSERT INTO R_A2C VALUES ('A1', 'B1', 2);
INSERT INTO R_A2C VALUES ('A1', 'B0', 1);
INSERT INTO R_A2C VALUES ('A2', 'B0', 1);
INSERT INTO R_A2C VALUES ('A3', 'B2', 2);
INSERT INTO R_A2C VALUES ('A4', 'B3', 1);
INSERT INTO R_A2C VALUES ('A5', 'B4', 2);
INSERT INTO R_A2C VALUES ('A6', 'B5', 1);
INSERT INTO R_A2C VALUES ('A7', 'B0', 1);
INSERT INTO R_A2C VALUES ('A6', 'B6', 2);
INSERT INTO R_A2C VALUES ('A5', 'B0', 2);
INSERT INTO R_A2C VALUES ('A3', 'B7', 2);
INSERT INTO R_A2C VALUES ('A3', 'B5', 2);
INSERT INTO R_A2C VALUES ('A3', 'B5', 1);
INSERT INTO R_A2C VALUES ('A0', 'B0', 2);
INSERT INTO R_A2C VALUES ('A1', 'B9', 1);
INSERT INTO R_A2C VALUES ('A3', 'B3', 1);
INSERT INTO R_A2C VALUES ('A9', 'B2', 2);
INSERT INTO R_A2C VALUES ('A1', 'B0', 2);
COMMIT;

#5


上面代码我跑了下 出现以下错误:
java.sql.SQLException: 未读取数据
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:111)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:145)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:207)
at oracle.jdbc.driver.OracleStatement.wasNullValue(OracleStatement.java:3252)
at oracle.jdbc.driver.OracleResultSetImpl.wasNull(OracleResultSetImpl.java:113)
at com.njedc.dssportal.meta.Demo42.getDataByAid(Demo42.java:88)
at com.njedc.dssportal.meta.Demo42.main(Demo42.java:57)
Exception in thread "main" java.lang.NullPointerException
at com.njedc.dssportal.meta.MergeList.mergeAddAll(Demo42.java:122)
at com.njedc.dssportal.meta.Demo42.main(Demo42.java:57)

#6


求一Java递归算法用SQL比较好吧 递归太慢了吧

#7


sql的话 这里用存储过程该怎么去写呢?

#8


根据错误信息看出,报了NullPointerException
原因是因为没有抽到数据,而使用result.wasNull()方法。
修改方法:将if (!result.wasNull())判断去掉

#1


引用
Quote:
求一Java递归算法
dfsdf 求一Java递归算法求一Java递归算法

#2


最简单的方法就是采用递归,但是性能很低下。

如果希望采用优化的方法来做的话,需要综合考虑很多因素,A、B、C表中的数据量各有多大,并发量有多大,数据库服务器内存多大,应用服务器内存多大等综合因素。如果数据量不大的情况下,不采用递归模式,大大减少数据库读取次数将能够大大提高性能。

#3


数据量不会很大,也就5000多条数据,而且我这个是jsp页面上的一个按钮来触发查询的,数据库的交互和读取次数也不会很多!

#4


不知道这样的DEMO行不行,没有使用递归,改一下SQL应该就可以测试了。
package com.cua.testdemo;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

public class Demo42 {

    private Connection conn = null;

    protected Connection getConn() {
        return conn;
    }

    protected void setConn(Connection conn) {
        this.conn = conn;
    }

    protected boolean closeConn() {
        boolean result = Boolean.TRUE;
        try {
            if (conn != null) conn.close();
        } catch (SQLException e) {
            result = Boolean.FALSE;
        }
        return result;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        Demo42 demo = new Demo42();
        try {
            // 连接数据库
            Class.forName("org.gjt.mm.mysql.Driver");
            demo.setConn(DriverManager.getConnection("jdbc:mysql://localhost:3306/ctc", "root", "root"));
            if (demo.getConn() == null) {
                System.out.println("Connection mysql failed!");
                System.exit(0);
            }
            // 所有的AID存放入数组
            MergeList<String> allaid = new MergeList<String>();
            // 初期传入的AID
            allaid.add("A0");
            int index = -1;
            while (++index < allaid.size()) {
                allaid.mergeAddAll(demo.getDataByAid(allaid.get(index)));
            }
            // 最终所有满足条件的AID,并格式化输出
            System.out.println(allaid.join());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (!demo.closeConn()) System.out.println("close connection failed!");;
        }
    }

    /**
     * 根据AID取数据库数据
     * @param aid
     * @return
     */
    public List<String> getDataByAid(String aid) {
        PreparedStatement pst = null;
        ResultSet result = null;
        List<String> list = null;
        try {
            pst = getConn().prepareStatement("SELECT AID FROM R_A2C WHERE CID IN (SELECT CID FROM R_A2C WHERE AID = ? AND FLAG = 1) AND FLAG = 2");
            pst.setString(1, aid);
            result = pst.executeQuery();
            if (!result.wasNull()) list = new ArrayList<String>();
            while (result.next()) {
                list.add(result.getString(1));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (result != null) result.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if (pst != null) pst.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return list;
    }
}

class MergeList<T> extends ArrayList<T> {
    private static final long serialVersionUID = 1L;

    public void mergeAdd(T o) {
        if (!super.contains(o)) super.add(o);
    }

    public void mergeAddAll(Collection<? extends T> c) {
        if (c.isEmpty()) return;
        for (Iterator<? extends T> it = c.iterator(); it.hasNext();) {
            this.mergeAdd(it.next());
        }
    }

    public String join() {
        return this.join(null);
    }

    public String join(String mark) {
        if (super.isEmpty()) return "";
        if (mark == null) mark = ",";
        StringBuffer buf = new StringBuffer();
        for (Iterator<T> it = super.iterator(); it.hasNext();) {
            buf.append(it.next()).append(mark);
        }
        buf.deleteCharAt(buf.length() - 1);
        return buf.toString();
    }
}

这是测试数据
CREATE TABLE R_A2C (
AID VARCHAR(10),
CID VARCHAR(10),
FLAG INTEGER
);
INSERT INTO R_A2C VALUES ('A0', 'B1', 1);
INSERT INTO R_A2C VALUES ('A1', 'B1', 2);
INSERT INTO R_A2C VALUES ('A1', 'B0', 1);
INSERT INTO R_A2C VALUES ('A2', 'B0', 1);
INSERT INTO R_A2C VALUES ('A3', 'B2', 2);
INSERT INTO R_A2C VALUES ('A4', 'B3', 1);
INSERT INTO R_A2C VALUES ('A5', 'B4', 2);
INSERT INTO R_A2C VALUES ('A6', 'B5', 1);
INSERT INTO R_A2C VALUES ('A7', 'B0', 1);
INSERT INTO R_A2C VALUES ('A6', 'B6', 2);
INSERT INTO R_A2C VALUES ('A5', 'B0', 2);
INSERT INTO R_A2C VALUES ('A3', 'B7', 2);
INSERT INTO R_A2C VALUES ('A3', 'B5', 2);
INSERT INTO R_A2C VALUES ('A3', 'B5', 1);
INSERT INTO R_A2C VALUES ('A0', 'B0', 2);
INSERT INTO R_A2C VALUES ('A1', 'B9', 1);
INSERT INTO R_A2C VALUES ('A3', 'B3', 1);
INSERT INTO R_A2C VALUES ('A9', 'B2', 2);
INSERT INTO R_A2C VALUES ('A1', 'B0', 2);
COMMIT;

#5


上面代码我跑了下 出现以下错误:
java.sql.SQLException: 未读取数据
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:111)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:145)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:207)
at oracle.jdbc.driver.OracleStatement.wasNullValue(OracleStatement.java:3252)
at oracle.jdbc.driver.OracleResultSetImpl.wasNull(OracleResultSetImpl.java:113)
at com.njedc.dssportal.meta.Demo42.getDataByAid(Demo42.java:88)
at com.njedc.dssportal.meta.Demo42.main(Demo42.java:57)
Exception in thread "main" java.lang.NullPointerException
at com.njedc.dssportal.meta.MergeList.mergeAddAll(Demo42.java:122)
at com.njedc.dssportal.meta.Demo42.main(Demo42.java:57)

#6


求一Java递归算法用SQL比较好吧 递归太慢了吧

#7


sql的话 这里用存储过程该怎么去写呢?

#8


根据错误信息看出,报了NullPointerException
原因是因为没有抽到数据,而使用result.wasNull()方法。
修改方法:将if (!result.wasNull())判断去掉