我们可以从数据库中查询出相应的要更新的数据集合,这里我们叫它持久化数据集合,如果说要查找出与导入的数据集合中相应的数据,使用双重循环也是不错的选择。先循环导入的数据集合,然后拿当前遍历到的数据再来一个循环去持久化数据集合中查找对应的对象。但是一般建议不这样做,使用二分法(折半查找)替代双重循环要好的多。下面一个小demo演示了如何使用二分法在集合中查找相应的对象。
public class User implements Comparable<User>, Serializable{ private static final long serialVersionUID = -5410921420480739669L; private String name; // 姓名 private String nationalIdentifier; // 身份证号码 /** * 实现Comparable接口的compareTo方法,该方法表示传入的对象与当前对象谁大谁小 * 传入的参数对象u的属性nationalIdentifier大于当前对象的natioanlIdentifier返回正数 * 否则返回负数,相等返回0(有兴趣的朋友可以查看String类的源码) * 使用二分法在集合中查询某个元素的前提是该集合已经排序好了,如果要查找的元素是自定义类,则必须实现Comparable接口并实现compareTo接口 */ @Override public int compareTo(User u) { if(u != null) // 调用了String类的compareTo方法 return this.nationalIdentifier.compareTo(u.nationalIdentifier); return -1; } /** * 重写Object类的equals方法 * 在这里两个User对象的姓名和身份证号码相等表示这两个User对象相等 */ @Override public boolean equals(Object obj){ User u = (User) obj; if( this.name.equals(u.name) && this.nationalIdentifier.equals(u.nationalIdentifier) ) { return Boolean.TRUE; } return Boolean.FALSE; } public User(String _name, String _nationalIdentifier){ this.name = _name; this.nationalIdentifier = _nationalIdentifier; } // ... 其他代码 }
public class Application{ public static void main(String[] args) { // 假设这里的iList是要导入的Excel数据集合 iList = import list List<User> iList = new ArrayList<User>(2); iList.add(new User("学点啥小许", "www.xuediansha.com/city.php?ename=shenzhen")); iList.add(new User("学点啥小周", "www.xuediansha.com/city.php?ename=guangzhou")); // 这里假设pList是从数据库中查询的持久化集合 pList = persistent list List<User> pList = new ArrayList<User>(6); pList.add(new User("学点啥老武", "www.xuediansha.com/city.php?ename=xian")); pList.add(new User("学点啥老周", "www.xuediansha.com/city.php?ename=beijing")); pList.add(new User("学点啥老许", "www.xuediansha.com/city.php?ename=shanghai")); pList.add(new User("学点啥小许", "www.xuediansha.com/city.php?ename=shenzhen")); // 在使用二分法在集合中查找某个元素需要将该集合进行排序,使用Collections工具类的sort方法即可 Collections.sort(pList); // cUser = current user User cUser; // eUser = each User for(User eUser : iList) { cUser = binarySearch(pList, eUser); if(cUser != null) { System.out.println(cUser.getName()); // ... 其他操作 } } } /** * 使用二分法在list集合中查找user对象 * @param list 传入的持久化数据集合 * @param user 要查询的对象 * @return */ public static User binarySearch(List<User> list, User user) { // curPos = current position int curPos; // startPos = start position int startPos = 0; // endPos = end position int endPos = list.size() - 1; // cUser = current user User cUser; int counts = 0; while(true) { // curPos = current position curPos = (startPos + endPos) / 2; cUser = list.get(curPos); if(user.equals(cUser)) { System.out.printf("查找了%d次\n", counts); return cUser; } else if (endPos < startPos) { return (cUser = null); } else { if(user.compareTo(cUser) > 0) { startPos = curPos + 1; } else { endPos = curPos - 1; } } counts++; } } }
当然了,执行这样的批量更新操作,在将持久化数据查询出来的同时最好锁定这些数据,至于使用何种锁机制,根据不同系统业务来做决定(悲观锁/乐观锁)。