文档章节

表的影射关系: 一对多,一对一,多对多

CarlDing
 CarlDing
发布于 2016/06/27 14:55
字数 1255
阅读 60
收藏 0

表的影射关系:

  一对多,一对一,多对多

 

Session - QBC -

        save/delete/update/persist=save

        HQL - 对类的查询

 

1:一对多

表的关系:

   一个人,可以很多的车的

   Person          car 一般在car表中创建一个外键引用person表中的主键。

   Id  name        id  name  car_pid

 

  在类上的关系是:

Person{

     Set<Car> cars;  || List<Car> || Car[] cars  || Map<String,Car> cars

}

 

Car{

    Person person;   

}

创建对象模型:

一方 使用set集来影射。

public class Person {

private String id;

private String name;

private Set<Car> cars = new HashSet<>();

 

在配置文件中,使用<one-to-many>来影射多方:

  

      <class name="cn.hib.domain.Person" table="persons">

        <id name="id" type="java.lang.String" length="32">

            <column name="person_id" />

            <generator class="uuid" />

        </id>

        <property name="name" type="java.lang.String" length="30">

            <column name="person_name" />

        </property>

        <!-- 声明一对多的关系 Set<Car>-->

        <set name="cars">

         <!-- 关联的是car.car_pid,必须要指定外键 -->

         <key column="car_pid"></key>

         <!-- 一对多 -->

         <one-to-many class="cn.hib.domain.Car"/>

        </set>

</class>

 

 

    <class name="cn.hib.domain.Car" table="cars">

        <id name="id" type="java.lang.String" length="32">

            <column name="car_id" />

            <generator class="uuid" />

        </id>

        <property name="name" type="java.lang.String" length="30">

            <column name="car_name" />

        </property>

        <!-- 配置多对一 -->

        <many-to-one name="person" column="car_pid"></many-to-one>

</class>

 

 

1:测试保存

 

@Test

public void testSave() {

Session s = HibernateUitls.openSession();

Transaction tx = s.beginTransaction();

Person p = new Person();

p.setName("张三");

Car c1 = new Car();

c1.setName("Audi");

Car c2 = new Car();

c2.setName("Buick");

p.getCars().add(c1);

p.getCars().add(c2);

 

s.save(c1);

s.save(c2);

s.save(p);

 

tx.commit();

s.close();

 

}

Hibernate: insert into cars (car_name, car_pid, car_id) values (?, ?, ?)

Hibernate: insert into cars (car_name, car_pid, car_id) values (?, ?, ?)

Hibernate: insert into persons (person_name, person_id) values (?, ?)

Hibernate: update cars set car_pid=? where car_id=?

Hibernate: update cars set car_pid=? where car_id=?

 

 

2:级联保存
  <!-- 声明一对多的关系 Set<Car>-->

        <set name="cars" cascade="save-update">

         

         <!-- 关联的是car.car_pid,必须要指定外键 -->

         <key column="car_pid"></key>

         <!-- 一对多 -->

         <one-to-many class="cn.hib.domain.Car"/>

        </set>

 

 

 

3:根据一个对象查询出另一个对象

@Test

public void testQuery() {

Session s = HibernateUitls.openSession();

// 执行查询person的sql

Person p = s.get(Person.class, "4028806a556d85b101556d85b35b0000");

// 根据Peson对象获取所有车,查询cars表

Set<Car> set = p.getCars();

System.err.println(set);

 

p = (Person) s.createCriteria(Person.class).add(Restrictions.idEq("4028806a556d85b101556d85b35b0000")).uniqueResult();

set = p.getCars();

System.err.println(set);

 

 

p = (Person) s.createQuery("from Person where id=:id")

.setString("id","4028806a556d85b101556d85b35b0000").uniqueResult();

set= p.getCars();

System.err.println(set);

 

s.close();

}

 

 

4:关联查询 - 查询某个有某车

SELECT p.person_name,c.car_name FROM

persons p INNER JOIN cars c ON p.person_id=c.car_pid;

 

Session s = HibernateUitls.openSession();

List list = s.createCriteria(Person.class)// 添加主对象

.createAlias("cars", "c")// 创建一个关联对象,此时关联的对象是person类的自己的属性

.setProjection(Projections.projectionList()// 创建投影的集合

.add(Projections.property("name"), "pname")//

.add(Projections.property("c.name"), "cname")//

)//

.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)//

