hibernate 映射关系

关系标签

  1. one-to-one:标签不影响存储,只影响加载,不会修改数据库,也就是说不会添加字段
  2. many-to-one:一般在程序中表现为子表对象里存储一个主表对象,会修改数据库,会增加一个字段

级联操作

cascade:级联的意思是指定两个对象之间的操作联动关系,对一个对象执行了操作之后,对其指定的级联对象也需要执行相同的操作。
其属性值如下:
1. all:在所有的情况下都执行级联操作
2. none:在所有情况下都不执行级联操作
3. save-update:在保存和更新的时候执行级联操作
4. delete:在删除的时候执行级联操作
5.

单向n对1

    public class OrderEntity {
        private int id;
        private String orderName;
        private CustomerEntity customerEntity;
        ...
    }

    <class name="OrderEntity" table="orders" schema="test">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="orderName" column="orderName"/>
        <!--
            customerEntity属性的主键id参照orders表生成字段customerId查询,并且加入外键:customerEntity.id = customerId
        -->
        <many-to-one name="customerEntity" class="CustomerEntity" column="customerId"/>
    </class>
    public class CustomerEntity {
        private int id;
        private String customerName;
        ...
    }

    <class name="CustomerEntity" table="customer" schema="test">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="customerName" column="customerName"/>
    </class>

插入操作:

            // add
            OrderEntity order = new OrderEntity();
            order.setOrderName("test_order1");
            OrderEntity order2 = new OrderEntity();
            order2.setOrderName("test_order1");

            CustomerEntity customer = new CustomerEntity();
            customer.setCustomerName("test_customer2");

            order.setCustomerEntity(customer);
            order2.setCustomerEntity(customer);

            // 3条insert,推荐插入顺序
            session.save(customer);
            session.save(order);
            session.save(order2);

            // 3条insert(customer为null)+2条update
            session.save(order);
            session.save(order2);
            session.save(customer);

查询+更新操作:

            // 查询,默认延迟加载,使用到代理对象的时候才会进行初始化
            OrderEntity orderEntity = session.get(OrderEntity.class, 2);
            // customerEntiy 代理对象
            // update
            orderEntity.setOrderName("hahaha");
            orderEntity.getCustomerEntity().setCustomerName("ooooo");

删除分级联情况考虑。

双向1对n

    public class CustomerEntity {
        private int id;
        private String customerName;
        // 防止空指针
        private Set<OrderEntity> orders = new HashSet<>();
        ...
    }

    <class name="CustomerEntity" table="customer" schema="test">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="customerName" column="customerName"/>

        <!--使用额外java属性:set集合,查询orders表,以 orders.customerId = CustomerEntity.id 作为查询条件-->
        <!--inverse="true":主动方维护关系,推荐-->
        <!--inverse="false":被动方维护关系-->
        <!--不设置inverse,两边都维护-->
        <!--cascade="delete"级联删除-->
        <set name="orders" table="orders" inverse="true" cascade="delete" order-by="orderName desc">
            <key column="customerId"/>
            <one-to-many class="OrderEntity"/>
        </set>
    </class>

orderEntity相同,插入操作

            OrderEntity order = new OrderEntity();
            order.setOrderName("test_order1");
            OrderEntity order2 = new OrderEntity();
            order2.setOrderName("test_order2");

            CustomerEntity customer = new CustomerEntity();
            customer.setCustomerName("test_customer2");

            order.setCustomerEntity(customer);
            order2.setCustomerEntity(customer);
            customer.getOrders().add(order);
            customer.getOrders().add(order2);

            // 3条insert+2条update,推荐插入顺序
            // 设定inverse="true"3条insert
            session.save(customer);
            session.save(order);
            session.save(order2);

查询+更新操作

            // select
            CustomerEntity customerEntity=session.get(CustomerEntity.class,1);
            //代理对象
            System.out.println(customerEntity.getOrders().getClass().getName());
            // 延迟加载
            System.out.println(customerEntity);

            OrderEntity orderEntity=new OrderEntity();
            orderEntity.setOrderName("SDA");
            session.save(orderEntity);

            orderEntity.setCustomerEntity(customerEntity);
            customerEntity.getOrders().add(orderEntity);

            customerEntity.setCustomerName("nimab");

删除操作相同

基于外键的1对1映射关系

