read-Atleap-11-主业务分析-NewsItem类-Hibernate继承关系实施案例

v 新闻主业务

Ø 数据结构描述

ª 通过继承PageLocalizableNewsItem完成新闻实体

    ª 通过继承、映射和引用NewsItem并不真正的保存新闻信息

    ª ContentFieldVale保存真正的新闻内容,包括标题、注释和内容体等

    ª ContentField保存布局信息,和ContentFieldVale形成引用关系,完成显示布局和内

    容的分离

Ø新闻实体类图

Ø基类Localizable分析(总览)

ª LocalizablePage类的父类

ª Page类是NewsItem类的父类

ª NewsItem类知实现了很少的属性,大部分属性都使用继承自父类的属性。

ª 在这里采用了hibernate的第3种继承策略,即父类与子类每个类对应一个表格,父类别映

像的表格与子类别映像的表格共享相同的主键值,父类别表格只记录本身的属性,如果要

查询的是子类别,则透过外键参考从父类别表格中取得继承而来的属性数据。

Ø代码实现

    ª Localizable.hbm.xml中的设置

    ª 注意:其中子类的设置是嵌套在父类的设置中的

    ª 采用这样的策略后,Page类和NewsItem类是不会产生单独的映射配置文件的

    ª key>卷标指定子类别表格与父类别表格共享的主键值

            <joined-subclass

            name="com.blandware.atleap.model.core.Page"

            table="page"

            dynamic-update="false"

            dynamic-insert="false"

            lazy="false"

        >

        <key

            column="localizable_id"

        />

        <property

            name="uri"

            type="java.lang.String"

            update="true"

            insert="true"

            access="property"

        >

            <column

                name="uri"

                not-null="false"

                unique="true"

            />

        </property>

        <property

            name="usageCounter"

            type="java.lang.Integer"

            update="true"

            insert="true"

            access="property"

            column="usage_counter"

            not-null="false"

        />

        <property

            name="active"

            type="true_false"

            update="true"

            insert="true"

            access="property"

            column="active"

            not-null="true"

        />

        <bag

            name="linkedContentFieldValues"

            table="field_value_page"

            lazy="true"

            inverse="false"

            cascade="none"

        >

              <key

                  column="page_id"

              >

              </key>

              <many-to-many

                  class="com.blandware.atleap.model.core.ContentFieldValue"

                  column="field_value_id"

                  outer-join="auto"

               />

        </bag>

        <joined-subclass

            name="com.blandware.atleap.model.news.NewsItem"

            table="news_item"

            dynamic-update="false"

            dynamic-insert="false"

            lazy="false"

        >

        <key

            column="page_id"

        />

        <property

            name="publicationDate"

            type="date"

            update="true"

            insert="true"

            access="property"

            column="publication_date"

            not-null="false"

        />

        </joined-subclass>

        </joined-subclass>

    ª Localizable.java中的代码

        继承关系中父类中不需要代码

    ª Page.java中的代码

        /**

*@hibernate.joined-subclass table="page" lazy="false"

*@hibernate.joined-subclass-key column="localizable_id"

        */

    ª NewsItem中的代码

    /**

        * @hibernate.joined-subclass table="news_item" lazy="false"

 * @hibernate.joined-subclass-key column="page_id"

 */

注:引用

引用地址:http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=833

ª hibernate 继承描述

如果应用程序中的对象有继承的关系,我们可以有三种策略将这种关系映像至数据表上。

I)            最简单的方式就是给每个对象一个表格,如果父类别User中有field1field2两个属性,其表格USERFIELD1FIELD2与之对应,而子类别SubUser若继承了父类别的field1field2属性,表格中SUBUSER中也要拥有FIELD1FIELD2与之对应,这种方法的好处只有映射上的方便,很显然的,父类与子类共有的属性,会变成在数据库表格中重复的字段,而且很难实现多型操作,建议只有在不需要多型操作时使用,要执行这种映射,为每一个子类别撰写一个映射文件就是了,没什么特别的设定。

