映射的本质是将关联关系映射到数据库,而关联关系是对象在内存中的引用关系。
多对一的关系:多个对象对应一个对象,比如多个学生对应着一个班级,那么在对象的描述上只需要在学生类中持有一个班级对象的引用即可。
<many-to-one>标签会在多的一端添加一个外键,指向一得一端,这个外键是由<many-to-one>中的column属性定义的,如果忽略属性,默认创建的外键与实体类的属性名相同。
User对象:
package com.jzq.hibernate;
public class User {
int id;
String name;
Group group;
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
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 User(){}
}
User.hbm.xml配置文件:
<hibernate-mapping>
<class name="com.jzq.hibernate.User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- user与group的多对一映射,在多的一端添加一个外键,属性名称与关键字重复所以映射的字段要重命名 -->
<many-to-one name="group" column="groupid" />
</class>
</hibernate-mapping>
Group对象:
package com.jzq.hibernate;
public class Group {
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;
}
}
Group.hbm.xml配置文件:
<hibernate-mapping>
<class name="com.jzq.hibernate.Group" table="t_group">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>
测试代码:
package com.jzq.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import junit.framework.TestCase;
public class ManyToOneTest extends TestCase {
public void testSave1()
{
Configuration configuration=new Configuration().configure();
SessionFactory sessionFactory=configuration.buildSessionFactory();
Session session=sessionFactory.openSession();
try {
session.beginTransaction();
Group group = new Group();
group.setName("魔战");
session.save(group);
for (int i = 0; i < 10; i++) {
User user = new User();
user.setName("user" + i);
//建立对象的关系
user.setGroup(group);
session.save(user);
}
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
}
session.close();
}
}
在测试代码中要注意多个用户对应一个组,即用户类中持有了组的一个对象,所以要先创建一个组对象并关联到数据库中,然后才能保存用户对象到数据库中;在此还可以使用级联cascade。
重要属性:cascade
1,级联是指定两个对象之间的操作联动关系,对一个对象执行操作之后,对其指定的级联对象也需要执行相同的操作。
2,总共可以取值为:all,none,save-update,delete
3,all代表在所有的情况下都执行级联操作
4,none在所有情况下都不执行级联操作
5,save-update在保存和更新的时候执行级联操作
6,delete在删除的时候执行级联操作
在user配置中添加级联属性:
<hibernate-mapping>
<class name="com.jzq.hibernate.User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- user与group的多对一映射,在多的一端添加一个外键,属性名称与关键字重复所以映射的字段要重命名 -->
<many-to-one name="group" column="groupid" cascade="all"/>
</class>
</hibernate-mapping>
测试代码:
package com.jzq.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import junit.framework.TestCase;
public class ManyToOneTest extends TestCase {
public void testSave1()
{
Configuration configuration=new Configuration().configure();
SessionFactory sessionFactory=configuration.buildSessionFactory();
Session session=sessionFactory.openSession();
try {
session.beginTransaction();
Group group = new Group();
group.setName("魔战");
//session.save(group);
for (int i = 0; i < 10; i++) {
User user = new User();
user.setName("user" + i);
//建立对象的关系
user.setGroup(group);
//user设置了cascade所以可以保存user对象的时候会级联保存group
session.save(user);
}
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
}finally{
session.close();
}
}
public void testLoad1()
{
Configuration config=new Configuration().configure();
SessionFactory factory=config.buildSessionFactory();
Session session=factory.openSession();
try {
session.beginTransaction();
User user = (User) session.load(User.class, 30);
System.out.println(user.getName());
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
}finally{
session.close();
}
}
}
注意事项:
结果在运行测试时出现了:Field 'id' doesn't have a default value。其实这只是小问题罢了,我是想在数据库里的主键的类型定义为int的,然后让它自增。出现这样的问题是因为自己粗心。没有在数据库里设置自增。