跟着汤阳光同志做一个OA系统(十二):通用的分页实现、HQL生成器QueryHelper
2015-12-10 08:46
597 查看
======================= 本页的数据列表 ========================
<s:iterator value="recordList">
...
</s:iterator>
======================= 分页信息 ========================
页次:${pageNow}/${pageCount}页
每页显示:${pageSize}条
总记录数:${recordCount}条
<s:iterator begin="%{beginPageIndex}"end="%{endPageIndex}" var="num">
...
</s:iterator>
转到:
<selectonchange="gotoPage(this.value)">
<s:iterator begin="1"end="%{pageCount}" var="num">
<optionvalue="${num}">${num}</option>
</s:iterator>
</select>
<script>
function gotoPage(pageNow){
window.location.href = "url? pageNow ="+ pageNow;
}
</script>
======== 页面中需要显示的数据 ===========
recordList 本页的数据列表
pageNow 当前页
pageCount 总页数
pageSize 每页显示多少条
recordCount 总记录数
beginPageIndex 页码列表的开始索引
endPageIndex 页码列表的结束索引
========================================
假设共25条数据,每页显示10条,则共3页
first max
---------------------------------
第1页 0 10
第2页 10 10
第3页 20 10
first = (pageNow - 1) *pageSize
max = pageSize
实现分页的流程
设计一个实体PageBean,这中间就包含分页的所有信息,由service提供,传入需要的参数。
PageBean的设计
publicclass PageBean {
//
指定的或是页面参数
privateintcurrentPage;
// 当前页
privateintpageSize;
// 每页显示多少条
//
查询数据库
privateintrecordCount;
// 总记录数
private
List recordList;
// 本页的数据列表
//
计算
privateintpageCount;
// 总页数
privateintbeginPageIndex;
// 页码列表的开始索引(包含)
privateintendPageIndex;
// 页码列表的结束索引(包含)
/**
*
只接受前4个必要的属性,会自动的计算出其他3个属生的值
*
* @param currentPage
* @param pageSize
* @param recordCount
* @param recordList
*/
public PageBean(int currentPage,
int pageSize,
int recordCount,
List recordList) {
this.currentPage = currentPage;
this.pageSize = pageSize;
this.recordCount = recordCount;
this.recordList = recordList;
//
计算总页码
pageCount = (recordCount + pageSize - 1) / pageSize;
//
计算 beginPageIndex
和 endPageIndex
// >>
总页数不多于10页,则全部显示
if (pageCount <= 10) {
beginPageIndex = 1;
endPageIndex =
pageCount;
}
// >>
总页数多于10页,则显示当前页附近的共10个页码
else {
//
当前页附近的共10个页码(前4个 +
当前页 +
后5个)
beginPageIndex = currentPage - 4;
endPageIndex = currentPage + 5;
//
当前面的页码不足4个时,则显示前10个页码
if (beginPageIndex < 1) {
beginPageIndex = 1;
endPageIndex = 10;
}
//
当后面的页码不足5个时,则显示后10个页码
if (endPageIndex >
pageCount) {
endPageIndex = pageCount;
beginPageIndex =
pageCount - 10 + 1;
}
}
}
。。。
}
实现第一个分页(回复贴分页)
Action中
来源于页面
privateintpageNum = 1;//当前页,默认第一页
privateintpageSize = 10;//每页数量,默认10条
/**
显示单个主题(主帖+回帖列表) */
public String show()
throws Exception {
//
准备数据:topic
Topic topic =
topicService.getById(model.getId());
ActionContext.getContext().put("topic", topic);
// //
准备数据:replyList
// List<Reply> replyList = replyService.findByTopic(topic);
// ActionContext.getContext().put("replyList",replyList);
// //
准备分页信息 v1
PageBean pageBean =
replyService.getPageBeanByTopic(pageNum,
pageSize, topic);
ActionContext.getContext().getValueStack().push(pageBean);//放在栈顶就能少写一些#对象
topicId =
model.getId();
return"show";
}
Service的实现中
public PageBean getPageBeanByTopic(int pageNum,
int pageSize, Topic topic) {
//
查询本页的数据列表
List list = getSession().createQuery(//
"FROM Replyr WHERE r.topic=? ORDER BY r.postTime ASC")//
.setParameter(0, topic)//
.setFirstResult((pageNum - 1) * pageSize)//
.setMaxResults(pageSize)//
.list();
//
查询总记录数量
Long count = (Long) getSession().createQuery(//
"SELECTCOUNT(*) FROM Reply r WHERE r.topic=?")//
.setParameter(0, topic)//
.uniqueResult();
returnnew PageBean(pageNum, pageSize, count.intValue(), list);
}
JSP中
前面方然按照自己的循环显示所有的列表数据
<!--分页信息-->
<div
id=PageSelectorBar>
<div
id=PageSelectorMemo>
页次:${currentPage}/${pageCount
}页
每页显示:${pageSize
}条
总记录数:${recordCount
}条
</div>
<div
id=PageSelectorSelectorArea>
<a
href="javascript:
gotoPage(1)"
title="首页"
style="cursor: hand;">
<img
src="${pageContext.request.contextPath}/style/blue/images/pageSelector/firstPage.png"/>
</a>
<s:iterator
begin="%{beginPageIndex}"
end="%{endPageIndex}"
var="num">
<s:if
test="#num ==currentPage"><%--
当前页 --%>
<span
class="PageSelectorNumPageSelectorSelected">${num}</span>
</s:if>
<s:else><%--
非当前页 --%>
<span
class="PageSelectorNum"style="cursor: hand;"
onClick="gotoPage(${num});">${num}</span>
</s:else>
</s:iterator>
<a
href="javascript:
gotoPage(${pageCount})"
title="尾页"
style="cursor: hand;">
<img
src="${pageContext.request.contextPath}/style/blue/images/pageSelector/lastPage.png"/>
</a>
转到:
<select
onchange="gotoPage(this.value)"
id="_pn">
<s:iterator
begin="1"end="%{pageCount}"
var="num">
<option value="${num}">第
${num} 页</option>
</s:iterator>
</select>
<!--
回显 -->
<script
type="text/javascript">
$("#_pn").val("${currentPage}");
</script>
</div>
</div>
<script
type="text/javascript">
function gotoPage( pageNum ){
window.location.href =
"topic_show.action?id=${id}&pageNum=" + pageNum;
}
</script>
为了减少代码和以后带过滤参数,我们把上面script替换为
<scripttype="text/javascript">
function gotoPage( pageNum ){
// window.location.href = "forum_show.action?id=${id}&pageNum="+ pageNum;
$(document.forms[0]).append("<inputtype='hidden' name='pageNum' value='" + pageNum +"'>");
document.forms[0].submit();
}
</script>
而在分页的地方,因为form天生就能带参数,所以排序和过滤的条件就可以放在这个form中,但是保证这个form在这个页面中是第一个
增加过滤条件
<div
id="TableTail">
<div
id="TableTail_inside">
<table
border="0"cellspacing="0"
cellpadding="0"height="100%"
align="left">
<tr
valign=bottom>
<td></td>
<td>
<s:select
name="viewType"list="#{0:'全部主题',
1:'全部精华贴'}"/>
<s:select
name="orderBy"onchange="onSortByChange(this.value)"
list="#{0:'默认排序(所有置顶帖在前面,并按最后更新时间降序排列)',
1:'只按最后更新时间排序', 2:'只按主题发表时间排序', 3:'只按回复数量排序'}"
/>
<s:select
name="asc"list="#{false:'降序',
true:'升序'}"/>
<input
type="IMAGE"src="${pageContext.request.contextPath}/style/blue/images/button/submit.PNG"
align="ABSMIDDLE"/>
</td>
</tr>
</table>
</div>
</div>
Service的分页合并后提取到DaoSupport中
// 公共的查询分页信息的方法
public PageBean getPageBean(int pageNum,
int pageSize, String hql, List<Object>parameters) {
// System.out.println("------->DaoSupportImpl.getPageBean()");
//
查询本页的数据列表
Query listQuery = getSession().createQuery(hql);
// 创建查询对象
if (parameters !=
null) {
// 设置参数
for (int i = 0; i < parameters.size();
i++) {
listQuery.setParameter(i, parameters.get(i));
}
}
listQuery.setFirstResult((pageNum - 1) * pageSize);
listQuery.setMaxResults(pageSize);
List list = listQuery.list();
// 执行查询
//
查询总记录数量
Query countQuery = getSession().createQuery("SELECT COUNT(*) " + hql);
if (parameters !=
null) {
// 设置参数
for (int i = 0; i < parameters.size();
i++) {
countQuery.setParameter(i, parameters.get(i));
}
}
Long count = (Long) countQuery.uniqueResult();
// 执行查询
returnnew PageBean(pageNum, pageSize, count.intValue(), list);
}
QueryHelper来帮助生成HQL语句
/**
*
*
调用方式】
* QueryHelper helper = newQueryHelper(Reply.class, "r")//
.addCondition("r.topic=?",topic)//
.addOrderProperty("r.postTime",true);
PageBean pageBean = replyService.getPageBean(pageNum,pageSize, helper);
或者添加condition和orderby之后直接调用preparePageBean
*/
/**
*
* FROM
必须
实体名
WHERE
可选
条件1 AND 条件2 AND ...
条件n
ORDER BY
可选
属性1,
属性2, ...
属性n
*
用于辅助拼接HQL语句
*
*
*
支持方法连缀
*
生成HQL语句
*
生成参数列表
*
生成查询总记录数的HQL,去除掉OrderBy
*
直接生成PageBean
* @author
tyg
* StringBuffer代替String应该还能提升性能
*/
publicclass QueryHelper {
private StringBuffer
fromClause;
// FROM子句
private StringBuffer
whereClause =
new StringBuffer("");
// Where子句
private StringBuffer
orderByClause =
new StringBuffer("");
// OrderBy子句
private List<Object>
parameters =
new ArrayList<Object>();
// 参数列表
/**
*
生成From子句
*
* @param clazz
* @param alias
*
别名
* FROM Topic t
*/
public QueryHelper(Class clazz, String alias) {
fromClause =
new StringBuffer("FROM ")
.append(clazz.getSimpleName())
.append(" ")
.append(alias);
}
/**
*
拼接Where子句
* d.id BETWEEN ? AND ?
d.parent=?
d.parent IS NULL
* @param condition
* @param params
*/
public QueryHelper addCondition(String condition, Object...params) {
//
拼接
if (whereClause.length() == 0) {
whereClause =
new StringBuffer(" WHERE ").append(condition);
} else {
whereClause.append(" AND ").append(condition);
}
//
参数
if (params !=
null) {
for (Object p : params) {
parameters.add(p);
}
}
returnthis;
}
/**
*
如果第一个参数为true,则拼接Where子句
*
* @param append
* @param condition
* @param params
*/
public QueryHelper addCondition(boolean append,
String condition,Object... params) {
if (append) {
addCondition(condition, params);
}
returnthis;
}
/**
*
拼接OrderBy子句
*
* @param propertyName
*
参与排序的属性名
* @param asc
* true表示升序,false表示降序
*/
public QueryHelper addOrderProperty(String propertyName,
boolean asc) {
if (orderByClause.length() == 0) {
orderByClause =
new StringBuffer(" ORDER BY ").append(propertyName + (asc ?
"ASC" :
"DESC"));
} else {
orderByClause.append(", ").append(propertyName + (asc ?
" ASC" :
" DESC"));
}
returnthis;
}
/**
*
如果第一个参数为true,则拼接OrderBy子句
*
* @param append
* @param propertyName
* @param asc
*/
public QueryHelper addOrderProperty(boolean
append, String propertyName, boolean asc) {
if (append) {
addOrderProperty(propertyName, asc);
}
returnthis;
}
/**
*
获取生成的用于查询数据列表的HQL语句
*
* @return
*/
public String getListQueryHql() {
returnnew StringBuffer(fromClause).append(whereClause).append(orderByClause).toString();
}
/**
*
获取生成的用于查询总记录数的HQL语句
*
* @return
*/
public String getCountQueryHql() {
return"SELECTCOUNT(*) " +
fromClause +
whereClause;
}
/**
*
获取HQL中的参数值列表
*
* @return
*/
public List<Object> getParameters() {
returnparameters;
}
/**
*
查询分页信息,并放到值栈栈顶
*
* @param service
* @param pageNum
* @param pageSize
*/
publicvoid preparePageBean(DaoSupport<?> service,
int pageNum,
int pageSize) {
PageBean pageBean = service.getPageBean(pageNum, pageSize,
this);
ActionContext.getContext().getValueStack().push(pageBean);
}
}
<s:iterator value="recordList">
...
</s:iterator>
======================= 分页信息 ========================
页次:${pageNow}/${pageCount}页
每页显示:${pageSize}条
总记录数:${recordCount}条
<s:iterator begin="%{beginPageIndex}"end="%{endPageIndex}" var="num">
...
</s:iterator>
转到:
<selectonchange="gotoPage(this.value)">
<s:iterator begin="1"end="%{pageCount}" var="num">
<optionvalue="${num}">${num}</option>
</s:iterator>
</select>
<script>
function gotoPage(pageNow){
window.location.href = "url? pageNow ="+ pageNow;
}
</script>
======== 页面中需要显示的数据 ===========
recordList 本页的数据列表
pageNow 当前页
pageCount 总页数
pageSize 每页显示多少条
recordCount 总记录数
beginPageIndex 页码列表的开始索引
endPageIndex 页码列表的结束索引
========================================
假设共25条数据,每页显示10条,则共3页
first max
---------------------------------
第1页 0 10
第2页 10 10
第3页 20 10
first = (pageNow - 1) *pageSize
max = pageSize
实现分页的流程
设计一个实体PageBean,这中间就包含分页的所有信息,由service提供,传入需要的参数。
PageBean的设计
publicclass PageBean {
//
指定的或是页面参数
privateintcurrentPage;
// 当前页
privateintpageSize;
// 每页显示多少条
//
查询数据库
privateintrecordCount;
// 总记录数
private
List recordList;
// 本页的数据列表
//
计算
privateintpageCount;
// 总页数
privateintbeginPageIndex;
// 页码列表的开始索引(包含)
privateintendPageIndex;
// 页码列表的结束索引(包含)
/**
*
只接受前4个必要的属性,会自动的计算出其他3个属生的值
*
* @param currentPage
* @param pageSize
* @param recordCount
* @param recordList
*/
public PageBean(int currentPage,
int pageSize,
int recordCount,
List recordList) {
this.currentPage = currentPage;
this.pageSize = pageSize;
this.recordCount = recordCount;
this.recordList = recordList;
//
计算总页码
pageCount = (recordCount + pageSize - 1) / pageSize;
//
计算 beginPageIndex
和 endPageIndex
// >>
总页数不多于10页,则全部显示
if (pageCount <= 10) {
beginPageIndex = 1;
endPageIndex =
pageCount;
}
// >>
总页数多于10页,则显示当前页附近的共10个页码
else {
//
当前页附近的共10个页码(前4个 +
当前页 +
后5个)
beginPageIndex = currentPage - 4;
endPageIndex = currentPage + 5;
//
当前面的页码不足4个时,则显示前10个页码
if (beginPageIndex < 1) {
beginPageIndex = 1;
endPageIndex = 10;
}
//
当后面的页码不足5个时,则显示后10个页码
if (endPageIndex >
pageCount) {
endPageIndex = pageCount;
beginPageIndex =
pageCount - 10 + 1;
}
}
}
。。。
}
实现第一个分页(回复贴分页)
Action中
来源于页面
privateintpageNum = 1;//当前页,默认第一页
privateintpageSize = 10;//每页数量,默认10条
/**
显示单个主题(主帖+回帖列表) */
public String show()
throws Exception {
//
准备数据:topic
Topic topic =
topicService.getById(model.getId());
ActionContext.getContext().put("topic", topic);
// //
准备数据:replyList
// List<Reply> replyList = replyService.findByTopic(topic);
// ActionContext.getContext().put("replyList",replyList);
// //
准备分页信息 v1
PageBean pageBean =
replyService.getPageBeanByTopic(pageNum,
pageSize, topic);
ActionContext.getContext().getValueStack().push(pageBean);//放在栈顶就能少写一些#对象
topicId =
model.getId();
return"show";
}
Service的实现中
public PageBean getPageBeanByTopic(int pageNum,
int pageSize, Topic topic) {
//
查询本页的数据列表
List list = getSession().createQuery(//
"FROM Replyr WHERE r.topic=? ORDER BY r.postTime ASC")//
.setParameter(0, topic)//
.setFirstResult((pageNum - 1) * pageSize)//
.setMaxResults(pageSize)//
.list();
//
查询总记录数量
Long count = (Long) getSession().createQuery(//
"SELECTCOUNT(*) FROM Reply r WHERE r.topic=?")//
.setParameter(0, topic)//
.uniqueResult();
returnnew PageBean(pageNum, pageSize, count.intValue(), list);
}
JSP中
前面方然按照自己的循环显示所有的列表数据
<!--分页信息-->
<div
id=PageSelectorBar>
<div
id=PageSelectorMemo>
页次:${currentPage}/${pageCount
}页
每页显示:${pageSize
}条
总记录数:${recordCount
}条
</div>
<div
id=PageSelectorSelectorArea>
<a
href="javascript:
gotoPage(1)"
title="首页"
style="cursor: hand;">
<img
src="${pageContext.request.contextPath}/style/blue/images/pageSelector/firstPage.png"/>
</a>
<s:iterator
begin="%{beginPageIndex}"
end="%{endPageIndex}"
var="num">
<s:if
test="#num ==currentPage"><%--
当前页 --%>
<span
class="PageSelectorNumPageSelectorSelected">${num}</span>
</s:if>
<s:else><%--
非当前页 --%>
<span
class="PageSelectorNum"style="cursor: hand;"
onClick="gotoPage(${num});">${num}</span>
</s:else>
</s:iterator>
<a
href="javascript:
gotoPage(${pageCount})"
title="尾页"
style="cursor: hand;">
<img
src="${pageContext.request.contextPath}/style/blue/images/pageSelector/lastPage.png"/>
</a>
转到:
<select
onchange="gotoPage(this.value)"
id="_pn">
<s:iterator
begin="1"end="%{pageCount}"
var="num">
<option value="${num}">第
${num} 页</option>
</s:iterator>
</select>
<!--
回显 -->
<script
type="text/javascript">
$("#_pn").val("${currentPage}");
</script>
</div>
</div>
<script
type="text/javascript">
function gotoPage( pageNum ){
window.location.href =
"topic_show.action?id=${id}&pageNum=" + pageNum;
}
</script>
为了减少代码和以后带过滤参数,我们把上面script替换为
<scripttype="text/javascript">
function gotoPage( pageNum ){
// window.location.href = "forum_show.action?id=${id}&pageNum="+ pageNum;
$(document.forms[0]).append("<inputtype='hidden' name='pageNum' value='" + pageNum +"'>");
document.forms[0].submit();
}
</script>
而在分页的地方,因为form天生就能带参数,所以排序和过滤的条件就可以放在这个form中,但是保证这个form在这个页面中是第一个
增加过滤条件
<div
id="TableTail">
<div
id="TableTail_inside">
<table
border="0"cellspacing="0"
cellpadding="0"height="100%"
align="left">
<tr
valign=bottom>
<td></td>
<td>
<s:select
name="viewType"list="#{0:'全部主题',
1:'全部精华贴'}"/>
<s:select
name="orderBy"onchange="onSortByChange(this.value)"
list="#{0:'默认排序(所有置顶帖在前面,并按最后更新时间降序排列)',
1:'只按最后更新时间排序', 2:'只按主题发表时间排序', 3:'只按回复数量排序'}"
/>
<s:select
name="asc"list="#{false:'降序',
true:'升序'}"/>
<input
type="IMAGE"src="${pageContext.request.contextPath}/style/blue/images/button/submit.PNG"
align="ABSMIDDLE"/>
</td>
</tr>
</table>
</div>
</div>
Service的分页合并后提取到DaoSupport中
// 公共的查询分页信息的方法
public PageBean getPageBean(int pageNum,
int pageSize, String hql, List<Object>parameters) {
// System.out.println("------->DaoSupportImpl.getPageBean()");
//
查询本页的数据列表
Query listQuery = getSession().createQuery(hql);
// 创建查询对象
if (parameters !=
null) {
// 设置参数
for (int i = 0; i < parameters.size();
i++) {
listQuery.setParameter(i, parameters.get(i));
}
}
listQuery.setFirstResult((pageNum - 1) * pageSize);
listQuery.setMaxResults(pageSize);
List list = listQuery.list();
// 执行查询
//
查询总记录数量
Query countQuery = getSession().createQuery("SELECT COUNT(*) " + hql);
if (parameters !=
null) {
// 设置参数
for (int i = 0; i < parameters.size();
i++) {
countQuery.setParameter(i, parameters.get(i));
}
}
Long count = (Long) countQuery.uniqueResult();
// 执行查询
returnnew PageBean(pageNum, pageSize, count.intValue(), list);
}
QueryHelper来帮助生成HQL语句
/**
*
*
调用方式】
* QueryHelper helper = newQueryHelper(Reply.class, "r")//
.addCondition("r.topic=?",topic)//
.addOrderProperty("r.postTime",true);
PageBean pageBean = replyService.getPageBean(pageNum,pageSize, helper);
或者添加condition和orderby之后直接调用preparePageBean
*/
/**
*
* FROM
必须
实体名
WHERE
可选
条件1 AND 条件2 AND ...
条件n
ORDER BY
可选
属性1,
属性2, ...
属性n
*
用于辅助拼接HQL语句
*
*
*
支持方法连缀
*
生成HQL语句
*
生成参数列表
*
生成查询总记录数的HQL,去除掉OrderBy
*
直接生成PageBean
* @author
tyg
* StringBuffer代替String应该还能提升性能
*/
publicclass QueryHelper {
private StringBuffer
fromClause;
// FROM子句
private StringBuffer
whereClause =
new StringBuffer("");
// Where子句
private StringBuffer
orderByClause =
new StringBuffer("");
// OrderBy子句
private List<Object>
parameters =
new ArrayList<Object>();
// 参数列表
/**
*
生成From子句
*
* @param clazz
* @param alias
*
别名
* FROM Topic t
*/
public QueryHelper(Class clazz, String alias) {
fromClause =
new StringBuffer("FROM ")
.append(clazz.getSimpleName())
.append(" ")
.append(alias);
}
/**
*
拼接Where子句
* d.id BETWEEN ? AND ?
d.parent=?
d.parent IS NULL
* @param condition
* @param params
*/
public QueryHelper addCondition(String condition, Object...params) {
//
拼接
if (whereClause.length() == 0) {
whereClause =
new StringBuffer(" WHERE ").append(condition);
} else {
whereClause.append(" AND ").append(condition);
}
//
参数
if (params !=
null) {
for (Object p : params) {
parameters.add(p);
}
}
returnthis;
}
/**
*
如果第一个参数为true,则拼接Where子句
*
* @param append
* @param condition
* @param params
*/
public QueryHelper addCondition(boolean append,
String condition,Object... params) {
if (append) {
addCondition(condition, params);
}
returnthis;
}
/**
*
拼接OrderBy子句
*
* @param propertyName
*
参与排序的属性名
* @param asc
* true表示升序,false表示降序
*/
public QueryHelper addOrderProperty(String propertyName,
boolean asc) {
if (orderByClause.length() == 0) {
orderByClause =
new StringBuffer(" ORDER BY ").append(propertyName + (asc ?
"ASC" :
"DESC"));
} else {
orderByClause.append(", ").append(propertyName + (asc ?
" ASC" :
" DESC"));
}
returnthis;
}
/**
*
如果第一个参数为true,则拼接OrderBy子句
*
* @param append
* @param propertyName
* @param asc
*/
public QueryHelper addOrderProperty(boolean
append, String propertyName, boolean asc) {
if (append) {
addOrderProperty(propertyName, asc);
}
returnthis;
}
/**
*
获取生成的用于查询数据列表的HQL语句
*
* @return
*/
public String getListQueryHql() {
returnnew StringBuffer(fromClause).append(whereClause).append(orderByClause).toString();
}
/**
*
获取生成的用于查询总记录数的HQL语句
*
* @return
*/
public String getCountQueryHql() {
return"SELECTCOUNT(*) " +
fromClause +
whereClause;
}
/**
*
获取HQL中的参数值列表
*
* @return
*/
public List<Object> getParameters() {
returnparameters;
}
/**
*
查询分页信息,并放到值栈栈顶
*
* @param service
* @param pageNum
* @param pageSize
*/
publicvoid preparePageBean(DaoSupport<?> service,
int pageNum,
int pageSize) {
PageBean pageBean = service.getPageBean(pageNum, pageSize,
this);
ActionContext.getContext().getValueStack().push(pageBean);
}
}
相关文章推荐
- UI-7-UIScrollView
- 造轮子:Guid.NewGuid().ToString()得几种格式显示
- UITableView
- this class is not key value coding-compliant for the key id
- alrtbuilder.dialog使用以及两种上下文比较
- UICollectionView must be initialized with a non-nil layout parameter
- request.getInputStream()只能获取一次的问题
- UIView中的坐标转换
- liquibase tag name expected解决方法
- win8/win10操作系统如何通过Legacy BIOS与UEFI两种模式安装
- UEFI装系统不能从U盘启动的解决办法
- Marklogic学习 由浅入深(4)—— 初识Query Console
- Unique Binary Search Trees
- 欢迎使用CSDN-markdown编辑器
- UIViewController
- UITableView以及UITableViewCell设置的时候容易出现的错误
- iOS之UI--UITabBarController
- 瀑布流-UICollectionView 的从新布局,动态加载HTML数据,HTML数据的解析和UICollectionViewFlowLayout的从布
- 在非gui线程使用QMessageBox
- iOS开发之int,NSInteger,NSUInteger,NSNumber的使用