3

请耐心等待新手问题,因为我正在尝试同时学习 MyBatis 和 java。我有一个需要使用线程安全变量的应用程序。基于一些研究和我对如何使用该应用程序的想法,我决定使用 CopyOnWriteArrayList 而不是 Vector。

当我从 mybatis sql 会话中调用 selectList 时,有没有办法告诉它创建一个 CopyOnWriteArrayList 作为它的返回而不是一个 ArrayList?诚然,我的配置代码是两行而不是一行,但我内心的某些东西说必须有更好的方法和/或我不是第一个遇到这种情况的人。

List<Team> teams = session.selectList("getTeamsByGameID", gameID);
List<Team> arrayListReturn = new CopyOnWriteArrayList<Team>(teams);
return arrayListReturn;

提前致谢,

4

1 回答 1

7

我知道有两种方法来处理这个问题。

选项 1:使用 Mapper 类并指定要返回的 List 类型。

定义一个映射器接口:

public interface TeamMapper {
  CopyOnWriteArrayList<Team> getTeamsByGameID();
}

您的映射器 xml 文件保持不变。执行查询的代码更改为:

TeamMapper m = session.getMapper(TeamMapper.class);
List<Team> lt = m.getTeamsByGameID();
System.out.println(lt.getClass());  
  //=> prints out "class java.util.concurrent.CopyOnWriteArrayList"


选项 2:创建一个 ResultHandler 并将其传递给session.select()方法。

在这里,您使用 ResultHandler 接口。该接口要求您覆盖一个方法,handleResult该方法会在查询进行时给出从数据库返回的每个结果。

在您的情况下,您的 ResultHandler 看起来像这样:

public class TeamResultHandler implements ResultHandler {

  private List<Team> teams = new CopyOnWriteArrayList<Team>();

  @Override
  public void handleResult(ResultContext rc) {
    countries.add((Team) rc.getResultObject());
  }

  // provide a getter so you can retrieve it when finished
  public List<Team> getTeamList() {
    return teams;
  }
}

selectList您现在可以使用 ,而不是像上面那样使用,session.select(String, ResultHandler)如下所示:

TeamResultHandler rh = new TeamResultHandler();
session.select("getTeamsByGameID", rh);
List<Team> lt = rh.getTeamList();
return lt;

此解决方案比您的解决方案更冗长(在查询代码中需要一个额外的类和三行,而不是 2 行),但它只创建一个列表,而不是两个,因此您必须决定哪个最适合您的需求。

此外,ResultHandlers 可以用于其他事情 - 确保结果以某种方式排序或过滤或其他方式,以防您需要。

于 2012-07-21T21:34:22.330 回答