一个销售员salesman对应一个地址Address:
1.数据库建表SQL:
use test;
create table salesman3(sid int not null primary key, salesName varchar(20));
create table address(aid int not null primary key, province varchar(20),city varchar(20),street varchar(20),gatenumber int, foreign key(aid) references salesman(sid));
2.model:
Salesman.java:
package ie.basicCar3.bean;
public class Salesman implements java.io.Serializable{
private long sid;
private String salesName;
private Address saddress;
public Salesman() {
}
public Salesman(String salesname, Address a) {
this.salesName = salesname;
this.saddress = a;
}
//省略了getter setter方法
}
Address.java:
package ie.basicCar3.bean;
public class Address implements java.io.Serializable{
private long aid;
private String province;
private String city;
private String street;
private int gatenumber;
private Salesman salesman;
public Address(){
}
public Address(String p, String c, String s,int n){
this.province=p;
this.city=c;
this.street=s;
this.gatenumber=n;
}
//省略了getter setter方法
}
3.Hibernate映射文件:
Salesman.hbm.xml:
<hibernate-mapping>
<class name="ie.basicCar3.bean.Salesman" table="salesman3" lazy="false">
<id column="sid" name="sid" type="long">
<generator class="increment"></generator>
</id>
<property name="salesname" column="salesname" type="string">
</property>
<one-to-one
name="saddress"
class="ie.basicCar3.bean.Address"
cascade="all"
></one-to-one>
</class>
</hibernate-mapping>
Address.hbm.xml:
<hibernate-mapping>
<class name="ie.basicCar3.bean.Address" table="address" lazy="false">
<id name="aid" column="aid" type="long">
<generator class="foreign">
<param name="property">salesman</param>
</generator>
</id>
<property name="province" column="province" type="string">
</property>
<property name="city" column="city" type="string">
</property>
<property name="street" column="street" type="string">
</property>
<property name="gatenumber" column="gatenumber" type="int">
</property>
<one-to-one
name="salesman"
class="ie.basicCar3.bean.Salesman"
constrained="true"
cascade="save-update">
</one-to-one>
</class>
</hibernate-mapping>
在上面的映射文件中,特别注意主键的生成方式为foreign。使用foreign作为标识符生成器,说明这个主键同时也作为外键,依赖于另一个相关联表的主键,所以需要<param>元素来制定要关联的实体。
constrained属性为true,说明address表的id主键同时作为外键参照salesman表。这个选项影响save()和delete()在级联执行时的先后顺序,其默认是false。
其它属性的含义与一对多里的相同。
单向一对一,则只配置其中一部分,同时根据实际需要,注意选择cascade的属性值。
4.测试类:
package ie.basicCar3;
import java.sql.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import ie.basicCar3.bean.Address;
import ie.basicCar3.bean.Salesman;
public class Test {
Configuration cfg;
SessionFactory sf;
Session session;
public static void main(String[] args) {
Test test=new Test();
test.DoConfiguration();
//test.saveEntity();
test.updateEntity();
//test.deleteEntity();
System.out.println("end");
}
void DoConfiguration(){
// new a configuration and read the configuration from the given path
cfg = new Configuration();
cfg.configure("ie/basicCar3/hibernate.cfg.xml");
//use the properites in the configure file to new a sessionFactory
sf = cfg.buildSessionFactory();
}
void saveEntity() {
// new a session from sessionfactory
session = sf.openSession();
// save a BasicCar in database
Transaction tx1 = session.beginTransaction();
Address ad = new Address("guangdong3", "guangzhou", "dexing", 104);
Salesman ss = new Salesman("bbb78", ad);
//不管设置了cascade还是没有,保存了一个,都会自动保存另一个,写任何一个的save,或者两个,都是两个表都保存一下
ad.setSalesman(ss);
//ss.setSaddress(ad);
//session.save(ss);
session.save(ad);
// System.out.println(bc1.getFactory());
tx1.commit();
//close session
session.close();
}
void deleteEntity() {
// new a session from sessionfactory
session = sf.openSession();
//delete the id=1 basicCar Object from database
Transaction tx3 = session.beginTransaction();
try {
//Address add = (Address) session.load(Address.class, new Long(12));
//如果address.hbm.xml有cascade="delete",那么可以连着把salesman也删除,否则只删除address
//session.delete(add);
Salesman sas = (Salesman) session.load(Salesman.class, new Long(4));
//由于foreign key约束不能只是删salesman,而不删除address
//如果salesman.hbm.xml没有cascade="delete",但是因为数据库里有foreign key约束,所以会报错Cannot delete or update a parent row: a foreign key constraint fails
// session.delete(sas.getSaddress());
session.delete(sas);
} catch (Exception e) {
System.out.println("id=1 car are not existed, can't be deleted");
}
tx3.commit();
//close session
session.close();
}
void updateEntity() {
// new a session from sessionfactory
session = sf.openSession();
//update the name of besicCar above into databas
Transaction tx2 = session.beginTransaction();
Address a1 = (Address) session.load(Address.class, new Long(1));
//a1.getSalesman().setSalesname("gagagaga");
session.update(a1);
//Salesman sas2 = (Salesman) session.load(Salesman.class, new Long(4));
//sas2.getSaddress().setCity("nanjing2");
//session.update(sas2);
tx2.commit();
//close session
session.close();
}
void queryEntity() {
// new a session from sessionfactory
session = sf.openSession();
// query a car from database
/* try{
Query query=session.createQuery("from BasicCar");
BasicCar bc3=(BasicCar)query.list().get(0);
System.out.println("name for the first selected car is: "+bc3.getName());
}catch (Exception e)
{
System.out.println("no car in database");
}*/
//close session
session.close();
}
}
5.导入Hibernate jar包,jdbc驱动,再加一个Hibernate配置文件(如下),就可以用运行测试类,一对多配置完成,可以根据实际需求调整相应的映射文件。
hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.password">embed</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:@192.168.100.231:1521:typt</property>
<property name="hibernate.connection.username">dbcdc</property>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle9iDialect</property>
<!-- mapping resource="basicCar/bean/BasicCar1.hbm.xml"/-->
<mapping resource="ie/basicCar3/bean/Address.hbm.xml"/>
<mapping resource="ie/basicCar3/bean/Salesman.hbm.xml"/>
</session-factory>
</hibernate-configuration>