存在外键的一端使用,不存在外键的一端使用

    public class DepartmentEntity {
        private int id;
        private String departmentName;
        private Integer managerId;
        private ManagerEntity managerEntity;
        ...
    }

    <!-- 存在外键 DepartmentEntity.managerId = ManagerEntity.id -->
    <class name="DepartmentEntity" table="department" schema="test">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="departmentName" column="departmentName"/>

        <!--
            managerEntity的主键id参照department表生成字段managerId查询,并且生成外键:
            department.managerId = managerEntity.id
        -->
        <many-to-one name="managerEntity" class="ManagerEntity" column="managerId" cascade="all"
                     unique="true"/>
    </class>
    public class ManagerEntity {
        private int id;
        private String managerName;
        private DepartmentEntity departmentEntity;
        ...
    }

    <!--不存在外键,主键被DepartmentEntity.managerId参考-->
    <class name="ManagerEntity" table="manager" schema="test">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="managerName" column="managerName"/>

        <!--
            不生成额外字段和外键
            departmentEntity的主键id参考DepartmentEntity的managerEntity属性的主键id
            departmentEntity.id = DepartmentEntity.managerEntity.id = department.managerId
        -->
        <one-to-one name="departmentEntity" class="DepartmentEntity" property-ref="managerEntity"/>
    </class>

插入操作:

            DepartmentEntity departmentEntity = new DepartmentEntity();
            departmentEntity.setDepartmentName("hashh");
            ManagerEntity managerEntity = new ManagerEntity();
            managerEntity.setManagerName("test");

            managerEntity.setDepartmentEntity(departmentEntity);
            departmentEntity.setManagerEntity(managerEntity);

            session.save(departmentEntity);
            System.out.println(departmentEntity.getId());
            session.save(managerEntity);

查询+更新操作:

            // 查询,延迟加载
            DepartmentEntity departmentEntity = session.get(DepartmentEntity.class, 1);
            System.out.println(departmentEntity.getManagerEntity().getManagerName());
            ManagerEntity managerEntity = session.get(ManagerEntity.class, 1);
            System.out.println(managerEntity.getDepartmentEntity().getDepartmentName());
            managerEntity.setManagerName("whf");
            departmentEntity.setDepartmentName("jd");

基于主键的1对1映射关系

两个表的主键完全相同,只需要one-to-one标签

    <!-- 存在外键 DepartmentEntity.id = ManagerEntity.id -->
    <class name="DepartmentEntity" table="department" schema="test">
        <id name="id" column="id">
            <!--参考managerEntity的主键id-->
            <generator class="foreign">
                <param name="property">managerEntity</param>
            </generator>
        </id>
        <property name="departmentName" column="departmentName"/>

        <!--
            不生成额外字段
            生成外键:ManagerEntity.id = DepartmentEntity.id
            DepartmentEntity的主键id参考ManagerEntity的主键id
        -->
        <one-to-one name="managerEntity" class="ManagerEntity" constrained="true"/>
    </class>

    <!--不存在外键,主键id被DepartmentEntity.id参考-->
    <class name="ManagerEntity" table="manager" schema="test">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="managerName" column="managerName"/>

        <!--
            不生成额外字段和外键
            ManagerEntity的主键id参考DepartmentEntity的主键id
            不指定property-ref,默认参照departmentEntity.id
            ManagerEntity.id = DepartmentEntity.id
        -->
        <one-to-one name="departmentEntity" class="DepartmentEntity"/>
    </class>

单向n对n关系映射

    <class name="CatagoryEntity" table="catagory" schema="test">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="catagoryName" column="catagoryName"/>

        <set name="items" table="catagoryitem">
            <!--CatagoryEntity参考中间表catagoryitem的cataId字段-->
            <key column="cataId"/>
            <!--ItemEntity参考中间表catagoryitem的itemId字段 -->
            <many-to-many class="ItemEntity" column="itemId"/>
        </set>
    </class>

    public class CatagoryEntity {
        private int id;
        private String catagoryName;
        private Set<ItemEntity> items = new HashSet<>();
        ...
    }
    <class name="n2n.ItemEntity" table="item" schema="test">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="itemName" column="itemName"/>
    </class>

    public class ItemEntity {
        private int id;
        private String itemName;
        ...
    }

