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()才对。

     

  • 相关阅读:
    如何修改MySQL的默认安装路径
    给WordPress分类目录和页面添加斜杠
    制作macOS Sierra 正式版USB安装盘的方法
    Companion.JS 与 Microsoft Script Debugger 结合IE javaScript 调试工具
    启动Weblogic报出java.lang.OutOfMemoryError: PermGen space异常
    Spring中@Autowired注解、@Resource注解的区别
    webligc VALIDATION PROBLEMS WERE FOUND problem错误
    解决visio在win7下意外退出问题
    myeclipse 9.0 配svn 报 Failed to load JavaHL Library 解决方法
    powerDesigner 15 unable to list the users 解决方法
  • 原文地址:https://www.cnblogs.com/TheViper/p/4096301.html
Copyright © 2011-2022 走看看