颠覆一下Hibernate的一般用法
一对多关系时,一般都是在多的一端维护关联关系,但不一定任何时候都好用!!!
特定场景:
需要在一的一端维护关系。
使用JAXB进行对象转xml的时候,这样做非常方便!
多的一方不能持有一的一方的引用,否则在转换XML的时候会循环调用导致失败!
POM
<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>com.gc.sis</groupId> <artifactId>sis-core</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>sis-core</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.2.6.Final</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.26</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> </dependency> </dependencies> </project>
实体类
package com.gc.sis.core;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
@Entity
@Table(name="illu")
@XmlRootElement
public class Illu {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private int singlePrem;
//级联保存,删除等;不使用懒加载策略,在查询Illu对象的同时,联合查询Client
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
private Set<Client> clients;
//级联保存,删除等;不使用懒加载策略,在查询Illu对象的同时,联合查询Rider
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
private Set<Rider> riders;
public Illu() {
super();
}
public int getId() {
return id;
}
public int getSinglePrem() {
return singlePrem;
}
public void setSinglePrem(int singlePrem) {
this.singlePrem = singlePrem;
}
public Set<Client> getClients() {
if(clients==null)
clients = new HashSet<Client>();
return clients;
}
public void setClients(Set<Client> clients) {
this.clients = clients;
}
public Set<Rider> getRiders() {
if(riders==null)
riders = new HashSet<Rider>();
return riders;
}
public void setRiders(Set<Rider> riders) {
this.riders = riders;
}
}
package com.gc.sis.core;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="client")
public class Client {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String name;
private int age;
private String profession;
public Client() {
}
public Client(String name, int age, String profession) {
super();
this.name = name;
this.age = age;
this.profession = profession;
}
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result
+ ((profession == null) ? 0 : profession.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Client other = (Client) obj;
if (age != other.age)
return false;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (profession == null) {
if (other.profession != null)
return false;
} else if (!profession.equals(other.profession))
return false;
return true;
}
}
package com.gc.sis.core;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="rider")
public class Rider {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String riderCode;
private String riderName;
private boolean basic;
public Rider() {
super();
}
public Rider(String riderCode, String riderName, boolean basic) {
super();
this.riderCode = riderCode;
this.riderName = riderName;
this.basic = basic;
}
public String getRiderCode() {
return riderCode;
}
public void setRiderCode(String riderCode) {
this.riderCode = riderCode;
}
public String getRiderName() {
return riderName;
}
public void setRiderName(String riderName) {
this.riderName = riderName;
}
public boolean isBasic() {
return basic;
}
public void setBasic(boolean basic) {
this.basic = basic;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (basic ? 1231 : 1237);
result = prime * result + id;
result = prime * result
+ ((riderCode == null) ? 0 : riderCode.hashCode());
result = prime * result
+ ((riderName == null) ? 0 : riderName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Rider other = (Rider) obj;
if (basic != other.basic)
return false;
if (id != other.id)
return false;
if (riderCode == null) {
if (other.riderCode != null)
return false;
} else if (!riderCode.equals(other.riderCode))
return false;
if (riderName == null) {
if (other.riderName != null)
return false;
} else if (!riderName.equals(other.riderName))
return false;
return true;
}
}
Hibernate配置文件
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.url">jdbc:mysql://localhost/illu</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property> <!--如果使用的是本地事务(jdbc事务) ,此配置将不需要再close session了; getCurrentSession创建的session会和绑定到当前线程,而openSession不会; getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭; --> <property name="current_session_context_class">thread</property> <!-- 如果使用的是全局事务(jta事务) --> <!-- <property name="hibernate.current_session_context_class">jta</property> --> <!-- 指定实体的具体路径,否则hibernate找不到 --> <mapping class="com.gc.sis.core.Illu"/> <mapping class="com.gc.sis.core.Client"/> <mapping class="com.gc.sis.core.Rider"/> </session-factory> </hibernate-configuration>
Hibernate工具类
package com.gc.sis.util;
import java.util.Map;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class HibernateUtil {
private static SessionFactory factory;
private static ServiceRegistry serviceRegistry;
static{
Configuration cfg = new Configuration().configure();
Map map = cfg.getProperties();
for(Object key : map.keySet()) {
//可以打印出很多系统属性!
//System.out.println(key);
//System.out.println(map.get(key));
}
serviceRegistry = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
factory = cfg.buildSessionFactory(serviceRegistry);
}
public static Session getSession() {
return factory.getCurrentSession();
}
}
测试类
package com.gc.sis.core;
import java.util.Set;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import junit.framework.TestCase;
import org.hibernate.Session;
import org.junit.Test;
import com.gc.sis.util.HibernateUtil;
public class HibernateTest extends TestCase{
/**
* 保存数据
*/
@Test
public void testSave() {
int singlePrem = 10000;
Illu illu = new Illu();
illu.setSinglePrem(singlePrem);
Client c1 = new Client("zs", 20, "teacher");
Client c2 = new Client("ls", 30, "worker");
illu.getClients().add(c1);
illu.getClients().add(c2);
Rider r1 = new Rider("PE01", "A", true);
Rider r2 = new Rider("MM02", "B", false);
illu.getRiders().add(r1);
illu.getRiders().add(r2);
Session session = HibernateUtil.getSession();
try {
session.beginTransaction();
session.save(illu);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
System.out.println("session connect:"+session.isConnected());//自动关闭
}
/**
* 获取数据
*/
public void testGet() {
Session session = HibernateUtil.getSession();
try {
session.beginTransaction();
Illu illu = (Illu)session.get(Illu.class, 1);
System.out.println(illu.getSinglePrem());
Set<Client> clients = illu.getClients();
for(Client c : clients) {
System.out.println(c.getName()+","+c.getAge()+","+c.getProfession());
}
Set<Rider> riders = illu.getRiders();
for(Rider r : riders) {
System.out.println(r.getRiderCode()+","+r.getRiderName()+","+r.isBasic());
}
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
}
/**
* 对象转xml
*/
public void testObject2XML() {
Session session = HibernateUtil.getSession();
try {
session.beginTransaction();
Illu illu = (Illu)session.get(Illu.class, 1);
JAXBContext ctx = JAXBContext.newInstance(Illu.class);
Marshaller marshaller = ctx.createMarshaller();
marshaller.marshal(illu, System.out);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
}
}
对象转为XML的结果
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <illu> <clients> <age>30</age> <id>1</id> <name>ls</name> <profession>worker</profession> </clients> <clients> <age>20</age> <id>2</id> <name>zs</name> <profession>teacher</profession> </clients> <riders> <basic>true</basic> <riderCode>PE01</riderCode> <riderName>A</riderName> </riders> <riders> <basic>false</basic> <riderCode>MM02</riderCode> <riderName>B</riderName> </riders> <singlePrem>10000</singlePrem> </illu>