Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
255 views
in Technique[技术] by (71.8m points)

Non Intersecting two ResultSet in Java

I have two result sets coming from two different database and I need to compare it. I want an operation like

A-B

to be performed on them.

I cannot perform row by row comparison as 1st row in A resultset can be present anywhere in B resultset.

Below is the code to do that in .NET, which is very easy and perfect .

var nonIntersecting = dtSource.AsEnumerable().Except
                      (
                        dtTarget.AsEnumerable(), DataRowComparer.Default
                      );
try
{
   dtSrcToTgtResult = nonIntersecting.CopyToDataTable();
} catch (InvalidOperationException ex) {}

Here dtSource,dtTarget are datatables having source and target data from databases. dtSrcToTgtResult contains data present in source but not in target, which is exactly what I want.

Can same be done in JavaScript with result sets. I can also check CachedRowSet or webRowSet if something like this is available in it.

EDIT

For people who are giving minus votes. this is what i already did, but its not solving the problem.

private Boolean compare(ResultSet rsSrc,ResultSet rsTgt,String ExecCondition)
    {
        Boolean status = true;
        try  
        {
            ResultSetMetaData metaSrc = rsSrc.getMetaData(); 
            ResultSetMetaData metaTgt = rsTgt.getMetaData();
            final int columnCountSrc = metaSrc.getColumnCount();
            List<DBRow> dList = new  ArrayList<DBRow>();
            List<DBRow> DataInSourceNotInTarget = new ArrayList<DBRow>();
            List<DBRow> DataInTargetNotInSource = new ArrayList<DBRow>();

            DBRow d = new DBRow();
            DBRow d1 = new DBRow();

            for (int column = 1; column <= columnCountSrc; column++) 
            {
            d.Row.add(metaSrc.getColumnName(column));
            d1.Row.add(metaTgt.getColumnName(column));
            }
            DataInSourceNotInTarget.add(d);
            DataInTargetNotInSource.add(d1);

            if(ExecCondition.equals("Source To Target"))
            {

            while(rsSrc.next())
            {

                if(rsTgt.next())
                {
                for (int column = 1; column <= columnCountSrc; column++) 
                {

                    Object valueSrc = rsSrc.getObject(column);
                    Object valueTgt = rsTgt.getObject(column);

                        if(!valueSrc.toString().equals(valueTgt.toString()))
                        {
                            status=false;
                            System.out.println("ValueSRC: "+v    alueSrc.toString());
                            System.out.println("ValueTgt: "+valueTgt.toString());
                    }

            }
            }
            else
            {
                // if target rows ends
                DBRow dr = new DBRow();

                for (int column = 1; column <= columnCountSrc; column++) 
                {

                    Object valueSrc = rsSrc.getObject(column);
                    dr.Row.add(valueSrc);
                }
                DataInSourceNotInTarget.add(dr);

            }

        }
    }//exec condition if


        if(ExecCondition.equals("Target To Source"))
        {

        while(rsTgt.next())
        {

            if(rsSrc.next())
            {
            for (int column = 1; column <= columnCountSrc; column++) 
            {

                Object valueSrc = rsSrc.getObject(column);
                Object valueTgt = rsTgt.getObject(column);

                    if(!valueSrc.toString().equals(valueTgt.toString()))
                    {
                        status=false;
                        System.out.println("ValueSRC: "+valueSrc.toString());
                        System.out.println("ValueTgt: "+valueTgt.toString());
                    }

            }
            }
            else
            {
                // if Source rows ends
                DBRow dr = new DBRow();

                for (int column = 1; column <= columnCountSrc; column++) 
                {

                    Object valueTgt = rsTgt.getObject(column);
                    dr.Row.add(valueTgt);
                }
                DataInTargetNotInSource.add(dr);

            }

        }

        for(DBRow obj:DataInTargetNotInSource)
        {
            obj.print();
        }
    }//exec condition if


    }
    catch(Exception e)
    {
        e.printStackTrace();
    }

    return status;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I have a solution that is functional but not optimal:

  1. It requires to load all rows into in-memory data structures (each ResultSet is loaded into list, each item is map of column name-value)
  2. loop on source rows' list and for every item in that list - search that it does not exist in target list (meaning o(n^2) processing)

I used Apache DbUtils to easily convert ResultSet to List.

import java.sql.*;
import java.util.*;
import java.util.stream.*;
import org.apache.commons.dbutils.handlers.MapListHandler;

try (Connection conn = DriverManager.getConnection(url, user, password)) {

    // load source table
    Statement st = conn.createStatement();
    ResultSet sourceRs = st.executeQuery("SELECT * FROM source");
    List<Map<String, Object>> sourceRows = new MapListHandler().handle(sourceRs);
    sourceRs.close();
    st.close();

    // load target table
    st = conn.createStatement();
    ResultSet targetRs = st.executeQuery("SELECT * FROM target");
    List<Map<String, Object>> targetRows = new MapListHandler().handle(targetRs);
    targetRs.close();
    st.close();

    // for every row in source, look for no match in target
    List<Map<String, Object>> diffRows = 
    sourceRows.stream()
        .filter(sourceRow -> rowExistsInTable(sourceRow, targetRows) == false)
        .collect(Collectors.toList());

    diffRows.stream().forEach(System.out::println); 

} catch (Exception e) {
    e.printStackTrace();
}

EDIT:

you will notice that the filtering of sourceRows is now done according to result of method rowExistsInTable(). I added methods to search row in table and check rows' equality without relying on java 8 lambda syntax (also added as much documentation as I could :))

/**
 * checks if {@code searchRow} exists in {@code table}
 * existence is determined according to {@code areRowsEqual} method 
 * @param searchRow {@code Map<String, Object>} where keys are column names and values are column vales 
 * @param table {@code List} of {@code Map<String, Object>} rows 
 * @return {@code true} if {@code searchRow} was found in {@code table} 
 */
public static boolean rowExistsInTable(Map<String, Object> searchRow, List<Map<String, Object>> table)
{
    for (Map<String, Object> tableRow : table) {
        if (areRowsEqual(tableRow, searchRow)) return true;
    }
    return false;
}

/**
 * checks if all of row1 columns are found with same values in row2
 * note: does not check if there is column in row2 that does not exist in row1  
 * @param row1 
 * @param row2
 * @return {@code true} if {@code row1} is equal to {@code row2}
 */
public static boolean areRowsEqual(Map<String, Object> row1, Map<String, Object> row2)
{
    // loop on row1 columns
    for (Map.Entry<String, Object> row1Column : row1.entrySet()) {
        String row1ColumnName = row1Column.getKey(); 
        Object row1ColumnValue = row1Column.getValue();
        // search row1 column in row2
        if (row2.containsKey(row1ColumnName) &&
            row2.get(row1ColumnName) != null &&
            row2.get(row1ColumnName).equals(row1ColumnValue)) {
            // row1 column was found in row2, nothing to do 
        } else {
            // row1 column was not found in row2
            return false;
        }
    }
    return true;  // all row 1 columns found in row 2
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...