java解析字符串,按照树形结构存入数据库--这个问题纠结了我好久,各路大神求帮忙

[color=red][b][size=large]字符串:[/size][/b][/color]
LDAP://gz.cvte.cn/CN=张三,OU=研发中心,OU=事业部,OU=AAA有限公司,OU=C集团
LDAP://gz.cvte.cn/CN=tom,OU=销售部,OU=事业部,OU=AAA有限公司,OU=C集团
......
[color=red]
[b][size=large]表结构:(可以修改,反正能体现到树状结构就好了)[/size][/b][/color]
id
name:名称
fatherId: 父Id
type:类型(人员,公司,部门)

[size=large][color=red]问题:解析上述字符串,然后按照下列树状形式存入数据库,数据库不限。
PS:【上述字符串中 人员的名字, 集团的名字, xxx有限公司的名字都是唯一的】
[/color][/size]
[code="java"] C集团 (公司)
|-AA有限公司 (公司)
| |-电源事业部门 (部门)
| |-研发中心 (部门)
| |-张三 (人员)
|
|-BBB公司 (公司)
|-研发中心 (部门)
|-李四 (人员)[/code]

请求大神解答,我弄了两天都没弄出来。。哎哎呀呀呀呀呀。。

6个回答

for (int i = strs.length - 1; i > -1; i--) {
String str = strs[i];
/*
* 这里是从root向下插入,所以如果遇到节点已经存在的情况
* 执行查询select count(1) from test where name = nodeName and type = nodeType
/
if (node存在) {
continue; // 不再创建重复节点
}
/

* 这里需要判断需要创建节点的父节点
/
if (i < strs.length - 1) {
String parent = strs[i + 1];
/

* 执行查询select id from test where name = parentName and type = parentType
* 找到父ID
*/
}
if (父id > 0) {
stmt.executeUpdate("insert into test(id, name, parentid, type) values(null, '"
+ str.substring(str.indexOf("=") + 1)
+ "', " + 父id + ", '"
+ str.substring(0, str.indexOf("=")) + "');");
conn.commit();
} else {
stmt.executeUpdate("insert into test(id, name, parentid, type) values(null, '"
+ str.substring(str.indexOf("=") + 1)
+ "', 0, '"
+ str.substring(0, str.indexOf("=")) + "');");
conn.commit();
}
}

QiangGe2Dai
QiangGe2Dai 是的,你给的条件本来就很少,而这里判断的是树结构,所以增加了空间复杂度。还没用过n叉树这么高深的算法,你可以研究研究然后教教我,^_^
7 年多之前 回复
woaitengyu01
woaitengyu01 哥们,这样弄好像只能判定到某一个支点的父亲,但是还没判断到他的爷爷。。oh,这么麻烦。。要不能不能搞个面向对象的n叉树来呢?感谢你啊,哥们,就你这么热心帮助我。
7 年多之前 回复
QiangGe2Dai
QiangGe2Dai /* * 这里是从root向下插入,所以如果遇到节点已经存在的情况 * 执行查询select count(1) from test where name = nodeName and type = nodeType */ if (node存在) { continue; // 不再创建重复节点 } 这段判断的代码修改一下,参考: if (i == strs.length - 1) { // root节点处理 /* * 执行查询select * from test where name = nodeName and type = nodeType * 返回node */ if (node.parentid == 0) { // root不用重新创建 continue; } } else { /* * 执行查询select * from test where name = nodeName and type = nodeType * 返回node */ if (node.parentid > 0) { // 非root节点 /* * 执行查询select * from test where id = node.parentid * 返回parentnode父节点 */ String currentparent = stirs[i + 1]; // 当前父节点 if (parentnode.name = currentparent.indexof(XXX) && parentnode.type = currentparent.indexof(XXX)) { continue; // 同一结构,此时节点无需创建 } } }
7 年多之前 回复
woaitengyu01
woaitengyu01 不好意思哈,我之前说错了,我想不修改数据设计。就按照上面我那个设计来实现咧,就麻烦你帮我一下哈,我也一直在努力的想。希望我不会想到晕过去。。
7 年多之前 回复
QiangGe2Dai
QiangGe2Dai 最简单的修改就是数据设计上做文章,比如:AA公司--电源事业部门--研发中心;BB公司--直属研发中心,如果你不想这么设计,也可以从程序上来看。我现在有点儿,稍后帮你想想。
7 年多之前 回复
QiangGe2Dai
QiangGe2Dai 你不是在ps中说唯一的吗?现在又重复了?
7 年多之前 回复
woaitengyu01
woaitengyu01 哥们,我现在遇到一个新的问题,就是能成功弄成一个树了,但是如果叶子中有重复的话,只插入第一个,另外一个就不插入。比如上面: 1、AA公司--电源事业部门--研发中心-张三 2、BB公司--研发中心--李四 插入数据库之后,数据库中只有一个【研发中心】,张三的联接关系是对的,但是李四却连过去到张三那个【研发中心】了,这个该怎么判断?我一直在想想想想,有点晕了。。请帮帮我,我现在脑子好晕。。
7 年多之前 回复

/* 这种方式顺序就是实现关系的依据 /
String str = "CN=张三,OU=研发中心,OU=事业部,OU=AAA有限公司,OU=C集团";
String[] strs = str.split(",");
for (int i = 0; i < strs.length; i++) {
String son = strs[i];
if (i < strs.length - 1) {
String parent = strs[i + 1];
System.out.println(son + "<--->" + parent);
/

* CN=张三<--->OU=研发中心
* OU=研发中心<--->OU=事业部
* OU=事业部<--->OU=AAA有限公司
* OU=AAA有限公司<--->OU=C集团
/
} else {
System.out.println(son + "<--->ROOT");
/

* OU=C集团<--->ROOT
*/
}
}

