zoukankan      html  css  js  c++  java
  • 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()才对。

     

  • 相关阅读:
    HDU 2544 最短路
    HDU 3367 Pseudoforest
    USACO 2001 OPEN
    HDU 3371 Connect the Cities
    HDU 1301 Jungle Roads
    HDU 1879 继续畅通工程
    HDU 1233 还是畅通工程
    HDU 1162 Eddy's picture
    HDU 5745 La Vie en rose
    HDU 5744 Keep On Movin
  • 原文地址:https://www.cnblogs.com/TheViper/p/4096301.html
Copyright © 2011-2022 走看看