hibernate查漏补缺1

转载请注明: TheViper http://www.cnblogs.com/TheViper

SessionFactory接口

一个SessionFactory接口对应一个数据存储源。特点:

1.线程安全。即它的同一个实例可以被应用的多个线程共享。

2.重量级。创建和销毁它的实例所花费的代价很大,所以应用的一个数据库对应一个SessionFactory实例,在初始化时创建。

Session接口

持久化管理器,复杂和持久化的相关操作。特点:

1.不是线程安全。2.实例是轻量级的。

Hibernate的映射类型

有一点说明下,如果需要存储的字符串比较多,而且字符串长度也不好掌握,数据库就不好用varchar.这时可以像这样.

        <property name="content">
            <column name="content" sql-type="mediumtext" />
        </property>

pojo那边的content类型设置成String.可以看到上面表里面sql字段类型没有mediumtext.这样做就可以让java String数据库直接映射成medirmtext了。我用的是mysql,不知道其他数据库是不是这样的。

映射主键

1.单个主键

        <id name="feeling_id" type="java.lang.Integer">
            <column name="feeling_id " length="20" />
            <generator class="native" />
        </id>

2.复合主键

(1)与其他表无关联

比如:名字(name),好友名字(friend_name),好友分类(sort),name和friend_name组成复合主键user_friend_pk。

对user_friend_pk,单独创建一个User_Friend_pk类,继承Serializable接口,并重写hashCode(),equals(Object obj)方法。

对pojo User_Friend类,对User_Friend_pk setter,getter即可。

映射文件:

<?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="cls.User_Friend" table="user_friends">
        <composite-id name="user_friend_pk" class="cls.User_Friend_pk">
            <key-property name="name" column="name" type="java.lang.String"
                length="20"></key-property>
            <key-property name="friend_name" column="friend_name"
                type="java.lang.String" length="20"></key-property>
        </composite-id>
        <property name="sort" type="java.lang.String">
            <column name="sort" length="20" />
        </property>
    </class>
</hibernate-mapping>

(2)与其他表有关联

比如:User表(id,name)   User_Friend表和上面一样,只不过把name和friend_name换成id和friend_id,这就形成了关联。

这和上面的区别在于映射文件。

<?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="model.cls.User_Friend" table="user_friends">
        <composite-id name="user_friend_pk" class="model.cls.User_Friend_pk">
            <key-many-to-one name="ids" class="model.cls.User">
                <column name="id"></column>
            </key-many-to-one>
            <key-many-to-one name="friend_ids" class="model.cls.User">
                <column name="friend_id"></column>
            </key-many-to-one>
        </composite-id>
        <property name="sort" type="java.lang.String">
            <column name="sort" length="20" />
        </property>
    </class>
</hibernate-mapping>

下面来个复杂点的。

student表,班级(classId),学号(studentId).这两个可以确定一个学生,构成复合主键。

course表,课程id(courseId),课程名(courseName).

很显然,这两个是多对多的关系。我们用<many-to-many>构建单向的多对多映射。当然也可以用两个一对多关系来构建。

映射文件student.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="cls.Student" table="student">
        <composite-id name="studentPk" class="cls.StudentPk">
            <key-property name="studentId" column="studentId"
                type="java.lang.Integer"></key-property>
            <key-property name="classId" column="classId" type="java.lang.Integer"></key-property>
        </composite-id>
    </class>
</hibernate-mapping>

course.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="cls.Course" table="course">
        <id name="courseId" type="java.lang.Integer">
            <column name="courseId " length="20" />
            <generator class="native" />
        </id>
        <property name="courseName" type="java.lang.String">
            <column name="courseName" length="20" />
        </property>
        <set name="StudentCourse" table=‘StudentCourse‘>
            <key column="courseId" />
            <many-to-many class="cls.Student">
                <column name="studentId"></column>
                <column name="classId"></column>
            </many-to-many>
        </set>
    </class>
</hibernate-mapping>

关于<set>上的inverse属性

作用:决定是由谁来维护表和表之间的关系的。这里有个前提,这两个表之间必须是双向关联,道理很简单,比如一对多关系,在“一”那边设置了“一对多” inverse=true,让“多”那边来维护,但没有设置“多“那边的集合或类对象的映射,让”多“那边怎么去维护。

比如上面复合主键的第二个例子,我把sort(分类)变成一个friend_category_id,另外建个表friend_category。

