hibernate之实体表示法
hibernate中有3种内建的实体模式:
POJO 基于POJO,持久化类的一种领域模型实现。这是目前为止你所见到的,是默认的实体模式。
MAP 不需要Java类,用HashMap在Java应用程序中表示实体。这个模式允许完全动态应用程序的快速原型。
DOM4J 不需要Java类,实体被表示为xml元素,基于dom4j API。这种模式对于导出或者导入数据,或者通过XSLT处理来渲染和转 换数据时特别有用。
DOM4J模式的实例
把node属性添加到hibernate映射元数据来改变这个默认的xml表示法。
每一个node属性都定义了xml表示法:
. <class>映射中的node="xxx"属性,给该实体定义了xml元素的名称。如:<xxx></xxx>
. 任何属性映射中的node="yyy"属性,指定属性内容应该表示为给定名称的xml元素文本。如:<xxx><yyy>kkkk</yyy></xxx>
. 任何属性映射中的node="@zzz"属性,指定属性内容应该表示为给定名称的xml属性值。如:<xxx zzz="..."></xxx>
. 任何属性映射中的node="lll/@ppp"属性,指定属性内容应该在给定名称的一个子元素中表示为给定名称的xml属性值。
<xxx><lll ppp="..."></lll></xxx>
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>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1</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/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.driver_class">oracle.jdbc.driver.OracleDriver</property> <!-- 指定连接数据库的url,hibernate连接的数据库名 --> <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:XE</property> <property name="hibernate.connection.useUnicode">true</property> <property name="hibernate.connection.characterEncoding">gbk</property> <!-- 指定连接数据库的用户名 --> <property name="hibernate.connection.username">system</property> <!-- 指定连接数据库的密码 --> <property name="hibernate.connection.password">password</property> <!-- 指定连接池里最大连接数 --> <property name="hibernate.c3p0.max_size">20</property> <!-- 指定连接池里最小连接数 --> <property name="hibernate.c3p0.min_size">5</property> <!-- 指定连接池里连接的超时时长,以秒为单位 --> <property name="hibernate.c3p0.timeout">120</property> <!-- 指定连接池里最大缓存多少个Statement对象 --> <property name="hibernate.c3p0.max_statements">100</property> <!-- 每隔XX秒检查连接池里的空闲连接 ,单位是秒 --> <property name="hibernate.c3p0.idle_test_period">120</property> <!-- 当连接池里面的连接用完的时候,C3P0一次获取的新的连接数 --> <property name="hibernate.c3p0.acquire_increment">2</property> <!-- 指定数据库方言 --> <property name="dialect">org.hibernate.dialect.OracleDialect</property> <!-- 显示Hibernate持久化操作所生成的SQL --> <property name="show_sql">true</property> <!-- 将SQL脚本进行格式化后再输出 --> <property name="hibernate.format_sql">true</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; 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; } }
hibernateTest/Student.hbm.xml:
<?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" node="stu"> <id name="id" column="ID" type="int" node="@stuId"> <generator class="sequence"> <!-- seq_student就是表student的主键自增的sequence --> <param name="sequence">seq_student</param> </generator> </id> <property name="name" column="name" type="string" node="myStudent/@name"/> <property name="address" column="address" type="string" node="address"/> <property name="age" column="age" type="int" node="myStudent/@age"/> </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 java.io.IOException; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; import org.hibernate.EntityMode; import org.hibernate.Session; import org.hibernate.Transaction; public class StudentManager { public static void main(String[] args) { //打开一个处理DOM4J数据的Session Session dom4jSession = HibernateUtil.getSessionFactory().openSession().getSession(EntityMode.DOM4J); Transaction transaction = dom4jSession.beginTransaction(); Element studentElement = (Element) dom4jSession.get(Student.class, 5); transaction.commit(); dom4jSession.close(); try { OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter writer = new XMLWriter(System.out,format); writer.write(studentElement); } catch (IOException e) { throw new RuntimeException(); } //打开一个普通的session Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction1 = session.beginTransaction(); Student stu = (Student) session.get(Student.class, 5); System.out.println("id="+stu.getId()); System.out.println("name="+stu.getName()); System.out.println("address="+stu.getAddress()); System.out.println("age="+stu.getAge()); transaction1.commit(); session.close(); } }
输出结果:
<stu stuId="5"> <myStudent name="fuhaidong" age="28"/> <address>美国</address> </stu>
id=5 name=fuhaidong address=美国 age=28
注意:xxx.hbm.xml中加了note属性的xml表示法,并不影响你使用普通的POJO表示法。如上例。
DOM4J实体表示法的一对多实例:
<?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="Item" table="ITEM_ENTITY" node="item"> <id name="id" type="long" column="ITEM_ID" node="@id"> <generator class="native"/> </id> <property name="initialPrice" type="big_decimal" column="INIT_PRICE" node="item-details/@initial-price"/> <property name="description" type="string" column="DESCRIPTION" node="item-details/@description"/> <!-- 注意embed-xml="false",不允许嵌入xml元素数据 --> <many-to-one name="seller" class="User" column="USER_ID" embed-xml="false" node="@seller_id"/> </class> <!-- 把两个映射放到一个文件中是允许的 --> <class name="User" table="USERS" node="user"> <id name="id" type="long" column="USER_ID" node="@id"> <generator class="native"/> </id> <property name="username" type="string" column="USERNAME" node="@username"/> <!-- 注意embed-xml="true",允许嵌入xml元素数据 --> <bag name="itemsForSale" inverse="true" cascade="all" embed-xml="true" node="items-for-sale"> <key column="USER_ID"/> <one-to-many class="Item"/> </bag> </class> </hibernate-mapping>
生成的xml数据格式为:
<user id="1" username="johndoe"> <items-for-sale> <item id="2" seller-id="1"> <item-details initial-price="99" description="An item for auction"/> </item> <item id="3" seller-id="1"> <item-details initial-price="123" description="Another item for auction"/> </item> </items-for-sale> </user>
embed-xml选项被用于触发被关联实体数据的嵌入或者引用。小心这个embed-xml选项--你可能很容易创建导致无限循环的循环引用。