orm确实事很方便让人不需要大量的写sql,但是很多人诟病造成sql性能不好
举个例子,一个功能是修改get用户数据的金币清零然后update
非常简单的一个业务:
user user=dao.getuser(uid); user.setgold(0); dao.updateuser(user);
就这样一个简单的功能,实际会向数据库发送一长串的sql update语句
如:update user set a=?,b=?,c=?............gold=? where uid = ?
看到这里有人会明白问题出在哪里了,想想一下每个表都有一堆字段, 而实际上我们在各个业务里面只会修改一两个字段,导致每次调用业务都会生产这样一长串的sql,给数据库来带巨大而且没有必要的压力。
有的人会说:我编程习惯很好,平时都会把调用频率高的方法单独写sql。例如上面修改金币会单独写一个updategold方法。当然,这是一种很好的习惯并且也能解决这个问题。但是 大部分开发者、大部分业务实现并不会这样做。不是吗?
现在可以通过另外一种方法来实现对原有的orm系统优化兼顾开发效率和系统性能提升:
/** update之前先比较,只update修改过的列 */ publicvoid compareandupdate(t oldt, t newt);
简单的介绍一下就是,通过对比新旧实体,根据修改过的列来生成指定的列到达针对性更新的目的。
//以前: user user=dao.getuser(uid); user.setgold(0); dao.updateuser(user); //产生的sql: update user set a=?,b=?,c=?............gold=? where uid = ? //新的做法: user user=dao.getuser(uid); user olduser=beanutils.clonebean(user); user.setgold(0); dao.compareandupdate(olduser,user); //产生的sql: update user set gold = ? where uid = ? sql语句的缩短成倍的降低了与数据库通讯的开销,并且大大的降低了数据库压力。 如果上面的写法可能会稍微麻烦点,我们可以再偷点懒: user user=dao.getuser(uid); object oldbean=beanutils.copybean(user);//这样的区别是copy这段代码即可,不需要经常修改oldbean的类型。因为我们不关心oldbean是什么类型。 user.setgold(0); dao.compareandupdate(oldbean,user);
有人会说实体copy和拼接sql也会产生开销,这个是不错。但是这种开销对于数据库的压力来说根本就是九牛一毛不值一提。
compareandupdate这个方法是我自己写的orm框架:freyja-jdbc 里面改写update方法产生的。如果是使用的其他orm框架 有预留接口的话可以改写下即可。没有接口的话可能需要自己去实现了,方法就是映射实体和字段 生成sql语句
hibernate 好久没碰了,怎么改写hibernate也能达到一样的效果不清楚,有兴趣的可以自己研究下。
最后还是放下相关代码吧
public static parameter compareandupdate(object oldentity, object newentity) { freyjaentity entity = shardingutil.getentity(newentity.getclass()); list