Hibernate容器映射技术

这篇博客详细介绍了Hibernate中List、Map、Array和Bag四种集合类型的映射技术。通过示例展示了如何在数据库脚本、Java类和Hibernate映射文件中进行配置,并分析了它们在数据保存和查询时的特点,强调了Set适用于唯一字段,List适合有索引的重复数据,Map包含key-value对,而Array和Bag则提供了不同场景下的映射选择。
摘要由CSDN通过智能技术生成

11.2、List映射

对于Collection子接口有两个常用的:无重复的set子接口、允许重复的List子接口,而且在List接口中大量的扩充了Collection接口里面的方法,而且List接口有一个get()方法,此方法可以根据索引取数据,所以List集合本身就具备了索引的能力。而马上要讲解的List映射也会包含索引与数据两个部分。

范例:数据库创建脚本

- 使用数据库

USE mldn ;

-- 删除数据表

DROP TABLE books ;

DROP TABLE member ;

-- 创建数据表

CREATE TABLE member(

    mid         VARCHAR(50) ,

    name        VARCHAR(50) ,

    CONSTRAINT pk_mid PRIMARY KEY(mid)

) ;

CREATE TABLE books(

    mid         VARCHAR(50) ,

    position    INT ,

    title       VARCHAR(200) ,

    CONSTRAINT fk_mid FOREIGN KEY(mid) REFERENCES member(mid) ON DELETE CASCADE

) ;

其中在Books表中定义的position字段,就表示一个数据的访问索引。下面就根据以上的脚本加入Hibernate支持。

范例:修改Member.java类的定义

package cn.cgj.pojo;

import java.util.List;

@SuppressWarnings("serial")

public class Member implements java.io.Serializable {

    private String mid;

    private String name;

    private List books = new ArrayList();

    public Member() {

    }

    //settergetter

}

下面的关键还是在于Member.hbm.xml文件的修改上。

范例:修改Member.hbm.xml文件,加上List支持

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    <class name="cn.cgj.pojo.Member" table="member" catalog="mldn">

        <id name="mid" type="java.lang.String">

            <column name="mid" length="50" />

            <generator class="assigned"></generator>

        </id>

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

            <column name="name" length="50" />

        </property>

        <list name="books" table="books" lazy="false">

            <key>

                <column name="mid"/>

            </key>

            <index column="position"/>

            <element column="title" type="java.lang.String"/>

        </list>

    </class>

</hibernate-mapping>

范例:实现数据的增加操作

package cn.cgj.pojo;

import cn.cgj.dbc.HibernateSessionFactory;

public class MemberTestInsert {

    public static void main(String[] args) {

        Member mem = new Member();

        mem.setMid("daguo" + System.currentTimeMillis());

        mem.setName("大国");

        mem.getBooks().add("java核心技术");

        mem.getBooks().add("java核心技术");

        mem.getBooks().add("java核心技术");

        mem.getBooks().add("java开发实战经典");

        mem.getBooks().add("java开发实战经典");

        mem.getBooks().add("java开发实战经典");

        mem.getBooks().add("java开发实战经典");

        HibernateSessionFactory.getSession().save(mem);

        HibernateSessionFactory.getSession().beginTransaction().commit();

        HibernateSessionFactory.closeSession();

    }

}

Hibernate:

    insert

    into

        mldn.member

        (name, mid)

    values

        (?, ?)

Hibernate:

    insert

    into

        books

        (mid, position, title)

    values

        (?, ?, ?)

Hibernate:

    insert

    into

        books

        (mid, position, title)

    values

        (?, ?, ?)

Hibernate:

    insert

    into

        books

        (mid, position, title)

    values

        (?, ?, ?)

Hibernate:

    insert

    into

        books

        (mid, position, title)

    values

        (?, ?, ?)

Hibernate:

    insert

    into

        books

        (mid, position, title)

    values

        (?, ?, ?)

Hibernate:

    insert

    into

        books

        (mid, position, title)

    values

        (?, ?, ?)

Hibernate:

    insert

    into

        books

        (mid, position, title)

    values

        (?, ?, ?)

      现在同样实现了两张表的增加操作。而后在books表中可以发现position列的内容会自动的进行增长。

范例:实现数据的查询

package cn.cgj.pojo;

import cn.cgj.dbc.HibernateSessionFactory;

public class MemberTestSelectById {

    public static void main(String[] args) {

        Member mem = (Member) HibernateSessionFactory.getSession().get(Member.class, "daguo1456907570242");

        System.out.println(mem);

        HibernateSessionFactory.closeSession();

    }

}

