今天在一个DAO中尝试对一个数据执行先查询再更新的操作,结果后台提示出现了sql语句
Hibernate: select group_id from fnd_groupid where id= ?
Hibernate: update fnd_groupid set group_id= ? where id = ?
本来是很简单的一个操作,但是数据库里面的值却始终不更新。
之前的代码如下:
SQLQuery query = this.getSession().createSQLQuery("select group_id from fnd_groupid where id= ?");
query.setLong(0, 1L);
Long nextVal = StringTools.parseLong(query.uniqueResult().toString());
SQLQuery queryUpdate = this.getSession().createSQLQuery("update fnd_groupid set group_id= ? where id = ? ");
queryUpdate.setLong(0, nextVal+1);
queryUpdate.setLong(1, 1l);
queryUpdate.executeUpdate();
后来google一下,才发现我的操作很有问题,我连续取出当前会话进行操作,前面的查询操作可以进行,但是此时会话还在进行中,我后面再次取到当前会话,并执行更新操作,这个操作始终无法完成。多次操作应该使用事务,只有提交事务之后才会生效。这其中涉及到hibernate的一级缓存机制。
这说明埋头写代码真的没啥用,原理的东西很多尚待研究,任重而道远~~
修改后的代码如下:
Session session = this.getSession();
Transaction transaction = session.beginTransaction();//启动事务
SQLQuery query = session.createSQLQuery("select group_id from fnd_groupid where id= ?");
query.setLong(0, 1L);
Long nextVal = StringTools.parseLong(query.uniqueResult().toString());
SQLQuery queryUpdate = session.createSQLQuery("update fnd_groupid set group_id= ? where id = ? ");
queryUpdate.setLong(0, nextVal+1);
queryUpdate.setLong(1, 1l);
queryUpdate.executeUpdate();
transaction.commit();
session.close();
return nextVal;
与Hibernate DetachedCriteria有关的分页问题
这是本人做项目数据库移植的时候遇到的一个最典型的问题,在查询总量的时候,会报如下错误
ORDER BY 子句中的列 "fnd_code.CODE_ID" 无效,因为该列没有包含在聚合函数或 GROUP BY 子句中。
当时百度google了很久,感觉网上都是泛泛而谈,没有从根源解决这个问题。下面就这个问题分析一下。
public List findPageByCriteria(DetachedCriteria criteria, int pageFirst, int pageMax){
log.debug("finding instance page by criteria");
try {
List results = getHibernateTemplate().findByCriteria(criteria, pageFirst, pageMax);
log.debug("find page by criteria successful, page size: "
+ results.size());
return results;
} catch (RuntimeException re) {
log.error("find page by criteria failed", re);
throw re;
}
}
这是BaseDao中的一个方法,使用hibernate管理数据库连接的时候,就是通过下面几行代码
getHibernateTemplate().findByCriteria(criteria, pageFirst, pageMax);
//其中,criteria是查询语句,pageFirst就是要查第几页,而pageMax就是总页数,hibernate会自动将这一页的内容取出来
来进行分页查询的。
但是在进行分页查询以前,必须要知道记录总数,以及分页信息,这个通常手动指定。知道这些信息后,再通过记录总数调整分页信息,调整方法如下:
public void adjustByTotalRow(int total){
totalRow = total;
if(totalRow < 1){
page = 0; //当前页
pageRow = 0; //页面记录数
totalPage = 0;//总页数
totalRow = 0;//总数据量
} else {
//设置总页数
totalPage = (totalRow / pageMax) + ((totalRow % pageMax) == 0 ? 0 : 1);
//调整页号
if(page > totalPage){
page = totalPage;
} else if(page < 1){
page = 1;
}
//计算页面记录数
pageRow = totalRow - (page - 1) * pageMax;
if (pageRow > pageMax){
pageRow = pageMax;
}
}
}
下面问题出来了,需要获得记录总数,最简单的代码如下所示
select count(*) from fnd_code order by code_id
但是令人蛋碎的是,一模一样的一个sql语句,在oracle中正常运行,但是sql server竟然报错,就是我上面贴出来的这个错误。分页的问题就是因为这个语句出来的。
在我的service中,进行如下调用,需要说明的是,现在传进来的criteria是有order的。
protected List findByPage(BaseDAO dao, DetachedCriteria criteria, PageMeta page) throws ServiceException{
if (page == null) {
return dao.findByCriteria(criteria);
} else {
int total = dao.findTotalByCriteria(criteria);//获取记录总数
if (total == 0) {
// no record found
return null;
}
page.adjustByTotalRow(total);//这个方法上面有贴出来,调整分页信息
// fetch the result page
if (page.getPage() < 1) {
// no fetch needed
return null;
}
List results = dao.findPageByCriteria(criteria,page.getPageFirstRow(), page.getPageMax());//分页查询
}
在service中,获取记录总数就会调用上面类似的sql语句,错误也就在此产生的。
啰嗦这么多,只是想也把分页的方法大致描述一下,方便理解。这个问题解决起来很简单,我们要把addOrder操作加到获取记录总数之后。下面是我修改的BaseService
protected Order order;//定义一个字段Order
/*此方法供外部调用,不再给criteria添加Order,而是将order给service
*/
public void addOrder(Order order){
this.order = order;
}
protected List findByPage(BaseDAO dao, DetachedCriteria criteria, PageMeta page) throws ServiceException{
if (page == null) {
return dao.findByCriteria(criteria);
} else {
int total = dao.findTotalByCriteria(criteria);
if (total == 0) {
// no record found
return null;
}
if(order != null){
criteria.addOrder(order);//获取记录总数以后,再将order加入
}
// adjust the page meta info by the actual total
page.adjustByTotalRow(total);
// fetch the result page
if (page.getPage() < 1) {
// no fetch needed
return null;
}
List results = dao.findPageByCriteria(criteria,page.getPageFirstRow(), page.getPageMax());
}
作了如下调整后,分页问题不复存在,当然我的方法可能不太好,如果哪位朋友有不同解决办法,可以留言交流,谢谢。
今天处理日期时发现一个问题,日期越减越大,为啥?
原来是基本数据类型的问题,Java默认数值类型为int型,下面的运算超出范围,越界之后数值变为负数,因此出现这个问题。
sDate.setTime(eDate.getTime() - 180*24*60*60*1000);
应该在后面加上类型转换:
sDate.setTime(eDate.getTime() - 180*24*60*60*1000 L);
这种类型的错误太蛋疼了~~
分享到:
相关推荐
随手记可以手机记账,在线理财,上随手记网站,你可以更方便的去发现自己的财务漏洞。随手记,记账方便!生活场景设计,左手拿满东西,右手大拇指也能记完账。这次我们分享的是随手记的源码,供大家参考学习。
1、这是Android流行应用随手记的部分源码,用于学习使用
金蝶 随手记 PC 单机版,只能在本地使用,如果需要和移动端同步需要注册
android随手记项目源码
android 随手记源码.rar
Android应用源码随手记安卓记账项目
AA记账随手记
类似于随手记的记账软件,功能相对比较强大,可以显示图表信息,支持记账,银行帐,现金帐,支票帐等功能
仿随手记小程序
随手记,理财第一步!源自金蝶,专业又好用。左手拿满东西,右手大拇指也把账记了。当时懒得记,也有记账拍照功能。自然而然,漂亮轻松。 v9.4.1.5主更新:优化了在部分小屏幕、大屏幕设备上的显示效果。对了,如果想...
Android 随手记记账应用源码.rar
Lisa随手记是一款简单、易用、免费、无广告的移动记事本软件,具有以下特点: ☞免账号免登陆不使用云端存储,不主动联网不上传,无需担心隐私泄露 ☞操作便捷、查看方便,完成事项一目了然,特别适合工作备忘和购物...
仿随手记的炫酷饼图 基于Eclipse的android工程源码demo
安卓Android源码——随手记安卓记账项目.zip
Android应用源码之随手记安卓记账项目
本例子是一个模仿金蝶随手记饼形统计图的小例子,使用的素材也是直接反编译随手记的图片,但源码作者自己写的,例子可以按住转动,话说我十分想把这个例子做成GIF呈现给大家,不过找了很久没有找到合适的录屏软件,...
这是本人移动开发课程的一个小作业,也就是做一个能进行文本记录的随手记小应用,经过本人编码、测试,程序运行正常。
Android应用源码之随手记安卓记账项目.zip
随手记记账应用源码.zip
可以记笔记 并且可以进行笔记的添加、笔记的删除以及修改