阅读对象:
1.已经在使用Hibernate JPA完成持久化映射的朋友。
2.在网上搜索Formula并通通搜到转载oralce一篇技术文章或hibernate annotations技术文档的朋友。
3.发现@Formula不能使用并想Ctrl+Delete hibernate jar包,然后砸烂显示器的朋友。
文章内容
本文将说明如何使用@Formula,并且说明在哪几种情况下@Formula会失灵。
1.Formula的作用
引用hibernate annotations技术文档中的解释可以很好的说明@Formula的作用,但它确实没有说清楚怎么使用,并且给出的示例是用不了的,这让我浪费了好几个钟头的时间!
Formula的作用就是说白了就是用一个查询语句动态的生成一个类的属性,比如java eye登陆之后 收件箱显示有几封未读邮件的数字,就是一条select count(*)...构成的虚拟列,而不是存储在数据库里的一个字段。用比较标准的说法就是:有时候,你想让数据库,而非JVM,来替你完成一些计算,也可能想创建某种虚拟列,你可以使用sql片段,而不是将属性映射(物理)列。这种属性是只读的(属性值由公式求得).Formula甚至可以包含sql子查询
Formula真的这么强大吗?确实,它很好很强大,节省了不少代码!
2.使用Formula
Java代码 1.package aa; 2. 3.import static javax.persistence.GenerationType.IDENTITY; 4. 5.import javax.persistence.Entity; 6.import javax.persistence.GeneratedValue; 7.import javax.persistence.Id; 8.import javax.persistence.Table; 9. 10.import org.hibernate.annotations.Formula; 11. 12./** 13. * 注解必须是在属性上的,如果有任何一个注解在方法上,那么@Formula将失效 14. * @author 昆明蜂鸟软件 15. * @version 0.1.0 2008-7-15 下午06:09:38 16. */ 17.@Entity 18.@Table(name = "user", catalog = "test") 19.public class User { 20. 21. @Id 22. @GeneratedValue(strategy = IDENTITY) 23. private int id; 24. 25. @Formula("(select COUNT(*) from user)") 26. private int count; 27. 28. public int getId() { 29. return id; 30. } 31. 32. public void setId(int id) { 33. this.id = id; 34. } 35. 36. public int getCount() { 37. return count; 38. } 39. 40. public void setCount(int count) { 41. this.count = count; 42. } 43.} package aa;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table;
import org.hibernate.annotations.Formula;
/** * 注解必须是在属性上的,如果有任何一个注解在方法上,那么@Formula将失效 * @author 昆明蜂鸟软件 * @version 0.1.0 2008-7-15 下午06:09:38 */ @Entity @Table(name = "user", catalog = "test") public class User { @Id @GeneratedValue(strategy = IDENTITY) private int id;
@Formula("(select COUNT(*) from user)") private int count;
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public int getCount() { return count; }
public void setCount(int count) { this.count = count; } }
数据库表:
Sql代码 1.CREATE TABLE `test`.`user` ( 2. `id` int(10) unsigned NOT NULL auto_increment, 3. PRIMARY KEY USING BTREE (`id`) 4.) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; CREATE TABLE `test`.`user` ( `id` int(10) unsigned NOT NULL auto_increment, PRIMARY KEY USING BTREE (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
细节1.使用@Formula 你的注解必须是在属性上,如果有一个注解在方法上,那么@Formula将失效。这个我是做过实验的,比如把以上的java文件改为:
Java代码 1.package aa; 2. 3.import static javax.persistence.GenerationType.IDENTITY; 4. 5.import javax.persistence.Entity; 6.import javax.persistence.GeneratedValue; 7.import javax.persistence.Id; 8.import javax.persistence.Table; 9. 10.import org.hibernate.annotations.Formula; 11. 12./** 13. * 注解必须是在属性上的,如果有任何一个注解在方法上,那么@Formula将失效 14. * @author 昆明蜂鸟软件 15. * @version 0.1.0 2008-7-15 下午06:09:38 16. */ 17.@Entity 18.@Table(name = "user", catalog = "test") 19.public class User { 20. 21. private int id; 22. 23. @Formula("(select COUNT(*) from user)") 24. private int count; 25. 26. @Id 27. @GeneratedValue(strategy = IDENTITY) 28. public int getId() { 29. return id; 30. } 31. 32. public void setId(int id) { 33. this.id = id; 34. } 35. 36. public int getCount() { 37. return count; 38. } 39. 40. public void setCount(int count) { 41. this.count = count; 42. } 43.} package aa;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table;
import org.hibernate.annotations.Formula;
/** * 注解必须是在属性上的,如果有任何一个注解在方法上,那么@Formula将失效 * @author 昆明蜂鸟软件 * @version 0.1.0 2008-7-15 下午06:09:38 */ @Entity @Table(name = "user", catalog = "test") public class User { private int id;
@Formula("(select COUNT(*) from user)") private int count; @Id @GeneratedValue(strategy = IDENTITY) public int getId() { return id; }
public void setId(int id) { this.id = id; }
public int getCount() { return count; }
public void setCount(int count) { this.count = count; } }
这样@Formula就不可以运行!!!我前边就是被Hibernate官方的文档给搞晕了。
细节2.既然@Formula 是一个虚拟列,那么数据库中不需要建这一列,同样可以,如果有个列存在,hibernate也会将 其忽略。以上示例中的user就没有count列。
细节3.sql语句必须写在()中,这个以前也有人说过。
细节4.如果有where子查询,那么表需要用别名,比如 select COUNT(*) from user where id=1 是错的
而select COUNT(*) from user u where u.id=1是正确的
细节5.只要是你在数据库的sql控制台执行过的语句,并且使用了表别名,那么@Formula都应该是支持的。
确实@Formula是一个很常用且好用的东西!希望这篇文章能帮助你~~
声明:允许转载且不著名文章作者,但不允许修改文章后转载。
5 楼 灵灵然 2009-03-18 注意统一就可以,要么全部写在属性上,要么全部写在方法上 4 楼 lym6520 2009-02-03 lym6520 写道
,你说 注解必须是在属性上的,如果有任何一个注解在方法上,那么@Formula将失效 ,我测试过了,注解在方法上也是没问题的,我用的hibernate版本是3.2的,,
补充下,在这样的情况下,必须也要有set方法。
|