浏览 14827 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-05-21
最后修改:2009-08-11
最近做了很多动态的查询,尤其是排序,以及一些状态字段,所以就做了一个总的动态查询,以不变应万变,呵呵
ibatis 里面的sql代码: <select id="getTopics" resultClass="topic" parameterClass="map"> <![CDATA[ select * from p_Topic ]]> <dynamic prepend=" WHERE "> <isPropertyAvailable property="authorId"> <isNotNull property="authorId" prepend=" and "> authorId=#authorId# </isNotNull> </isPropertyAvailable> <isPropertyAvailable property="marketId"> <isNotNull property="marketId" prepend=" and "> marketId=#marketId# </isNotNull> </isPropertyAvailable> <isPropertyAvailable property="isDelete"> <isNotNull property="isDelete" prepend=" and "> isDelete=#isDelete# </isNotNull> </isPropertyAvailable> <isPropertyAvailable property="isBest"> <isNotNull property="isBest" prepend=" and "> isBest=#isBest# </isNotNull> </isPropertyAvailable> <isPropertyAvailable property="statusStr"> <isNotNull property="statusStr" prepend=" and "> $statusStr$ </isNotNull> </isPropertyAvailable> <isPropertyAvailable property="marketIdList"> <isNotNull property="marketIdList" prepend=" and marketId in "> <iterate property="marketIdList" conjunction="," close=")" open="("> #marketIdList[]# </iterate> </isNotNull> </isPropertyAvailable> </dynamic> <dynamic prepend=" order by "> <isPropertyAvailable property="orderStr"> <isNotNull property="orderStr"> $orderStr$ </isNotNull> </isPropertyAvailable> </dynamic> <dynamic> <isPropertyAvailable property="begin"> <isNotNull property="begin"> limit #begin# </isNotNull> </isPropertyAvailable> <isPropertyAvailable property="max" prepend=" , "> <isNotNull property="max"> #max# </isNotNull> </isPropertyAvailable> </dynamic> </select> <select id="getTopicCount" resultClass="java.lang.Long" parameterClass="map"> <![CDATA[ select count(id) from p_Topic ]]> <dynamic prepend=" WHERE "> <isPropertyAvailable property="authorId"> <isNotNull property="authorId" prepend=" and "> authorId=#authorId# </isNotNull> </isPropertyAvailable> <isPropertyAvailable property="marketId"> <isNotNull property="marketId" prepend=" and "> marketId=#marketId# </isNotNull> </isPropertyAvailable> <isPropertyAvailable property="isDelete"> <isNotNull property="isDelete" prepend=" and "> isDelete=#isDelete# </isNotNull> </isPropertyAvailable> <isPropertyAvailable property="isBest"> <isNotNull property="isBest" prepend=" and "> isBest=#isBest# </isNotNull> </isPropertyAvailable> <isPropertyAvailable property="statusStr"> <isNotNull property="statusStr" prepend=" and "> $statusStr$ </isNotNull> </isPropertyAvailable> <isPropertyAvailable property="marketIdList"> <isNotNull property="marketIdList" prepend=" and "> <iterate property="marketIdList" conjunction="," close=")" open=" marketId in ("> #marketIdList[]# </iterate> </isNotNull> </isPropertyAvailable> </dynamic> </select> 这里需要注意的是: ①#xxx# 代表xxx是属性值,map里面的key或者是你的pojo对象里面的属性,ibatis会自动在它的外面加上引号,表现在sql语句是这样的 where xxx = 'xxx' ; 而$xxxx$ 则是把xxxx作为字符串拼接到你的sql语句中,比如 order by topicId , 如果你不用$来拼接而用#的话,外面就会被加上引号的哦 比如你的语句这样写 ... order by #xxx# (xxx就是你传进来的字符串topicId),ibatis 就会把他翻译成 order by 'topicId' 这样就报错了 ,用$的结果就是这样 order by topicId ②这里的iterate <isPropertyAvailable property="marketIdList"> <isNotNull property="marketIdList" prepend=" and marketId in "> <iterate property="marketIdList" conjunction="," close=")" open="("> #marketIdList[]# </iterate> </isNotNull> </isPropertyAvailable> 注意 iterate 的property属性 ,虽然你上面的isNotNull什么的都有这句,但这里一定要写清楚,否则ibatis会找不到你的list的
数据访问层代码: public List<Topic> getTopics(Map<String, Object> map) { return getSqlMapClientTemplate().queryForList("getTopics", map); } 服务层代码: public List<Topic> getTopicsByMarketIdList(Long authorId,List<Long> marketIdList, Integer orderby, Integer status, Pagination pagination) { Map<String, Object> map = new HashMap<String, Object>(); map.put("authorId", authorId); map.put("isDelete", false); map.put("marketIdList", marketIdList); map.put("orderStr", "这里你组装你的order字符串"); map.put("statusStr","这里你组装你的status字符串"); map.put("begin", pagination.getOffset()); map.put("max", pagination.getPageSize()); //这个getTopicCount()方法和getTopics()大体是一致的,所以我的dao里面省略了它 Long total = topicDao.getTopicCount(map); if (total == 0) { return new ArrayList<Topic>(); } else { pagination.setTotal(total); List<Topic> res = topicDao.getTopics(map); return res; } } public class Topic extends BaseObject implements Serializable { /** * */ private static final long serialVersionUID = -851973667810710701L; private Long id; private Long authorId; private String authorName; private Long marketId; private String title; private String tags; private String content; private Date pubdate; private Integer isBest; private Integer status; private Integer isDelete; private Integer clickCount; private Integer replyCount; private Date lastReplyTime; //getter and setter 省略... } Pagination代码: public class Pagination { /** * 要查看的页码 */ private int page; /** * 每页显示数 */ private int pageSize; /** * 一共有多少页 */ private int totalPage; /** * 一共有多少条记录 */ private long total; /** * 当前页的记录数 */ private int size; /** * 只需要topxx,不需要页数信息了 */ private boolean topOnly; /** *从第几条记录开始 */ private int offset; public void setOffset(int offset) { this.offset = offset; } public Pagination(int page, int pageSize) { this.page = page; this.pageSize = pageSize; } public Pagination() { } public boolean require() { return pageSize > 0 ? true : false; } public int from() { return page * pageSize; } public int to() { return from() + size; } public int getPage() { return page; } public void setPage(int page) { this.page = page; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getTotalPage() { return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public long getTotal() { return total; } public void setTotal(long total) { this.total = total; if (pageSize > 0) { this.totalPage = (int) Math.ceil(total / (double) pageSize); } else { this.totalPage = 1; } if (page >= totalPage) { page = totalPage - 1; } if (page < 0) page = 0; if (pageSize > 0) { if (page < totalPage - 1) this.size = pageSize; else this.size = (int) (total % pageSize); } else { this.size = (int) total; } offset=page * pageSize; } public int getOffset() { return offset; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public boolean isTopOnly() { return topOnly; } public void setTopOnly(boolean topOnly) { this.topOnly = topOnly; } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-08-04
最后修改:2009-08-04
动态语句里的分句给予服用都还是提出来比较好。
令 <isPropertyAvailable property="marketIdList"> <isNotNull property="marketIdList" prepend=" and marketId in "> <iterate property="marketIdList" conjunction="," close=")" open="("> #marketIdList[]# </iterate> </isNotNull> </isPropertyAvailable> 如果子句前的属性在参数对象中都不存在。 那么你动态生成的sql不符合逻辑了,改成下面的好些 <isPropertyAvailable property="marketIdList"> <isNotNull property="marketIdList" prepend="and"> <iterate property="marketIdList" conjunction="," close=")" open=" marketId in ("> #marketIdList[]# </iterate> </isNotNull> </isPropertyAvailable> |
|
返回顶楼 | |
发表时间:2009-08-11
谢谢 lemonweirui 的更正,帮我发现了一个bug,谢谢
|
|
返回顶楼 | |
发表时间:2009-11-05
我觉得2楼提出的,只不过是看起来更漂亮而已,原写法也不会出现Bug
|
|
返回顶楼 | |