需求:
同一页面显示的内容需要到2个不同的数据库a,b中查询,a的结果中的id作为条件再到b中查询。
如a的结果数据量大,需要分次到b中查询。
JDK:1.6
持久层框架:ibatis2.0
要注意的细节:
1.循环次数
2.内存占用
public PageResult queryForPageListNew(int pageSize, int pageNum,AForm queryForm)
{
// 初始化循环次数
int i = 0;
// 初始化n
int n = 200;
// 获得a表单
PageResult pr = aDAO.queryForPageResult(queryForm
.getParams(), pageSize, pageNum, A.class);
List<A> aList = pr.getResultList();
// 初始化size
int size = aList.size();
// 创建临时数组,用于存放a表单中的id
List<Long> temp = new ArrayList<Long>();
// 初始化hashmap,size*2避免hashmap resize()
Map<Long, Long> countMap = new HashMap<Long, Long>(size*2);
for (A a : aList)
{
i++;
temp.add(a.getId());
// 每n条数据查询一次数据库
if (((i + n) % n == 0 && i < size)||(i==size))
{
// 由于使用某种特殊框架自动生成DAOImpl,目前只能返回List
List<Map<String, Long>> countMapList = bDAO
.queryCountByOwnerForList(temp);
// 将查询结果放入countMap中
for (Map<String, Long> map : countMapList)
{
Long id = map.get("owner");
Long count = map.get("count");
countMap.put(id, count);
}
temp.clear();
}
}
temp = null;
for (A a : aList)
{
a.setCount(countMap.get(a.getId()));
}
countMap.clear();
countMap = null;
return pr;
}
b的ibatis SqlMap:
<select id="queryCountByOwnerForList" resultMap="resultMap.B" parameterClass="List">
select
t1.owner,
count(t1.owner) as count
from t_b t1
where
(
t1.status= 4
or t1.status=5
or t1.status=6
)
and t1.owner in
<iterate open= "(" close = ")" conjunction = ",">
#[]#
</iterate>
group by t1.owner
</select>
HashMap countMap 使用说明:
两次的查询结果,需要比对id,进行组合。2次查询的结果集均未List,如直接组合,需要做for循环的嵌套,比对方式如下:
for(A a: aList){
for(B b: countMapList){
if(a.id==b.id)
{
组合...
}
}
}
这样就要循环n的平方次,才能组合查询结果,使用HashMap只需要循环2n次
这里假定使用HashMap存取结果比List嵌套循环快(没经过测试)
改进思考:
1.hashmap初始化的值应为
大于 (int)(size/0.75)+1 且最小的2的n次方
参见:http://www.iteye.com/topic/539465
2.不知道ibatis是否支持参数为List<Object>,并获得Object的属性。如果可以,能否省掉temp?
代码初评:
1.int n = 1000;
常量应该设置为fanal static
2.int size = aList.size();
可以直接用aList.size(),没有必要再定义一个变量
3.List<Long> temp = new ArrayList<Long>();
长度也可以初始化
4.if (((i + n) % n == 0 && i < size)||(i==size))
太复杂,不容易看懂,尽量用面对对象的思想,而且i<size的条件也是多余的
5.没有考虑第一次查询aList为空的情况,程序仍在继续往下执行
初评过后的代码:
private final static int SELECT_IN_NUMBER=200;
public PageResult queryForPageListNew(int pageSize, int pageNum,
CorpClaimSetQueryForm queryForm)
{
// 获得a查询分页表单
PageResult pr = aDAO.queryForPageResult(queryForm
.getParams(), pageSize, pageNum, A.class);
List<A> aList = pr.getResultList();
// 如果cssList查询结果为空直接返回pr
if (aList.size() <= 0)
{
return pr;
}
// 创建临时数组,用于存放a表单中的id
List<Long> temp = new ArrayList<Long>(SELECT_IN_NUMBER);
// 初始化hashmap,size*2避免hashmap resize()
Map<Long, Long> countMap = new HashMap<Long, Long>(aList.size() * 2);
for (A a : aList)
{
temp.add(a.getId());
// 每n条数据查询一次数据库
if (temp.size() == SELECT_IN_NUMBER)
{
List<Map<String, Long>> countMapList = bDAO
.queryCountByOwnerForList(temp);
// 将查询结果放入countMap中
for (Map<String, Long> map : countMapList)
{
Long id = map.get("owner");
Long count = map.get("count");
countMap.put(id, count);
}
//每查询1次,清空一次temp
temp.clear();
}
}
//对temp中余留的数据进行查询
if (!temp.isEmpty())
{
List<Map<String, Long>> countMapList = bDAO
.queryCountByOwnerForList(temp);
for (Map<String, Long> map : countMapList)
{
Long id = map.get("owner");
Long count = map.get("count");
countMap.put(id, count);
}
temp.clear();
temp = null;
}
//将统计结果加入到原有的查询结果中
for (A a : aList)
{
a.setCount(countMap.get(a.getId()));
}
countMap.clear();
countMap = null;
return pr;
}
再次评审:
1.集合调用clear()之后,不需要再设置为null(方法调用完后,内存会自动释放,这些操作都没必要?)
2.一段代码中用到相同的代码2次,这段相同的代码应该提炼出来,自成一个方法
最终代码:
private final static int SELECT_IN_NUMBER = 200;
/**
* 分页查询 在原有的基础上增加数量统计,并可进行批量统计,每n条统计一次。
* @param pageSize
* @param pageNum
* @param queryForm
* @return PageResult
*/
@SuppressWarnings("unchecked")
@Override
public PageResult queryForPageListNew(int pageSize, int pageNum,
CorpClaimSetQueryForm queryForm)
{
// 获得a查询分页表单
PageResult pr = aDAO.queryForPageResult(queryForm
.getParams(), pageSize, pageNum,A.class);
List<A> aList = pr.getResultList();
// 如果aList查询结果为空直接返回pr
if (aList.size() <= 0)
{
return pr;
}
// 创建临时数组,用于存放a中的id
List<Long> temp = new ArrayList<Long>(SELECT_IN_NUMBER);
// 初始化hashmap,size*2避免hashmap resize()
Map<Long, Long> countMap = new HashMap<Long, Long>(aList.size() * 2);
for (A a : aList)
{
temp.add(a.getId());
// 每n条数据查询一次数据库
if (temp.size() == SELECT_IN_NUMBER)
{
queryAndWarpCountMap(temp, countMap);
}
}
//对temp中余留的数据进行查询
if (!temp.isEmpty())
{
queryAndWarpCountMap(temp, countMap);
}
//将统计结果加入到原有的查询结果中
for (A a : aList)
{
a.setCount(countMap.get(a.getId()));
}
return pr;
}
/**
* 根据临时ID集合,查询统计数据,并且包装到统计map中。
* 最后清空临时ID集合
* @param temp
* @param countMap
*/
private void queryAndWarpCountMap(List<Long> temp, Map<Long, Long> countMap) {
List<Map<String, Long>> countMapList = bDAO
.queryCountByOwnerForList(temp);
for (Map<String, Long> map : countMapList)
{
Long id = map.get("owner");
Long count = map.get("count");
countMap.put(id, count);
}
//每查询1次,清空一次temp
temp.clear();
}
相关推荐
大数相乘大数相加大数阶乘代码 完全解决代码简易 容易理解 有什么缺点欢迎评论 交流
大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码大数相乘算法源代码...
大数 加减乘 C++源代码 课程设计 上机实验 编程比赛 等可以使用
大数运算代码,可以用来计算各种大数运算,最高可以到2048位
C/C++实现两个大数相乘的源代码,同理可以实现两个无限小数的相乘,实现原理都是一样的。看代码就能写出来。
一个数组中第二大数的查找,很方便用户进行数据的查找,代码简单,安全移动
C语言无符号整形的大数加法和乘除法的源代码,自己编译通过,并且加有自己理解的注释!大数除法.cpp 大数乘法.cpp 大数加法.cpp
用python编程实现大数的运算,解决了RSA算法中的大数运算问题
C++版本大数阶乘原理讲解及代码实现
数据结构实习,关于线性表的应用,大数阶乘
电脑随机产生大数,实现大数相乘,密码学中用的~~~~~~
大数相乘算法,java代码,包含独立大数相加算法 其中bigNumberPlus(String s1,String s2)为大数相加方法 bigNumberMultiply(String s1,String s2)为大数相乘方法
大数阶乘如1000!无数据类型可以表示,用链表实现大数阶乘
用来计算特别大的数的加减乘除乘方什么的,理论上来说,没有位数限制,如果你的内存足够大,CPU足够强劲。 可速度却不怎么样,如有兄弟改进了,麻烦发到这上面来大家共享~~~ 采用链表实现,每个节点里放下4位,即...
两个N位大数的减法,比如两个100位甚至1000位的两个大数相减,利用此控制台程序就可以正确无误的计算出来。
该段程序使用简短的算法就可完成两个大数相乘的过程
大数计算器大数计算器大数计算器大数计算器
利用c语言写的大数加法源代码,欢迎大家下载。
大数相乘的代码及算法解析,希望对需要的人有帮助哦~
使用Java编写大数加法的程序,程序简单易懂,适合开发小白看