映射文件Friend_category.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="cls.Friend_Category" table="friend_category">
        <id name="friend_category_id" type="java.lang.Integer">
            <column name="friend_category_id " length="20" />
            <generator class="native" />
        </id>
        <property name="category_name" type="java.lang.String">
            <column name="category_name" length="20" />
        </property>
        <set name="user_friends" inverse="true">
            <key column="friend_category_id" />
            <one-to-many class="cls.User_Friend" />
        </set>
    </class>
</hibernate-mapping>

User_friend.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="cls.User_Friend" table="user_friends">
        <composite-id name="user_friend_pk" class="cls.User_Friend_pk">
            <key-property name="name" column="name" type="java.lang.String"
                length="20"></key-property>
            <key-property name="friend_name" column="friend_name"
                type="java.lang.String" length="20"></key-property>
        </composite-id>
<!--         <many-to-one name="friend_categorys" column="friend_category_id" -->
<!--             class="cls.Friend_Category"> -->
<!--         </many-to-one> -->
        <!-- <property name="sort" type="java.lang.String"> -->
        <!-- <column name="sort" length="20" /> -->
        <!-- </property> -->
    </class>
</hibernate-mapping>

为两表插入数据

        Friend_Category fc = new Friend_Category();
        fc.setCategory_name("好基友");
        User_Friend_pk pk = new User_Friend_pk();
        pk.setFriend_name("daut");
        pk.setName("TheViper");
        User_Friend uf = new User_Friend();
        uf.setUser_friend_pk(pk);
        uf.setFriend_categorys(fc);

        // uf.setSort("好基友");
        session.save(fc);
        session.save(uf);
Hibernate:
    insert
    into
        friend_category
        (category_name)
    values
        (?)
Hibernate:
    insert
    into
        user_friends
        (name, friend_name)
    values
        (?, ?)

可以看到在user_friends表中并没有插入friend_category_id字段。

还有一点,既然是双向关联了,上面插入数据的代码我也完全可以这样写。

         Friend_Category fc = new Friend_Category();
         fc.setCategory_name("好基友");
         User_Friend_pk pk = new User_Friend_pk();
         pk.setFriend_name("daut");
         pk.setName("TheViper");
         User_Friend uf = new User_Friend();
         uf.setUser_friend_pk(pk);
         Set user_friends = new HashSet();
         user_friends.add(uf);
         fc.setUser_friends(user_friends);
         session.save(fc);
        session.save(uf);
Hibernate:
    insert
    into
        friend_category
        (category_name)
    values
        (?)
Hibernate:
    insert
    into
        user_friends
        (friend_category_id, name, friend_name)
    values
        (?, ?, ?)

可以看到,这次user_friends表总算插入了friend_category_id字段,但是一看数据,friend_category_id字段居然木有数据。

因为你已经inverse=true了,两表关系就由user_friends(User_Friend类)来维护了,但是上面的代码却是通过Friend_Category的setUser_friends()添加关联。这时应该是User_Friend的setFriend_categorys()才对。

时间: 2024-10-26 19:37:40

hibernate查漏补缺1的相关文章

hibernate查漏补缺2

