1.先根据传入的一个A表的AID在B表中查出flag为1的C表的CID(一对多关系),然后根据查询到的CID在B表中查询flag为2的A表的AID(一对多关系)。
2.根据1中查询到的AID再重复执行1中步骤,直到查询到的AID为空为止。
3.将所查询到的所有AID放入一个数组或者List中。请将上诉算法该如何实现,麻烦附上源码,谢谢!
8 个解决方案
#1
#2
最简单的方法就是采用递归,但是性能很低下。
如果希望采用优化的方法来做的话,需要综合考虑很多因素,A、B、C表中的数据量各有多大,并发量有多大,数据库服务器内存多大,应用服务器内存多大等综合因素。如果数据量不大的情况下,不采用递归模式,大大减少数据库读取次数将能够大大提高性能。
如果希望采用优化的方法来做的话,需要综合考虑很多因素,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)
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
用SQL比较好吧 递归太慢了吧
#7
sql的话 这里用存储过程该怎么去写呢?
#8
根据错误信息看出,报了NullPointerException
原因是因为没有抽到数据,而使用result.wasNull()方法。
修改方法:将if (!result.wasNull())判断去掉
原因是因为没有抽到数据,而使用result.wasNull()方法。
修改方法:将if (!result.wasNull())判断去掉
#1
#2
最简单的方法就是采用递归,但是性能很低下。
如果希望采用优化的方法来做的话,需要综合考虑很多因素,A、B、C表中的数据量各有多大,并发量有多大,数据库服务器内存多大,应用服务器内存多大等综合因素。如果数据量不大的情况下,不采用递归模式,大大减少数据库读取次数将能够大大提高性能。
如果希望采用优化的方法来做的话,需要综合考虑很多因素,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)
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
用SQL比较好吧 递归太慢了吧
#7
sql的话 这里用存储过程该怎么去写呢?
#8
根据错误信息看出,报了NullPointerException
原因是因为没有抽到数据,而使用result.wasNull()方法。
修改方法:将if (!result.wasNull())判断去掉
原因是因为没有抽到数据,而使用result.wasNull()方法。
修改方法:将if (!result.wasNull())判断去掉