Hibernate notes:<1-n>
单向的1对n关联关系:
- 1. 首先进行Jar包的导入,然后编辑配置文件:
在进行jar包的导入时候,老师给的方法是通过加载的方式找到框架开源文件中的hibernate用的jar包然后找到你想用的数据库的驱动包,直接加载到工程中;这种方法的缺点是当你把此工程导出然后再在别的电脑上进行导入的时候会出现红的感叹号,提示错误,其实就是没有进行jar的配置,在视频中看到是直接在工程下新建一个文件包,用于存放这些需要的jar,然后再进行加载,这样在导入时候就不会出现那种错误,毕竟进行导出的时候把jar一起导入了(前提是版本一样)。
编译配置文件,代码如下:
<?xml version="1.0" encoding="UTF-8"?> <!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.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql:///test</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">123456</property>
<!-- 配置数据库方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置数据库表的生成方式 -->
<property name="hbm2ddl.auto">update</property>
<!-- 配置SQL格式 -->
<property name="show_sql">true</property> <property name="format_sql">true</property>
<!-- 配置加载关系映文件的路径 -->
<mapping resource="qau/edu/ren/Teams.hbm.xml"/> <mapping resource="qau/edu/ren/City.hbm.xml"/>
</session-factory> </hibernate-configuration>
|
在上次进行头文件的重新加载之后,没有出现上次的错误。
配置时还是牢记配置项目:
数据库连接信息------>数据库方言的选择 ------> SQL输出格式配置 ---- >数据表生成的方式配置 ----- >映射文件的加载路径
- 2. 编译POJO,代码:
package qau.edu.ren;
import java.util.Date; import java.util.HashSet; import java.util.Set;
public class City {
private int id ; private String name ; private Date date;
private Set<Teams> team = new HashSet<Teams>();
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 Date getDate() { return date; }
public void setDate(Date date) { this.date = date; }
public Set<Teams> getTeam() { return team; }
public void setTeam(Set<Teams> team) { this.team = team; }
public City() { super(); }
@Override public String toString() { return "City : [id=" + id + ", name=" + name + ", date=" + date + "]"; }
} |
package qau.edu.ren;
import java.util.Date;
public class Teams {
private int id ; private String name ; private Date date; private String color ; 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 Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public Teams() { super(); } @Override public String toString() { return "Teams : [id=" + id + ", name=" + name + ", date=" + date + ", color=" + color + "]"; } }
|
3.编译关系映射文件:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="qau.edu.ren">
<class name="City" table="t_city">
<id name="id" column="c_id"> <generator class="native"/> </id>
<property name="name" column="c_name"/> <property name="date" column="c_date"/>
<!-- 配置one-to-many关联关系 -->
<set name="team" table="t_teams"> <key column="c_id"></key> <one-to-many class="Teams"/> </set>
</class>
</hibernate-mapping>
|
总结:
<set name="team" table="t_teams">
<key column="c_id"></key> <one-to-many class="Teams"/>
</set> |
这是关系映射的关键: 1.set:指的是用于设置当前持久化类中set类型的属性. 2.Name: 指的是待映射的持久化对象在当前实体类中属性的名字;如:City类中的Teams 属性的名字:team. 3.table:指的是待映射的持久化对象在当前实体类中属性的在什么表中的对应的字段(列)。【非必须】 4.Key:指的是设置外键,column指的是关联表的外键名字。 5.One-to-many:用于设置1-n关联中,待映射的持久化类名字。(这里是Teams类)
也可以这样概括:set当然是用于设置当前实体类中set集合类型的属性的,由关系/映射的理论可以知道,实体类中的属性是映射成数据表中字段,也就是列的,那么这样的集合属性是不能放在“1”的这一端的,只能放在“n”生成的数据表中,而table的作用就是告诉他集合属性应该映射到什么表中。然后,进行关联时,就要通过外键进行关联两张表,这就是key要做的事情,用于指定关联的外键,而他中的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">
<hibernate-mapping package="qau.edu.ren">
<class name="Teams" table="t_teams">
<id name="id" column="t_id"> <generator class="native"/> </id>
<property name="name" column="t_name"/> <property name="date" column="t_date"/> <property name="color" column="t_color"/>
</class> </hibernate-mapping>
|
3.编写测试类:
代码:
package qau.edu.ren;
import java.util.Date;
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration;
public class Test {
public static void main(String[] args) {
// 创建configuration对象;加载配置文件;
Configuration con = new Configuration().configure();
// 创建SessionFactory;
SessionFactory factory = con.buildSessionFactory();
// 创建Session;
Session sess = factory.openSession();
// 开始事务;
Transaction tr = sess.beginTransaction();
// 创建对象;
City c = new City();
// set属性;
c.setDate(new Date()); c.setName("Binzhou");
Teams t1 = new Teams(); Teams t2 = new Teams();
t1.setName("AAAAA"); t1.setColor("aaaaa"); t1.setDate(new Date());
t2.setName("BBBBB"); t2.setColor("bbbbb"); t2.setDate(new Date());
// 设置关联;
c.getTeam().add(t1); c.getTeam().add(t2);
// 保存对象;
sess.save(c); sess.save(t1); sess.save(t2);
// 提交事务;
tr.commit();
// 关闭Session;
sess.close();
} } |
执行结果:
Hibernate: insert into t_city (c_name, c_date) values (?, ?) Hibernate: insert into t_teams (t_name, t_date, t_color) values (?, ?, ?) Hibernate: insert into t_teams (t_name, t_date, t_color) values (?, ?, ?) Hibernate: update t_teams set c_id=? where t_id=? Hibernate: update t_teams set c_id=? where t_id=? |
上面是先插入的“1”的一端,再看先插入“n”的一端的执行结果:
Hibernate: insert into t_teams (t_name, t_date, t_color) values (?, ?, ?) Hibernate: insert into t_teams (t_name, t_date, t_color) values (?, ?, ?) Hibernate: insert into t_city (c_name, c_date) values (?, ?) Hibernate: update t_teams set c_id=? where t_id=? Hibernate: update t_teams set c_id=? where t_id=?
|
观察之后还是和上面的一样,即不只是进行了insert插入,而且还进行了update操作。
在进行many-to-one 关联时,只有先插入”n”的一端,才会是这样的结果,但是为什么先进行”1”的一端插入还是这样呢?
原因就是当先插入“1”的一端的时候,在“1”的一端有“n”的属性,在没有进行”n”的一端的插入时,是没有办法插入的,所以只能在“n”的一端插入完成之后,通过更新进行插入。
【没有经过实践,没有资格说会什么,即使很简单的事情。】