Hibernate对象状态 瞬时(transient):由new操作符创建,且尚未Hibernate Session关联.瞬时对象不会被持久化到数据库,也不会被赋予持久化标识. 持久(persistent):持久化的实例在数据库中有对应的记录,并拥有一个持久化标识. 持久化的实例可能是刚被保存,或刚被加载的,无论哪一种,它都只存在于相关联的Session作用范围内.这点很重要.Hibernate会检测处于持久化状态的对象的任何变动,在当前操作单元执行完毕时,将对对象数据与数据库同步. 脱管(de

近来的java小总结(2.1):类的知识的查漏补缺

首先,我是一名新手,所以,要带着批判的眼光来看下面的文章   这篇文章说了些什么? 这文章是我近来8.6号来在编程思想上打的代码,从0~200页的源码接近到在这里,下文正是总结这0~200页的的知识,涉及到接口,内部类.初始化,数值计算的一些细节.此文章不会一下子写完,可能隔一天可能再补下来.因为代码确实有点多.. 注意 1 我的注释不一定正确(不过各小标题和代码一定是正确的,因为是书本上的原话,但是注释不一定正确),如果你确信我的内容的话,你可能会损失很大,因为我只是个菜鸟,我只是来补救一些知

查漏补缺——java多态

---恢复内容开始--- 刚学完java,开始了查漏补缺阶段阶段,为了巩固自己的知识和为别人提供一些微末的帮助决定开通博客,求各位大牛们指出我的不足,不要吝惜言语,也希望我的总结可以对别人有帮助,对自己对他人负责. 开始正文:术语多态:可以定义为“有多种形态”,多态引用是一个一个在不同时刻可以指向不同类型对象的引用变量.通过多态引用可以调用不同的具体的方法. 类方法的多态性的实现有两种方式: 1:方法重载:可以声明多个同名但是参数不同(个数.类型和顺序)的方法.注意呵呵重载方法只能声明在一个类里

近来的java小总结(2.2):类的知识的查漏补缺

1 首先,我是一名新手,所以,要带着批判的眼光来看下面的文章   这篇文章说了些什么? 这文章是我近来8.6号来在编程思想上打的代码,从0~200页的源码接近到在这里,下文正是总结这0~200页的的知识,涉及到接口,内部类.初始化,数值计算的一些细节.此文章不会一下子写完,可能隔一天可能再补下来.因为代码确实有点多.. 注意 1 我的注释不一定正确(不过各小标题和代码一定是正确的,因为是书本上的原话,但是注释不一定正确),如果你确信我的内容的话,你可能会损失很大,因为我只是个菜鸟,我只是来补救一

java知识查漏补缺

一.重写(override)和重载(overload)的区别 二者除了名字相似,其实没什么联系 范围不同:重写发生在同一个类的不同方法之间.重载发生在父类和子类自荐. 前提: 重写要求:方法名相同,参数列表不同,对于返回值类型不要求相同. 重载要求:方法名形同,参数列表也相同.重载是实现多态的关键,注意如果父类中的方法是private类型,那么子类中对应方法不算重载,而相当于是定义了一个新方法. 二.final的用法 修饰类:该类不能被继承 修饰方法:该方法不能被重写 修饰属性:该属性初始化后不

自家用的java小总结(2.4):类的知识的查漏补缺(内部类)

1 2      首先,这是一篇自己用的文章,不对读者承担任何责任,所以,要带着批判的眼光来看下面的文章   1 发现了,得加上输出结果,怕自己出错,~~   这篇文章说了些什么? 这文章是我近来8.6号来在编程思想上打的代码,从0~200页的源码接近到在这里,下文正是总结这0~200页的的知识,涉及到接口,内部类.初始化,数值计算的一些细节.此文章不会一下子写完,可能隔一天可能再补下来.因为代码确实有点多.. 注意 1 我的注释不一定正确(不过各小标题和代码一定是正确的,因为是书本上的原话,但

查漏补缺

查漏补缺[1].this语句:this语句用于构造函数之间进行相互调用.this语句只能定义在构造函数的第一行,因为初始化要先执行.[2].对象的初始化过程 Person p =new Person("hei",10); 1.因为new用到了Person.class,所以先找到Person.class文件加载到内存中 2.执行类中的静态代码块,如果有的话,给Person.class类进行初始化 3.在堆内存中开辟空间,分配内存地址 4.在堆内存中建立对象的特有属性,并进行默认初始化 5

《CSS权威指南》基础复习+查漏补缺

前几天被朋友问到几个CSS问题,讲道理么,接触CSS是从大一开始的,也算有3年半了,总是觉得自己对css算是熟悉的了.然而还是被几个问题弄的"一脸懵逼"... 然后又是刚入职新公司,事情不算多,于是拿起<CSS权威指南>进行"基础学习"+"查漏补缺",本篇文章主要是总结了些自己认为CSS中值的注意的几个知识点(本文知识点仅限本书范围内,若要讲CSS全部样式,那本兽还是选择慢慢懵逼去~). 选择器 这里要说明的是类选择器的嵌套选择与多类

今天开始慢下脚步,开始ios技术知识的查漏补缺。

从2014.6.30 开始工作算起.现在已经是第416天了.不止不觉,时间过的真快. 通过对之前工作的总结,发现,你的知识面,会决定你面对问题时的态度.过程和结果. 简单来讲,知识面拓展了,你才能有更多的备选方法,才更有可能选择到一条最最有效的路. 趁现在正好有时间,时机又正好,开始我的技术总结补缺之路吧. 参考教材<疯狂iOS讲义>.主要原因是,知识比较全面,涉及面比较广.适合查漏补缺. 开始吧.看我能坚持多久. 版权声明:本文为博主原创文章,未经博主允许不得转载.