插入操作:

            CatagoryEntity catagoryEntity1 = new CatagoryEntity();
            catagoryEntity1.setCatagoryName("cataName1");

            CatagoryEntity catagoryEntity2 = new CatagoryEntity();
            catagoryEntity2.setCatagoryName("cataName2");

            ItemEntity itemEntity1 = new ItemEntity();
            itemEntity1.setItemName("itemName1");

            ItemEntity itemEntity2 = new ItemEntity();
            itemEntity2.setItemName("itemName2");

            catagoryEntity1.getItems().add(itemEntity1);
            catagoryEntity1.getItems().add(itemEntity2);

            catagoryEntity2.getItems().add(itemEntity1);
            catagoryEntity2.getItems().add(itemEntity2);

            session.save(catagoryEntity1);
            session.save(catagoryEntity2);
            session.save(itemEntity1);
            session.save(itemEntity2);

双向n对n关系映射

    <class name="ItemEntity" table="item" schema="test">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="itemName" column="itemName"/>

        <!--两端必须有一端使用inverse="true",否则关系维护失败:主键重复-->
        <set name="catagorys" table="catagoryitem" inverse="true">
            <key column="itemId"/>
            <many-to-many class="CatagoryEntity" column="cataId"/>
        </set>
    </class>

    <class name="CatagoryEntity" table="catagory" schema="test">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="catagoryName" column="catagoryName"/>

        <set name="items" table="catagoryitem">
            <!--CatagoryEntity参考中间表catagoryitem的cataId字段-->
            <key column="cataId"/>
            <!--ItemEntity参考中间表catagoryitem的itemId字段 -->
            <many-to-many class="ItemEntity" column="itemId"/>
        </set>
    </class>

Subclass继承关系映射

父类与子类共用一张表

    <!--PeopleEntity设定辨别列的值为people-->
    <class name="PeopleEntity" table="people" schema="test"
           discriminator-value="people">
        <id name="id" column="id">
            <generator class="native"/>
        </id>

        <!--数据表的type字段为辨别列-->
        <discriminator column="type"/>

        <property name="peopleName" column="peopleName"/>

        <!--StudentEntity设定辨别列的值为student,使用hql的表名为StudentEntity-->
        <subclass name="StudentEntity" discriminator-value="student">
            <!--className不能选定非空-->
            <property name="className" column="className"/>
        </subclass>
    </class>

    public class PeopleEntity {
        public int id;
        public String type;
        public String peopleName;
        ...
    }

    public class StudentEntity extends PeopleEntity {
        public String className;
        ...
    }

查询操作:

            // 类型不匹配 -> 返回null
            StudentEntity studentEntity = session.get(StudentEntity.class, 3);
            System.out.println(studentEntity.getClassName());

            List<StudentEntity> studentEntityList = session.createQuery("from StudentEntity").list();
            System.out.println(studentEntityList.size());

joined-subclass继承关系映射

joined-subclass标签,提供的功能是只能为子类设定外部表,而且没有鉴别器,即子类一张表,父类一张表,子类以父类的主键为外键。父类对应的表中,没有判断类型的列。

    <class name="PeopleEntity" table="people" schema="test">
        <id name="id" column="id">
            <generator class="native"/>
        </id>

        <property name="peopleName" column="peopleName"/>

        <!--创建student表额外存储student类的属性-->
        <joined-subclass name="StudentEntity" table="student">
            <!--PeopleEntity.id参照student表的student_id属性-->
            <key column="student_id"/>
            <property name="className" column="className"/>
        </joined-subclass>
    </class>

union-subclass继承关系参考

union-subclass是将父类中的属性,添加到子类对应的表中去了。包括父类中的外键。union-class和前两个的区别就在于外键的不同,前两个标签,如果子类有单独对应的表的话,这个表的外键是其父类中的主键,而使用union-class,子类对应的表中的外键则和父类的外键是一样的,因为子类把父类继承的属性,也加到了自己的表当中。这样子类和父类的地位就相当了。

    <class name="PeopleEntity" table="PEOPLE" schema="test">
        <id name="id" column="id"/>

        <property name="peopleName" column="peopleName"/>

        <!--创建student表额外存储student类的属性-->
        <union-subclass name="StudentEntity" table="STUDENTS">
            <property name="className" column="className"/>
        </union-subclass>
    </class>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值