woaitengyu01
woaitengyu01 哥们,给个完整的插入数据库的代码怎么样?我纠结了好久,还是没办法按照上面的图那样,插入数据库中去。感谢你感谢你
7 年多之前 回复

闲来没事,就帮你写写。
先说说表结构,就用你这个结构
id:(自动增长)
name:名称
parentid:父ID
type:类型(人员,公司,部门)
使用DB------MYSQL5.0

String connectionUrl = "jdbc:mysql://localhost:3306/数据库名称?user=用户名&password=密码";
Connection conn = null;
Statement stmt = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(connectionUrl);
conn.setAutoCommit(false);
stmt = conn.createStatement();
String[] strs = "CN=张三,OU=研发中心,OU=事业部,OU=AAA有限公司,OU=C集团".split(",");
for (int i = strs.length - 1; i > -1; i--) { // 先有父类才有子类,所以倒过来写
String str = strs[i];
if (i == strs.length - 1) { // 创建ROOT
stmt.executeUpdate("insert into test(id, name, parentid, type) values(null, '"
+ str.substring(str.indexOf("=") + 1)
+ "', 0, '"
+ str.substring(0, str.indexOf("=")) + "')");
conn.commit();
} else { // 创建所有叶节点
stmt.executeUpdate("insert into test(id, name, parentid, type) values(null, '"
+ str.substring(str.indexOf("=") + 1)
+ "', @@IDENTITY, '"
+ str.substring(0, str.indexOf("=")) + "');");
conn.commit();
}
}
} catch (Exception e) {
// 异常处理
} finally {
// 关闭连接,释放资源
}

