双向多对一映射其实跟单向差不多,只是在一方多了些配置,使一方能获取到多方的相关数据
应用场景:以学生与老师为例,学生为多的一方,老师是一的一方,在特定的情况下,一个学生只面对一个老师,但一个老师要面对多个学生。单向则是从多方学的生这边可以获取老师的信息,一方的老师这边也可以获取他下面有哪些学生。如下:
- 实体类:
Studentpublic class Student { private int id; private String name; private Date birthday; private int age; private Teacher teacher; setter ..... getter...... @Override public String toString() { return "Student [id=" + id + ", name=" + name + ", birthday=" + birthday + ", age=" + age + ", teacher=" + teacher + "]"; }
Teacher
public class Teacher { private int id; private String name; private Set<Student> students=new HashSet<Student>(); setter............ getter....... @Override public String toString() { return "Teacher [id=" + id + ", name=" + name + "]"; } }
注意:在写tostring方法时如果 有集合属性,按默认生成的toString方法,将其直接写入,在进行hibernate查询时,如果直接打印查询到的对象,会出现java.lang.StackOverflowError的异常,需去掉集合。
如:Teacher类中写成:
public String toString() {
return “Teacher [id=” + id + “, name=” + name + “, students=” + students + “]”;
}
- hbm.xml映射配置
Student.hbm.xml<hibernate-mapping package="com.restfullDemo.model"> <class name="Student" table="students"> <id name="id" type="int"> <column name="id" /> <generator class="native" /> </id> <property name="name" type="java.lang.String"> <column name="s_name" /> </property> <property name="birthday" type="java.util.Date"> <column name="birthday" /> </property> <!-- <property name="age" type="int" formula="(SELECT FLOOR(DATEDIFF(NOW(),s.birthday)/365.25) FROM students s where s.id=id)"/> --> <!-- 双向多对一(多方一端的配置) --> <many-to-one name="teacher" class="Teacher"> <!-- 外键 --> <column name="tec_id" /> </many-to-one> </class></hibernate-mapping>
Teacher.hbm.xml
<hibernate-mapping package="com.restfullDemo.model"> <class name="Teacher" table="theachers"> <id name="id" type="int"> <column name="id" /> <generator class="native" /> </id> <property name="name" type="java.lang.String"> <column name="t_name" /> </property> <!-- inverses:作用是指定双向多对一的映射中,由哪一端来进行维护默认值为inverse="false",表示不放弃维护 ,inverse="true"表示放弃维护,一般在一的一方设置为inverse="true",来减少程序对数据的访问--> <set name="students" table="students" inverse="true" lazy="false"> <key> <!-- 此处值为 students表中的外键 --> <column name="tec_id" /> </key> <one-to-many class="Student" /> </set> </class> </hibernate-mapping>
- 测试
import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.boot.MetadataSources;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import org.junit.After;import org.junit.Before;import org.junit.Test;import com.restfullDemo.model.Student;import com.restfullDemo.model.Teacher;/** * @author: ljd * @date:2018年10月28日 下午1:55:13 * */public class TestStudentDao { SessionFactory sessionFactory; Session session; Transaction transaction; @Before public void init() { Configuration configuration=new Configuration().configure(); ServiceRegistry serviceRegistry=configuration.getStandardServiceRegistryBuilder().build(); sessionFactory=new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory(); session=sessionFactory.openSession(); transaction=session.beginTransaction(); } @After public void closeSession() { transaction.commit(); session.close(); } @Test public void saveTeache() throws ParseException{ Teacher tc=new Teacher(); tc.setName("张老师"); /* 学生 */ Student st=new Student(); st.setName("李四"); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); Date dt=sdf.parse("2001-05-10"); st.setBirthday(dt); st.setTeacher(tc); Student st2=new Student(); st2.setName("小胖"); Date dt3=sdf.parse("2001-03-10"); st2.setBirthday(dt3); st2.setTeacher(tc); tc.getStudents().add(st); tc.getStudents().add(st2); /* 在数据库表中同时插入多方和一方的数据时,先插入一方的数据,再插入多方的数据,效率会更高些 */ session.save(tc); session.save(st2); session.save(st); }}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/71208.html