使用衍生属性
衍生属性的值在运行时计算,通过对利用formula属性定义的表达式求值。例如,可以把totalIncludingTax属性映射到SQL表达式:
<property name="totalIncludingTax" formula="TOTAL + TAX_RATE * TOTAL" type="big_decimal"/>
这个给定的SQL公式在每次从数据库获取实体时求值.属性没有列属性,并且永远不会出现在SQL的insert或者update中,而只在
select中。公式可能指向数据库表的列,它们可以调用SQL函数,甚至包括SQL子查询。sql表达式实际上被传递到底层的数据库.
也就是说,这个公式在每次查询时候求值,并且这个属性不会被保存和更新,如果你改变其中的数据例如tax_rate,属性值不会去自动计算。
注意:在insert或update时,不用对衍生属性进行操作,不用对这个属性设置任何值,它不会对insert或update产生影响。在select时,我们可以通过这个衍生属性,获取我们想要的值。
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>hibernateTest</groupId> <artifactId>hibernateTest</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>hibernateTest</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>3.3.1.GA</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-nop</artifactId> <version>1.5.2</version> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.4.GA</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-proxool</artifactId> <version>3.3.1.GA</version> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc14</artifactId> <version>10.2.0.3.0</version> <scope>runtime</scope> </dependency> </dependencies> <build> <finalName>hibernateTest</finalName> <resources> <resource> <directory>src/main/resources</directory> </resource> <resource> <directory>src/main/java</directory> <excludes> <exclude>**/*.java</exclude> </excludes> </resource> </resources> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build> </project>
resources/proxool.xml:
<?xml version="1.0" encoding="UTF-8"?> <something-else-entirely> <proxool> <!-- 连接池的别名 --> <alias>proxool</alias> <!-- proxool只能管理由自己产生的连接 --> <driver-url>jdbc:oracle:thin:@localhost:1521:XE</driver-url> <!--JDBC驱动程序--> <driver-class>oracle.jdbc.driver.OracleDriver</driver-class> <!-- 用户名与密码 --> <driver-properties> <property name="user" value="system" /> <property name="password" value="password" /> </driver-properties> <!-- 允许最大连接数 ,默认是15,这里设置为20--> <maximum-connection-count>20</maximum-connection-count> <!-- 最小连接数 ,默认是5,其实可以不用声明它--> <minimum-connection-count>5</minimum-connection-count> <!-- 测试连接的sql语句 --> <house-keeping-test-sql>select sysdate from dual</house-keeping-test-sql> </proxool> </something-else-entirely>
resources/hibernate.cfg.xml:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory name="sessionFactory"> <property name="hibernate.connection.provider_class"> org.hibernate.connection.ProxoolConnectionProvider </property> <property name="hibernate.proxool.pool_alias">proxool</property> <property name="hibernate.proxool.xml">proxool.xml</property> <!-- 输出sql --> <property name="hibernate.show_sql">true</property> <!-- 格式化sql --> <property name="hibernate.format_sql">true</property> <!--指定数据库适配器 --> <property name="dialect"> org.hibernate.dialect.OracleDialect </property> <!-- 映射文件 --> <mapping resource="hibernateTest/Student.hbm.xml" /> </session-factory> </hibernate-configuration>
HibernateTest/Student.java:
package hibernateTest; public class Student { private int id; private String name; private String address; private int age; private int gfAge; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getGfAge() { return gfAge; } public void setGfAge(int gfAge) { this.gfAge = gfAge; } }
HibernateTest/Student.hbm.xml , 注意formula这个属性。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="hibernateTest.Student" table="STUDENT" dynamic-insert="true" dynamic-update="true"> <id name="id" column="ID" type="int"> <generator class="sequence"> <!-- seq_student就是表student的主键自增的sequence --> <param name="sequence">seq_student</param> </generator> </id> <property name="name" column="name" type="string"/> <property name="address" column="address" type="string"/> <property name="age" column="age" type="int"/> <!-- 利用formula属性定义的表达式求值 ,只能用于select中 --> <property name="gfAge" formula="AGE-4" type="int"/> </class> </hibernate-mapping>
util/HibernateUtil.java:
package util; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static SessionFactory sessionFactory; static{ try { sessionFactory = new Configuration().configure().buildSessionFactory(); } catch (Throwable e) { throw new ExceptionInInitializerError(e); } } public static SessionFactory getSessionFactory(){ return sessionFactory; } public static void shutdown(){ getSessionFactory().close(); } }
util/StudentManager.java:
package util; import hibernateTest.Student; import org.hibernate.Session; import org.hibernate.Transaction; public class StudentManager { public static void main(String[] args) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = session.beginTransaction(); Student s = (Student) session.get(Student.class, 5); System.out.println(s.getName()); System.out.println(s.getAddress()); System.out.println(s.getId()); System.out.println(s.getAge()); System.out.println(s.getGfAge()); transaction.commit(); session.close(); } }