Hibernate:

    select

        member0_.mid as mid0_0_,

        member0_.name as name0_0_

    from

        mldn.member member0_

    where

        member0_.mid=?

Hibernate:

    select

        books0_.mid as mid0_0_,

        books0_.title as title0_,

        books0_.position as position0_

    from

        books books0_

    where

        books0_.mid=?

Member [mid=daguo1456907570242, name=大国, books=[java核心技术, java核心技术, java核心技术, java开发实战经典, java开发实战经典, java开发实战经典, java开发实战经典]]

      操作的形式上和set集合的区别不大,但是在数据的保存上还是存在一些细微的区别的,而对应的其他操作与set集合的操作类似。

11.3、Map映射

Map集合最大的特征就是存在key与value的对应关系,所以在进行数据保存的时候,子表之中也一定会存在两个字段,一个是key,一个是value。

范例:数据库创建脚本

-- 使用数据库

USE mldn ;

-- 删除数据表

DROP TABLE grade ;

DROP TABLE sporter ;

-- 创建数据表

CREATE TABLE sporter(

    sid         VARCHAR(50) ,

    name        VARCHAR(50) ,

    sex         VARCHAR(10) ,

    CONSTRAINT pk_sid PRIMARY KEY(sid)

) ;

CREATE TABLE grade(

    sid         VARCHAR(50) ,

    item        VARCHAR(50) ,

    mark        INT ,

    CONSTRAINT fk_sid FOREIGN KEY(sid) REFERENCES sporter(sid) ON DELETE CASCADE

) ;

      很明显,现在每一个项目都应该对应一个运动员的成绩,而且此处也不考虑项目的名称是否重复。之后创建Hibernate映射。

范例:修改sporter.java类

package cn.cgj.pojo;

import java.util.HashMap;

import java.util.Map;

@SuppressWarnings("serial")

public class Sporter implements java.io.Serializable {

 

    private String sid;

    private String name;

    private String sex;

    private Map  grades = new HashMap();

    public Sporter() {

    }

    //settergetter

}

范例:修改sporter.hbm.xml文件

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    <class name="cn.cgj.pojo.Sporter" table="sporter" catalog="mldn">

        <id name="sid" type="java.lang.String">

            <column name="sid" length="50" />

            <generator class="assigned"></generator>

        </id>

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

            <column name="name" length="50" />

        </property>

        <property name="sex" type="java.lang.String">

            <column name="sex" length="10" />

        </property>

         <map name="grades" table="grade" lazy="false">

             <key>

                 <column name="sid"/>

             </key>

             <map-key type="java.lang.String" column="item"/>

             <element type="int" column="mark"/>

         </map>

    </class>

</hibernate-mapping>

 

范例:测试增加

package cn.cgj.test;

import cn.cgj.dbc.HibernateSessionFactory;

import cn.cgj.pojo.Sporter;

public class SporterTestInsert {

    public static void main(String[] args) {

        Sporter sporter = new Sporter();

        sporter.setSid("daguo");

        sporter.setName("大国");

        sporter.setSex("");

        sporter.getGrades().put("跳高", 11);

        sporter.getGrades().put("跳水", 1);

        sporter.getGrades().put("跳远", 21);

        HibernateSessionFactory.getSession().save(sporter);

        HibernateSessionFactory.getSession().beginTransaction().commit();

        HibernateSessionFactory.closeSession();

    }

}

Hibernate:

    insert

    into

        mldn.sporter

        (name, sex, sid)

    values

        (?, ?, ?)

Hibernate:

    insert

    into

        grade

        (sid, item, mark)

    values

        (?, ?, ?)

Hibernate:

    insert

    into

        grade

        (sid, item, mark)

    values

        (?, ?, ?)

Hibernate:

    insert

    into

        grade

        (sid, item, mark)

    values

        (?, ?, ?)

范例:查询数据

package cn.cgj.test;

import cn.cgj.dbc.HibernateSessionFactory;

import cn.cgj.pojo.Sporter;

public class SporterTestSelectById {

    public static void main(String[] args) {

        Sporter sporter = (Sporter) HibernateSessionFactory.getSession().get(Sporter.class, "daguo");

        System.out.println(sporter);

        HibernateSessionFactory.closeSession();

    }

}

Hibernate:

    select

        sporter0_.sid as sid0_0_,

        sporter0_.name as name0_0_,

        sporter0_.sex as sex0_0_

    from

        mldn.sporter sporter0_

    where

        sporter0_.sid=?

