你的数据结构似乎没设计好,
GroupTable里为什么不用010101这样的形式分层?这样就可以使用一条语句了
SELECT uid,gid FROM UserTable WHERE gid like '01' + '%' and uid IN (uid集合)
以你现在这样的结构,我想是不是只有先在程序里找到GroupTable里某个gid下的所有的子Group再去使用select查询了,你这关键是找子Group
GroupTable里为什么不用010101这样的形式分层?这样就可以使用一条语句了
SELECT uid,gid FROM UserTable WHERE gid like '01' + '%' and uid IN (uid集合)
以你现在这样的结构,我想是不是只有先在程序里找到GroupTable里某个gid下的所有的子Group再去使用select查询了,你这关键是找子Group
解决方案 »
- 在facebook注册api失败,在填写验证码后,提示信息说我的时假账号,手机也验证过了,怎么办啊,就这一步了
- Java模仿系统的目录,有人做过吗
- 读取exe文件,生成汇编代码 in java?
- 我用JCreator写了若干个类,可不知怎样把它们组装成一个可执行的应用程序!请高手指点!
- java控制Excel问题,请高手指教
- Java 英语音标无法显示。
- java初学者的问题,求大神指点
- 菜鸟问题---applet中的Runable方法,
- 一个菜鸟的问题,很弱智的。
- web.xml <filter-mapping> 我不想过滤html文件,怎么设置呢?
- 一个关于APPLET的调用问题
- 读写Excel,POI-HSSF会破坏公式,换JXL不会,为何?(有源码)
SELECT ... FROM ... WHERE pid=uid应该可以的啊,
这个集合将被用做其他查询的查询条件。
或者……我自己也有点晕了……简化一下问题吧:求:Group树中某个node的所有子孙(就是只要获得某Group的所有各级子Group, <b>只用SQL语句可否实现?</b>)>_<!
pxboy:
你这关键是找子Group
----
好像是这样,能否只用sql实现呢?实在不行只好写存储过程做递归了……
可以用两步完成:
1、找到所有子组(包括n级子组)。
2、找出这些组的所有成员。(select .. from ..where in(<所有组和子组>)
第一步可以这样实现:
取出所有GroupTable对象,放入数组(a1)
做一个动态增长数组(a2,如ArrayList),把要查找的组放入
int i = 0;
for(;i<a2.length;i++)
{
for(int j=0;j<a1.length;i++)
{
如果是a2当前对象(组)的子组(直接子组,也就是a1的pid=a2的gid)
把它放入a2中;
}
}
a2就是当前组的所有子组,然后你就可以拼一个字符串了。
群组下子组对应的连接表:TBL_GROUPSUPER
群组下个人对应的连接表:TBL_PERSONGROUP /**
* 得到所有的叶子(个人ID)
* @param groupid 群组ID注意:groupid前面必须有G
* @return 所有的叶子(个人ID)
*/
static public Vector getSonGroup(String groupid)
{
if (groupid == null || groupid.trim().charAt(0) != 'G')
{
return null;
}
Vector retvector = new Vector();
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
if (ButtonType.DEBUGSWITCH) //test
{
System.out.println("groupid:" + groupid);
}
String strSql = getSQL(groupid.substring(1, groupid.length()));
Vector tmpvector = new Vector();
DBConnectionManager connMgr = DBConnectionManager.getInstance();
try
{
conn = connMgr.getConnection();
//Class.forName( "com.microsoft.jdbc.sqlserver.SQLServerDriver" );
//conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://192.168.0.37;User=sa;Password=;DatabaseName=PortalDB_new;SelectMethod=cursor","sa","" );
if (conn == null) //如果得不到数据库连接
{
return null;
}
stat = conn.createStatement();
rs = stat.executeQuery(strSql);
while (rs.next())
{ //得到标志+ID 如:G001;P001等
tmpvector.add(rs.getString("FLAG") + rs.getString("SON"));
}
if (tmpvector == null)
{
return null;
}
else
{
retvector = getAllSon(tmpvector); //得到所有的叶子(个人ID)
}
}
catch (Exception ex)
{
if (ButtonType.DEBUGSWITCH) //test
{
ex.printStackTrace();
}
retvector = null;
String strErrorMsg = ex.getMessage();
if (strErrorMsg.indexOf(TypeConstants.DB_RESET) > 0)
{
connMgr.destroyAll();
// el.writeOperLog("重新加载数据库连接池!");
} }
finally
{
try
{
if (rs != null)
{
rs.close();
rs = null;
}
if (stat != null)
{
stat.close();
stat = null;
}
}
catch (SQLException sqle)
{
if (ButtonType.DEBUGSWITCH) //test
{
sqle.printStackTrace();
} retvector = null;
}
if (conn != null)
{
connMgr.freeConnection(conn);
}
}
return retvector;
}
* 递归函数得到叶子(个人ID)
* @param vector 包含子组的数组
* @return 解析了下层组的数组
*/
static private Vector getAllSon(Vector vector)
{
if (vector == null)
{
return null;
}
Vector retvector = new Vector(); int iCount = vector.size();
String sTmpID = "";
for (int i = 0; i < iCount; i++)
{
sTmpID = (String) vector.elementAt(i);
if (sTmpID.charAt(0) == 'P') //如果是个人,添加到返回数组中
{
retvector.add(sTmpID);
}
else if (sTmpID.charAt(0) == 'G') //如果是群组
{
sTmpID = sTmpID.substring(1, sTmpID.length()); //得到群组ID Connection conn2 = null;
Statement stat = null;
ResultSet rs = null;
Vector tmpvector = new Vector();
String sTmpSon = "";
int iTmpCount = 0;
boolean bool = false; //是否还有子组的标志 //得到查询得sql语句
String strSql = getSQL(sTmpID);
DBConnectionManager connMgr = DBConnectionManager.getInstance();
try
{
conn2 = connMgr.getConnection();
//Class.forName( "com.microsoft.jdbc.sqlserver.SQLServerDriver" );
//conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://192.168.0.37;User=sa;Password=;DatabaseName=PortalDB_new;SelectMethod=cursor","sa","" ); if (conn2 == null)
{
return null;
}
stat = conn2.createStatement();
rs = stat.executeQuery(strSql);
while (rs.next())
{ //加入所有的
sTmpSon = rs.getString("FLAG") + rs.getString("SON");
if (sTmpSon.charAt(0) == 'P') //个人,添加到返回数组中
{
retvector.add(sTmpSon);
}
else if (sTmpSon.charAt(0) == 'G') //如果还有儿子组,添加到临时数组(存储组成员"G")
{
bool = true;
tmpvector.add(sTmpSon);
}
}
if (bool) //如果还有儿子组,则继续循环查询
{
Vector tmpvector2 = null;
//根据存储组"G"临时数组,得到所有的叶子(个人ID数组)
tmpvector2 = getAllSon(tmpvector); //将得到的叶子("P"个人ID加入到返回数组中)
if (tmpvector2 != null)
{
int itmpsize = tmpvector2.size();
for (int j = 0; j < itmpsize; j++)
{
retvector.add( (String) tmpvector2.elementAt(j));
}
}
}
//bool = false;//重置标志
}
catch (Exception ex)
{
if (ButtonType.DEBUGSWITCH) //test
{
ex.printStackTrace();
}
retvector = null;
String strErrorMsg = ex.getMessage();
if (strErrorMsg.indexOf(TypeConstants.DB_RESET) > 0)
{
connMgr.destroyAll();
// el.writeOperLog("重新加载数据库连接池!");
} }
finally
{
try
{
if (rs != null)
{
rs.close();
rs = null;
}
if (stat != null)
{
stat.close();
stat = null;
}
}
catch (SQLException sqle)
{
if (ButtonType.DEBUGSWITCH) //test
{
sqle.printStackTrace();
} retvector = null;
}
if (conn2 != null)
{
connMgr.freeConnection(conn2);
}
}
}
}
return retvector;
} /**
* 得到查询的sql语句
* @param groupid 群组ID(没有前缀标志"G")
* @return
*/
static private String getSQL(String groupid)
{
int igroupid = 0;
try
{
igroupid = Integer.parseInt(groupid);
}
catch (Exception ex)
{
igroupid = 0;
} StringBuffer strSql = new StringBuffer();
strSql.append("SELECT SUPERGROUPID AS FATHER,GROUPID AS SON,FLAG FROM");
strSql.append(" ( ");
strSql.append(" SELECT SUPERGROUPID,GROUPID,'G' AS FLAG FROM TBL_GROUPSUPER ");
strSql.append(" UNION ALL ");
strSql.append(" SELECT GROUPID,ID,'P' AS FLAG FROM TBL_PERSONGROUP");
strSql.append(" ) AS A ");
strSql.append(" WHERE SUPERGROUPID='" + igroupid + "'");
return strSql.toString();
}
}
SELECT uid,gid FROM UserTable WHERE gid like '01' + '%' and uid IN (uid集合)
这样好处真的是很多,原来我也喜欢用父ID的方式,其实感觉很麻烦
我以前做无穷树的时候也是用父ID方式,我使用两层循环(vector的外层循环不断随着搜索而改变长度)或递归实现
==================================================================================这个也就是我说的那种方法,两层循环。
如果用递归实现,你要考虑系统的资源消耗和效率。
我认为如果不动表结构,两层循环是最有效的解决办法。
uid我是在显示树形结构的同时,顺便得到的
SELECT FROM WHERE uid IN ('user1','user2','user3'.......即获得的全部子uid的集合拼出的字符串)
括号里的东西太长了是否会有问题?