II)         性, 第二种方式是将所有继承同一父类别的对象储存在同一个表格中,表格中使用识别字段来表示某一列(row)是属于某个子类别或父类别,这种方式方便执行多型操作,而且兼具效能上的考虑。

例:

<hibernate-mapping>

    <class name="onlyfun.caterpillar.User" table="USER" discriminator-value="ParentUser">

        <id name="id" type="string" unsaved-value="null">

            <column name="ID" sql-type="char(32)"/>

            <generator class="uuid.hex"/>

        </id>

        <discriminator column="DISCRIMINATOR_USERTYPE" type="string"/>

        <property name="name" type="string" not-null="true">

            <column name="NAME" length="16" not-null="true"/>

        </property>

        <property name="password" type="string" not-null="true">

            <column name="PASSWORD" length="16" not-null="true"/>

        </property>

        <subclass name="onlyfun.caterpillar.PowerUser"

                discriminator-value="POWER">

            <property name="level" type="integer" column="POWERUSER_LEVEL"/>

            <property name="otherOfPower" type="string" column="POWER_OTHER"/>

        </subclass>

        <subclass name="onlyfun.caterpillar.GuestUser"

            discriminator-value="GUEST">

            <property name="otherOfGuest" type="string" column="GUEST_OTHER"/>

        </subclass>

    </class>

</hibernate-mapping>

III)      继承关系映像的第三种方式,我们给予父类别与每个子类别一个表格,与第一个方法不同的是,父类别映像的表格与子类别映像的表格共享相同的主键值父类别表格只记录本身的属性,如果要查询的是子类别,则透过外键参考从父类别表格中取得继承而来的属性数据。

您好,关于将Scrapy-Redis分布式爬虫爬取的数据写入MySQL数据库,您可以按照以下步骤操作: 1. 在pip中安装PyMySQL库:pip install pymysql 2. 在Scrapy项目的settings.py文件中添加数据库配置信息: ``` MYSQL_HOST = 'localhost' # 你的mysql地址 MYSQL_DBNAME = 'test' # 数据库名字,请修改 MYSQL_USER = 'root' # 数据库账号,请修改 MYSQL_PASSWORD = '123456' # 数据库密码,请修改 MYSQL_PORT = 3306 # 数据库端口号 ``` 3. 在items.py文件中定义需要存储的字段,例如: ``` import scrapy class NewsItem(scrapy.Item): title = scrapy.Field() url = scrapy.Field() date = scrapy.Field() ``` 4. 在pipelines.py文件中编写MySQL存储Pipeline: ``` import pymysql class MySQLPipeline(object): def __init__(self, mysql_host, mysql_port, mysql_user, mysql_password, mysql_dbname): self.host = mysql_host self.port = mysql_port self.user = mysql_user self.password = mysql_password self.dbname = mysql_dbname @classmethod def from_crawler(cls, crawler): return cls( mysql_host=crawler.settings.get('MYSQL_HOST'), mysql_port=crawler.settings.get('MYSQL_PORT'), mysql_user=crawler.settings.get('MYSQL_USER'), mysql_password=crawler.settings.get('MYSQL_PASSWORD'), mysql_dbname=crawler.settings.get('MYSQL_DBNAME') ) def open_spider(self, spider): self.db = pymysql.connect( host=self.host, port=self.port, user=self.user, password=self.password, db=self.dbname ) self.cursor = self.db.cursor() def close_spider(self, spider): self.db.close() def process_item(self, item, spider): data = dict(item) keys = ', '.join(data.keys()) values = ', '.join(['%s'] * len(data)) table = 'news' # 数据库表名,请修改 sql = f'INSERT INTO {table} ({keys}) VALUES ({values})' self.cursor.execute(sql, tuple(data.values())) self.db.commit() return item ``` 4. 在settings.py文件中启用Pipeline: ``` ITEM_PIPELINES = { 'myproject.pipelines.MySQLPipeline': 300 } ``` 这样,当Scrapy爬取到数据时,就会通过MySQLPipeline将数据写入MySQL数据库中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值