Hibernate:

    select

        grades0_.sid as sid0_0_,

        grades0_.mark as mark0_,

        grades0_.item as item0_

    from

        grade grades0_

    where

        grades0_.sid=?

Sporter [sid=daguo, name=大国, sex=男, grades={跳远=21, 跳高=11, 跳水=1}]

此时也是发出了两条指令,这样的好处明显就避免了多表查询的性能问题,但是通过以上三种映射可以发现:

l  Set映射只适合与子表中存在有一个字段(不包含外键)的情况下使用。

l  List映射适合于子表中有一个字段(不包含外键),但是可以重复,区分是依靠索引列来完成。

l  Map映射包含两个字段(不包含外键),key和value的内容可以由用户自己设置。

11.4、Array映射

这种映射采用的是数组的方式进行的保存,数组也就相当于集合,只不过此处是直接使用的数组完成的。

范例:数据库的创建脚本

-- 使用数据库

USE mldn ;

-- 删除表

DROP TABLE message ;

DROP TABLE member ;

-- 创建表

CREATE TABLE member(

    mid         VARCHAR(50) ,

    name        VARCHAR(50) ,

    CONSTRAINT pk_mid PRIMARY KEY(mid)

) ;

CREATE TABLE message(

    mid         VARCHAR(50) ,

    ind         INT ,

    content     TEXT ,

    CONSTRAINT fk_mid FOREIGN KEY(mid) REFERENCES member(mid) ON DELETE CASCADE

) ;

      可以感觉到此时的数组的映射结构和List非常相似,一定也需要一个索引的列,随后为项目增加Hibernate支持。

范例:修改Member.java类定义

package cn.cgj.pojo;

public class Member implements java.io.Serializable {

    private String mid;

    private String name;

    private String [] messages ;

    public Member() {

    }

    //settergetter  

}

范例:修改Member.hbm.xml文件

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    <class name="cn.cgj.pojo.Member" table="member" catalog="mldn">

        <id name="mid" type="java.lang.String">

            <column name="mid" length="50" />

            <generator class="assigned"></generator>

        </id>

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

            <column name="name" length="50" />

        </property>

        <array name="messages" table="message" >

        <key>

             <column name="mid"/>

        </key>

        <list-index column="ind"/>

        <element type="java.lang.String" column="content"/>

        </array>

    </class>

</hibernate-mapping>

 

      与List映射的不同在于,List使用的是index,而数组使用的是List_index。

范例:测试增加数据

package cn.cgj.test;

import cn.cgj.dbc.HibernateSessionFactory;

import cn.cgj.pojo.Member;

public class MemberTestInsert {

    public static void main(String[] args) {

        Member member = new Member() ;

        member.setMid("mldn - " + System.currentTimeMillis());

        member.setName("李兴华");

        member.setMessages(new String[]{

                "魔乐科技软件学院在北京" ,

                "后续的图书为Java Web开发实战经典(框架篇)",

                "后续的图书为Java Web开发实战经典(前台技术篇)"

        });

        HibernateSessionFactory.getSession().save(member) ;

        HibernateSessionFactory.getSession().beginTransaction().commit();

        HibernateSessionFactory.closeSession();

    }

}

    insert

    into

        mldn.member

        (name, mid)

    values

        (?, ?)

Hibernate:

    insert

    into

        message

        (mid, ind, content)

    values

        (?, ?, ?)

Hibernate:

    insert

    into

        message

        (mid, ind, content)

    values

        (?, ?, ?)

Hibernate:

    insert

    into

        message

        (mid, ind, content)

    values

        (?, ?, ?)

这个时候的索引依然是采用自动编号的方式完成。

范例:查询数据

package cn.cgj.test;

import cn.cgj.dbc.HibernateSessionFactory;

import cn.cgj.pojo.Member;

public class MemberTestSelectById {

    public static void main(String[] args) {

        Member member = (Member) HibernateSessionFactory.getSession().get(Member.class, "mldn - 1456915152014");

        System.out.println(member);

        HibernateSessionFactory.closeSession();

    }

}

Hibernate:

    select

        member0_.mid as mid0_0_,

        member0_.name as name0_0_

    from

        mldn.member member0_

    where

        member0_.mid=?

Hibernate:

    select

        messages0_.mid as mid0_0_,

        messages0_.content as content0_,

        messages0_.ind as ind0_

    from

        message messages0_

    where

        messages0_.mid=?