.list();

System.err.println(list);

s.close();

 

关联的对象都是自己的属性:

  @Test

public void testQuery3() {

Session s = HibernateUitls.openSession();

List list = s.createQuery("select new map(p.name as pnm,c.name as cn)" //

+ " from Person p inner join p.cars c").list();

System.err.println(list);

s.close();

}

 

5:子查询- 数量查询有N部的车人的

SELECT * FROM persons p WHERE (SELECT COUNT(1) FROM cars c WHERE c.car_pid=p.person_id)=2;  

 

@Test

public void testQuery41() {

Session s = HibernateUitls.openSession();

List list  =

s.createCriteria(Person.class)

.add(Restrictions.sizeEq("cars", 2))

.list();

System.err.println(list);

s.close();

}

 

@Test

public void testQuery42() {

Session s = HibernateUitls.openSession();

List list =

s.createQuery("from Person where size(cars)=1").list();

System.err.println(list);

s.close();

}

 

 

 

2:使用<bag>来影射无下标的List集合

 

public class Person {

private String id;

private String name;

private List<Car> cars = new ArrayList<>();

 

        <bag name="cars" cascade="save-update">

         <!-- 关联的是car.car_pid,必须要指定外键 -->

         <key column="car_pid"></key>

         <!-- 一对多 -->

         <one-to-many class="cn.hib.domain.Car"/>

        </bag>

 

 

3:使用<list>影射有下标的List

public class Person {

private String id;

private String name;

private List<Car> cars = new ArrayList<>();

 

   <list name="cars" cascade="save-update">

         <!-- 关联的是car.car_pid,必须要指定外键 -->

         <key column="car_pid"></key>

         <!-- 在cars表中保存下标的列 -->

         <index column="car_idx" type="integer"></index>

         <!-- 一对多 -->

         <one-to-many class="cn.hib.domain.Car"/>

        </list>

 

 

 

 

4:多对多

一个学生可以选择很多的课:

  学生 Studs                         课Courses

              创建中间表sc

                Sid   cid

多对多:

   Stud{

      Set<Course> courses;

   }

 

   Course{

     Set<Stud> studs;

   }

 

 

 

public class Course {

private String id;

private String name;

private Set<Stud> studs = new HashSet<>();

 

public class Stud {

private String id;

private String name;

private Set<Course> courses = new HashSet<>();

 

<?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>

<class name="cn.hib.domain.Stud" table="studs">

<id name="id" column="stud_id" type="string" length="32">

<generator class="uuid"></generator>

</id>

<property name="name" column="stud_name" length="30" type="string"/>

<!-- 多对多,是使用many-to-many实现的 -->

<set name="courses" table="sc">

<key column="sc_sid"></key>

<many-to-many class="cn.hib.domain.Course" column="sc_cid"></many-to-many>

</set>

</class>

<class name="cn.hib.domain.Course" table="courses">

<id name="id" type="string" length="32">

<column name="course_id"/>

<generator class="uuid"></generator>

</id>

<property name="name" column="course_name" type="string" length="30"/>

<set name="studs" table="sc">

<key column="sc_cid"/>

<many-to-many class="cn.hib.domain.Stud" column="sc_sid"></many-to-many>

</set>

</class>

</hibernate-mapping>

 

 

 

@Test

public void testSave() {

Session s = HibernateUitls.openSession();

s.beginTransaction();

 

Stud stud = new Stud();

stud.setName("Jack");

 

Course c = new Course();

c.setName("Java");

 

stud.getCourses().add(c);

s.save(stud);

 

s.getTransaction().commit();

 

s.close();

}

 

根据某一个学生,查询出这个学生选择了什么课?

 

 

查询哪一个学生,选择了哪一个课?

 

SELECT s.stud_name ,c.course_name

FROM studs s INNER JOIN sc ON s.stud_id=sc.sc_sid

             INNER JOIN courses c ON c.course_id=sc.sc_cid;

 

 

@Test

public void testQuery() {

Session s = HibernateUitls.openSession();

List list =  s.createQuery("select new map(s.name as sname,c.name as cname)"//

  + " from Stud s join s.courses c").list();

System.err.println(list);

}

 

请使用Criteira实现上面的查询:

  

 

查询选择了N课的学生?

@Test

public void testSize() {

Session s = HibernateUitls.openSession();

List list =  s.createQuery(""//

  + " from Stud s where s.courses.size=1").list();

System.err.println(list);

}

 

 

5:一对一

两种实现:

   主键对唯一

 

 

public class Man {

private String id;

private String name;

private Card card;

 

public class Card {

private String id;

private String gov;

private Man man;

 

    <class name="cn.hib.domain.Man" table="man">

        <id name="id" type="java.lang.String" length="32">

            <column name="id" />

            <generator class="uuid" />

        </id>

        <property name="name" type="java.lang.String" length="30">

            <column name="name" />

        </property>

<one-to-one name="card"></one-to-one>

    </class>

     <class name="cn.hib.domain.Card" table="card">

        <id name="id" type="java.lang.String" length="32">

            <column name="id" />

            <generator class="uuid" />

        </id>

        <property name="gov" type="java.lang.String" length="30">

            <column name="gov" />

        </property>

<many-to-one name="man" column="card_mid" unique="true"></many-to-one>

</class>

 

 

   主键对主键

© 著作权归作者所有

CarlDing
粉丝 5
博文 106
码字总数 78103
作品 0
济南
其他
私信 提问
oracle 数据库设计-数据库表设计

在数据库设计中,我的工作中经常会分析怎样商业逻辑中的表格如何设计。再设计表的关系之前 需要先了解关系型数据库特点 1关系型数据库,是指采用了关系模型来组织数据的数据库; 2、关系型数...

荜拨
2018/07/02
0
0
对于需求文档的疑问以及表设计提取

1.疑问 微信版本-公众号平台?--后期讨论 企业认证是否要考虑营业执照认证?--后期讨论 2.功能表信息 企业信息表 教师信息表 校区信息表 教室信息表 课程种类表 课程信息表 档期信息表 教师日...

UreyGao
2017/08/05
2
0
Yii 多表关联relations

1,首先多表关联是在models/xx.php的relations里配置的。而且是互配,但有区别。 格式: 'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...additional options) 需要弄清楚的......

rooney
2014/07/12
138
0
Laravel Eloquent Orm 使用指南

1、描述1vs1关系 例如比如又两张表,一张用户表,一张手机表,一个用户只有一个手机,一个手机也只属于一个人,就表达了一对一的关系 class User extends Eloquent { //一对一 public funct...

tree2013
2016/03/26
257
0
Hibernate映射解析——七种映射关系

首先我们了解一个名词ORM,全称是(Object Relational Mapping),即对象关系映射。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现,这样开发人员就可以把对数据库的...

universeye
2014/05/15
186
0

没有更多内容

加载失败,请刷新页面

加载更多

golang-字符串-地址分析

demo package mainimport "fmt"func main() {str := "map.baidu.com"fmt.Println(&str, str)str = str[0:5]fmt.Println(&str, str)str = "abc"fmt.Println(&s......

李琼涛
今天
4
0
Spring Boot WebFlux 增删改查完整实战 demo

03:WebFlux Web CRUD 实践 前言 上一篇基于功能性端点去创建一个简单服务,实现了 Hello 。这一篇用 Spring Boot WebFlux 的注解控制层技术创建一个 CRUD WebFlux 应用,让开发更方便。这里...

泥瓦匠BYSocket
今天
9
0
从0开始学FreeRTOS-(列表与列表项)-3

FreeRTOS列表&列表项的源码解读 第一次看列表与列表项的时候,感觉很像是链表,虽然我自己的链表也不太会,但是就是感觉很像。 在FreeRTOS中,列表与列表项使用得非常多,是FreeRTOS的一个数...

杰杰1号
今天
9
0
Java反射

Java 反射 反射是框架设计的灵魂(使用的前提条件:必须先得到代表的字节码的 Class,Class 类 用于表示.class 文件(字节码)) 一、反射的概述 定义:JAVA 反射机制是在运行状态中,对于任...

zzz1122334
今天
9
0
聊聊nacos的LocalConfigInfoProcessor

序 本文主要研究一下nacos的LocalConfigInfoProcessor LocalConfigInfoProcessor nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/config/impl/LocalConfigInfoProcessor.java p......

go4it
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部