QiangGe2Dai
QiangGe2Dai 关键其实就是保证你的字符串的顺序,所以这么做只是一个特列,没有扩展性哈。还要读文本啊,等哈嘛
7 年多之前 回复
QiangGe2Dai
QiangGe2Dai 直接用这个替换就可以了 stmt.executeUpdate("insert into test(id, name, parentid, type) values(null, '" + str.substring(str.indexOf("=") + 1) + "', @@IDENTITY, '" + str.substring(0, str.indexOf("=")) + "');"); conn.commit();
7 年多之前 回复
QiangGe2Dai
QiangGe2Dai mysql中以下代码是可以合并的 if (i == strs.length - 1) { // 创建ROOT stmt.executeUpdate("insert into test(id, name, parentid, type) values(null, '" + str.substring(str.indexOf("=") + 1) + "', 0, '" + str.substring(0, str.indexOf("=")) + "')"); conn.commit(); } else { // 创建所有叶节点 stmt.executeUpdate("insert into test(id, name, parentid, type) values(null, '" + str.substring(str.indexOf("=") + 1) + "', @@IDENTITY, '" + str.substring(0, str.indexOf("=")) + "');"); conn.commit(); }
7 年多之前 回复
woaitengyu01
woaitengyu01 对了,哥们,这两个字符串,是从txt文件里面提取。能帮忙做一个从txt读取,然后解析,然后在树状存入数据库么??
7 年多之前 回复
woaitengyu01
woaitengyu01 犀利,哥们,能不能给个稍微完整程序咧,从解析上面两条字符串,然后按照树形结构存入数据库(这里我攻破不了。。),哥们,能帮我写写么?我现在真得给这题目弄倒了。。55555,很感谢感谢你啊
7 年多之前 回复

File file = new File(文件路径);
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line = null;
List lists = new ArrayList();
while(null != (line = br.readLine())) {
lists.add(line);
}
return lists;
} catch (FileNotFoundException e) {

    } catch (IOException e) {

    }

/*
* 主要就这两个方法了
*/
public void mainMethod() {
List list = readFile(文件路径);
for (String s : list) {
inDB(s);
}
}

public List<String> readFile(String path) {
    File file = new File(path); // 文件路径
    try {
        BufferedReader br = new BufferedReader(new FileReader(file));
        String line = null;
        List<String> lists = new ArrayList<String>();
        while(null != (line = br.readLine())) {
            lists.add(line);
        }
        return lists; 
    } catch (FileNotFoundException e) {

    } catch (IOException e) {

    }
}

public void inDB(String str) {
    String connectionUrl = "jdbc:mysql://localhost:3306/数据库名称?user=用户名&password=密码"; 
    Connection conn = null; 
    Statement stmt = null; 
    try { 
    Class.forName("com.mysql.jdbc.Driver"); 
    conn = DriverManager.getConnection(connectionUrl); 
    conn.setAutoCommit(false); 
    stmt = conn.createStatement(); 
    String[] strs = str.split(","); 
    for (int i = strs.length - 1; i > -1; i--) {
    String str = strs[i]; 
    stmt.executeUpdate("insert into test(id, name, parentid, type) values(null, '" 
            + str.substring(str.indexOf("=") + 1) 
            + "', @@IDENTITY, '" 
            + str.substring(0, str.indexOf("=")) + "');"); 
            conn.commit(); 
    } 
    } catch (Exception e) { 
    // 异常处理 
    } finally { 
    // 关闭连接,释放资源 
    }
}
QiangGe2Dai
QiangGe2Dai 因为是读取每行数据,所以index越界,这是可以通过程序去判断的。反正大概思路我已经给你说了,就是每插入一个节点的时候首要要判断该节点是否存在,若存在则无视;若不存在,就去取这个节点的父节点,如果父节点不存在那么这个节点就是root(没有父节点);如果存在则按实际关系插入数据即可,希望对你有所帮助
7 年多之前 回复
woaitengyu01
woaitengyu01 我查到错误了,是因为我的txt文件后面不小心打了很多的换行,,我删除就好了。我现在继续研究去。
7 年多之前 回复
woaitengyu01
woaitengyu01 那个str.substring(0, str.indexOf("=")) + "');报java.lang.StringIndexOutOfBoundsException: String index out of range: -1异常,这个怎么弄呢,我在反复的查,但是没查到原因。我的基础比较水,别介意我多问哈,我是很想弄出以树状结构存入数据库的,而且重复的名称只出现一次那种效果,我想了好久,也百度谷歌了很久,还是没法搞成。。。5555
7 年多之前 回复
QiangGe2Dai
QiangGe2Dai 公司无法外网,qq不了。是的我说了,这是特例,每条记录就会有棵树,我只是给你提供一个大致的方向参考,要扩张还需要你根据自身项目用途修改
7 年多之前 回复
woaitengyu01
woaitengyu01 哥们,我拿你的代码试了一下,数据库那边会插多查入10多行数据,而且数据库那边还会重复输入已存在的名字,关于这个问题,能帮我解决一下么?这里我感觉好难啊,哥们,要不加我QQ帮帮我一下如何?
7 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