Member [mid=mldn - 1456915152014, name=李兴华, messages=[魔乐科技软件学院在北京, 后续的图书为Java Web开发实战经典(框架篇), 后续的图书为Java Web开发实战经典(前台技术篇)]]

但是从使用上来讲,如果非要使用数组,还是建议换成List集合更好,因为数组最大的缺点在于长度固定。

11.5、Bag映射

Bag实际上就是一种没有索引列的List映射。简化了的映射操作。

范例:数据库创建脚本

-- 使用数据库

USE mldn ;

-- 删除数据表

DROP TABLE books ;

DROP TABLE member ;

-- 创建数据表

CREATE TABLE member(

    mid         VARCHAR(50) ,

    name        VARCHAR(50) ,

    CONSTRAINT pk_mid PRIMARY KEY(mid)

) ;

CREATE TABLE books(

    mid         VARCHAR(50) ,

    title       VARCHAR(200) ,

    CONSTRAINT fk_mid FOREIGN KEY(mid) REFERENCES member(mid) ON DELETE CASCADE

) ;

      为项目添加Hibernate支持,同时还需要手工进行代码的修改。

范例:修改Member.java类

package cn.cgj.pojo;

import java.util.ArrayList;

import java.util.List;

public class Member implements java.io.Serializable {

    private String mid;

    private String name;

    private List bookses = new ArrayList(0);

    public Member() {

    }

    // settergetter

}

范例:编写Member.hbm.xml文件

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    <class name="cn.cgj.pojo.Member" table="member" catalog="mldn">

        <id name="mid" type="java.lang.String">

            <column name="mid" length="50" />

            <generator class="assigned"></generator>

        </id>

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

            <column name="name" length="50" />

        </property>

        <bag name="bookses" table="books" lazy="false">

        <key>

             <column name="mid"/>

        </key>

        <element type="java.lang.String" column="title"/>

        </bag>

    </class>

</hibernate-mapping>

范例:实现数据的增加操作

package cn.cgj.test;

import cn.cgj.dbc.HibernateSessionFactory;

import cn.cgj.pojo.Member;

public class MemberTestInsert {

    public static void main(String[] args) {

        Member member = new Member();

        member.setMid("daguo");

        member.setName("大国");

        member.getBookses().add("javaWeb开发");

        member.getBookses().add("javaWeb开发");

        member.getBookses().add("javaWeb开发");

        member.getBookses().add("javaweb基础");

        member.getBookses().add("javaweb基础");

        member.getBookses().add("javaweb基础");

        HibernateSessionFactory.getSession().save(member);

        HibernateSessionFactory.getSession().beginTransaction().commit();

        HibernateSessionFactory.closeSession();

       

    }

}

Hibernate:

    insert

    into

        mldn.member

        (name, mid)

    values

        (?, ?)

Hibernate:

    insert

    into

        books

        (mid, title)

    values

        (?, ?)

Hibernate:

    insert

    into

        books

        (mid, title)

    values

        (?, ?)

Hibernate:

    insert

    into

        books

        (mid, title)

    values

        (?, ?)

Hibernate:

    insert

    into

        books

        (mid, title)

    values

        (?, ?)

Hibernate:

    insert

    into

        books

        (mid, title)

    values

        (?, ?)

Hibernate:

    insert

    into

        books

        (mid, title)

    values

        (?, ?)

范例:实现数据的查询操作

package cn.cgj.test;

import cn.cgj.dbc.HibernateSessionFactory;

import cn.cgj.pojo.Member;

 

public class MemberTestSelectById {

    public static void main(String[] args) {

        Member member = (Member) HibernateSessionFactory.getSession().get(Member.class, "daguo");

        System.out.println(member);

        HibernateSessionFactory.closeSession();

       

    }

}

Hibernate:

    select

        member0_.mid as mid0_0_,

        member0_.name as name0_0_

    from

        mldn.member member0_

    where

        member0_.mid=?

Hibernate:

    select

        bookses0_.mid as mid0_0_,

        bookses0_.title as title0_

    from

        books bookses0_

    where

        bookses0_.mid=?

Member [mid=daguo, name=大国, bookses=[javaWeb开发, javaWeb开发, javaWeb开发, javaweb基础, javaweb基础, javaweb基础]]

      此时也同样发出了两个查询指令,而且现在也不需要一个索引列的标记了。

总结

1、       重点的映射在于三种:Set、List、Map三种;

在一些老的项目之中会使用Set映射来解决多对多关系表的数据维护情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值