Hibernate的写法总结
- 普通表操作
普通操作莫过于CRUD,建好表了之后对表的数据进行操作。详见代码。
package package2; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; public class HibernateExecute { public static void main(String[] args) { HibernateController hc=new HibernateController(); persion toadd=new persion(); toadd.setId(6); toadd.setName("lkxj"); hc.update(toadd); } } class HibernateUtil{ private static SessionFactory ssf; static{ Configuration cfg=new Configuration().configure(); ssf=cfg.buildSessionFactory(); } public static Session getSession(){ Session session=ssf.openSession(); return session; } public static void closeSession(Session session){ session.close(); } } class HibernateController implements DAOInterface{ // 添加信息 @Override public void add(persion p) { Session session=HibernateUtil.getSession(); Transaction transaction=session.beginTransaction(); try{ session.save(p); transaction.commit(); }catch (Exception e) { // TODO: handle exception transaction.rollback(); }finally { HibernateUtil.closeSession(session); } } // 删除信息 @Override public void delete(persion p) { // TODO Auto-generated method stub Session session=HibernateUtil.getSession(); Transaction transaction=session.beginTransaction(); try{ session.delete(p); transaction.commit(); }catch (Exception e) { // TODO: handle exception transaction.rollback(); }finally { HibernateUtil.closeSession(session); } } // 搜寻信息 @Override public persion search(int id) { // TODO Auto-generated method stub Session session=HibernateUtil.getSession(); Transaction transaction=session.beginTransaction(); persion p=null; try{ p=(persion)session.get(persion.class, id); transaction.commit(); }catch (Exception e) { // TODO: handle exception transaction.rollback(); }finally { HibernateUtil.closeSession(session); } return p; } // 更新信息 @Override public void update(persion p) { // TODO Auto-generated method stub Session session=HibernateUtil.getSession(); Transaction transaction=session.beginTransaction(); try{ session.update(p); transaction.commit(); }catch (Exception e) { // TODO: handle exception transaction.rollback(); }finally { HibernateUtil.closeSession(session); } } }
bean类如下
package package2; public class persion { int id; String name; 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; } }
persion.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2016-7-20 15:57:35 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="package2.persion" table="PERSION"> <id name="id" type="int"> <column name="id" /> <generator class="assigned" /> </id> <property name="name" type="java.lang.String"> <column name="name" /> </property> </class> </hibernate-mapping>
在hiberna.cfg.xml末尾添加一行
<mapping resource="package2/persion.hbm.xml" />
- 映射关系
一对一映射:比如一个用户只有一个地址。实现的方式有两种,一,主键关联;二,外键关联。
主键关联就是两个表的主键其中一个为另外一个表的外键。比如user表的主键,为address表的外键,这个address的外键正好就是它这个表的主键。user为主表,address为从表。address的外键引用的时user的主键。在下面的设计中,是user类为address的从表,user的生成策略为foreign,表示主键由关联类产生。
User.java
package HibernateRelation; //一个用户只有一个地址 public class User { private int userid; private String name; private String password; private Address address; public User(){ } public User(String name,String password,Address address){ this.name=name; this.password=password; this.address=address; } public int getUserid() { return userid; } public void setUserid(int userid) { this.userid = userid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } }
Address.java
package HibernateRelation; public class Address { private int addressid; private String addressinfo; public Address(int addressid,String addressinfo){ this.addressid=addressid; this.addressinfo=addressinfo; } public Address(){ } public int getAddressid() { return addressid; } public void setAddressid(int addressid) { this.addressid = addressid; } public String getAddressinfo() { return addressinfo; } public void setAddressinfo(String addressinfo) { this.addressinfo = addressinfo; } }
User.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2016-8-16 14:48:03 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="HibernateRelation.User" table="USER"> <id name="userid" type="int" access="field"> <column name="USERID" /> <!--由关联类来生成主键 --> <generator class="foreign" > <param name="property">address</param> </generator> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <property name="password" type="java.lang.String"> <column name="PASSWORD" /> </property> <!--基于主键的一对一映射--> <one-to-one name="address" class="HibernateRelation.Address" constrained="true"> </one-to-one> </class> </hibernate-mapping>
Address.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2016-8-16 14:48:03 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="HibernateRelation.Address" table="ADDRESS"> <id name="addressid" type="int" access="field"> <column name="ADDRESSID" /> <generator class="identity" /><!--主键生成策略--> </id> <property name="addressinfo" type="java.lang.String"> <column name="ADDRESSINFO" /> </property> </class> </hibernate-mapping>
惯例,在总配置文件中添加映射,和自动建表配置。
<property name="hibernate.hbm2ddl.auto">update</property> <mapping resource="HibernateRelation/User.hbm.xml" /> <mapping resource="HibernateRelation/Address.hbm.xml" />
在这里可以先建表,也可以不用建表,表结构和你写的类关系类似。遇到一个错误,在one-to-one的标签里添加了column这个属性,会导致一个异常。因为是工具自动产生的。
外键关联:一个表中有主键也有外键,外键是另外一个表的主键的引用。
package HibernateRelation; public class User2 { private int userid; private String name; private String password; private Address2 address2; public Address2 getAddress2() { return address2; } public void setAddress2(Address2 address2) { this.address2 = address2; } public int getUserid() { return userid; } public void setUserid(int userid) { this.userid = userid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
package HibernateRelation; public class Address2 { private int addressid; private String addressinfo; public int getAddressid() { return addressid; } public void setAddressid(int addressid) { this.addressid = addressid; } public String getAddressinfo() { return addressinfo; } public void setAddressinfo(String addressinfo) { this.addressinfo = addressinfo; } }
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2016-8-16 16:49:52 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="HibernateRelation.User2" table="USER2"> <id name="userid" type="int"> <column name="USERID" /> <generator class="identity" /> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <property name="password" type="java.lang.String"> <column name="PASSWORD" /> </property> <many-to-one name="address2" class="HibernateRelation.Address2" fetch="join" unique="true"> <column name="ADDRESS2" /> </many-to-one> </class> </hibernate-mapping>
这个配置文件,主要是写成many-to-one,unique设置为true。column的name为属性名,关联类配置在class中,在表中建立的外键名column中可以设置。
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2016-8-16 16:49:52 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="HibernateRelation.Address2" table="ADDRESS2"> <id name="addressid" type="int"> <column name="ADDRESSID" /> <generator class="identity" /> </id> <property name="addressinfo" type="java.lang.String"> <column name="ADDRESSINFO" /> </property> </class> </hibernate-mapping>
一对多映射:一个用户可以有多个收货地址,在这个设计中,官方说法是在多的一方加入外键,并指向一的一方。就是在address表中加入一个用户id,user的id为地址的识别码,id=2的用户在address表中可以有多条地址记录,他们隶属于外键id=2这个用户之下。
实现方法就是在bean类中加入一个集合set,然后生成xml的时候会自动配置。
package HibernateRelation; import java.util.HashSet; import java.util.Set; //一个用户对应多个地址 public class User1 { private int userid; private String name; private String password; private Set<Address1> addresses=new HashSet<Address1>(); public User1(){ } public User1(int userid,String name,String password){ this.userid=userid; this.name=name; this.password=password; } public int getUserid() { return userid; } public void setUserid(int userid) { this.userid = userid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Set<Address1> getAddresses() { return addresses; } public void setAddresses(Set<Address1> addresses) { this.addresses = addresses; } }
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2016-8-16 15:56:52 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="HibernateRelation.User1" table="USER1"> <id name="userid" type="int"> <column name="USERID" /> <generator class="identity" /> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <property name="password" type="java.lang.String"> <column name="PASSWORD" /> </property> <set name="addresses" table="ADDRESS1" inverse="false" lazy="true"> <key> <column name="USERID" /> </key> <one-to-many class="HibernateRelation.Address1" /> </set> </class> </hibernate-mapping>
package HibernateRelation; public class Address1 { private int addressid; private String addressinfo; public int getAddressid() { return addressid; } public void setAddressid(int addressid) { this.addressid = addressid; } public String getAddressinfo() { return addressinfo; } public void setAddressinfo(String addressinfo) { this.addressinfo = addressinfo; } }
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2016-8-16 15:56:52 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="HibernateRelation.Address1" table="ADDRESS1"> <id name="addressid" type="int"> <column name="ADDRESSID" /> <generator class="identity" /> </id> <property name="addressinfo" type="java.lang.String"> <column name="ADDRESSINFO" /> </property> </class> </hibernate-mapping>
多对多映射:多个用户对应多个地址,这里是单向的多对多,也就是一个用户对应多个地址,一个地址对应多个用户,他们需要有一个中间表,来转换映射。
package HibernateRelation; import java.util.HashSet; import java.util.Set; public class User3 { private int userid; private String name; private String password; private Set<Address3> address3s=new HashSet<Address3>(); public int getUserid() { return userid; } public void setUserid(int userid) { this.userid = userid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Set<Address3> getAddress3s() { return address3s; } public void setAddress3s(Set<Address3> address3s) { this.address3s = address3s; } }
package HibernateRelation; public class Address3 { private int addressid; private String addressinfo; public int getAddressid() { return addressid; } public void setAddressid(int addressid) { this.addressid = addressid; } public String getAddressinfo() { return addressinfo; } public void setAddressinfo(String addressinfo) { this.addressinfo = addressinfo; } }
在这个配置中,需要修改set标签的table属性,改为一个新表,它会生成一个中间表。自动生成时候没有修改报了一个映射异常。
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2016-8-16 18:35:47 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="HibernateRelation.User3" table="USER3"> <id name="userid" type="int"> <column name="USERID" /> <generator class="identity" /> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <property name="password" type="java.lang.String"> <column name="PASSWORD" /> </property> <set name="address3s" table="USER3_ADDRESS3" inverse="false" lazy="true"> <key> <column name="USERID" /> </key> <many-to-many class="HibernateRelation.Address3" column="ADDRESSID"/> </set> </class> </hibernate-mapping>
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2016-8-16 18:35:47 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="HibernateRelation.Address3" table="ADDRESS3"> <id name="addressid" type="int"> <column name="ADDRESSID" /> <generator class="identity" /> </id> <property name="addressinfo" type="java.lang.String"> <column name="ADDRESSINFO" /> </property> </class> </hibernate-mapping>
- 后记
余下细节以后补充。