第五章 Hibernate介绍(草稿)



Similar documents
I

目 录 一 系 统 访 问... 1 二 门 户 首 页 申 报 用 户 审 核 用 户... 2 三 系 统 登 录 用 户 名 密 码 登 录 新 用 户 注 册 用 户 登 录 已 注 册 用

修改版-操作手册.doc

《C语言基础入门》课程教学大纲

说 明 为 了 反 映 教 运 行 的 基 本 状 态, 为 校 和 院 制 定 相 关 政 策 和 进 行 教 建 设 与 改 革 提 供 据 依 据, 校 从 程 资 源 ( 开 类 别 开 量 规 模 ) 教 师 结 构 程 考 核 等 维 度, 对 2015 年 春 季 期 教 运 行 基

何 秋 琳 张 立 春 视 觉 学 习 研 究 进 展 视 觉 注 意 视 觉 感 知

目 录 关 于 图 标... 3 登 陆 主 界 面... 3 工 单 管 理... 5 工 单 列 表... 5 搜 索 工 单... 5 工 单 详 情... 6 创 建 工 单... 9 设 备 管 理 巡 检 计 划 查 询 详 情 销 售 管

<433A5C446F63756D656E E E67735C41646D696E F725CD7C0C3E65CC2DBCEC4CFB5CDB3CAB9D3C3D6B8C4CFA3A8BCF2BBAFA3A95CCAB9D3C3D6B8C4CF31302D31392E646F63>

2 熟 悉 Visual Basic 的 集 成 开 发 环 境 3 了 解 可 视 化 面 向 对 象 编 程 事 件 驱 动 交 互 式 开 发 等 基 本 概 念 4 了 解 Visual Basic 的 特 点 环 境 要 求 与 安 装 方 法 1 Visual Basic 开 发 应 用


第2章 数据类型、常量与变量

<443A5C6D B5C30312EB9A4D7F7CEC4B5B55C30322EBACFCDACCEC4B5B55C C30342EC8CBC9E7CCFC5C31332ECFEEC4BFC5E0D1B55C E30385C322EB2D9D7F7CAD6B2E12E646F63>

教师上报成绩流程图

自 服 务 按 钮 无 法 访 问 新 系 统 的 自 服 务 页 面 因 此 建 议 用 户 从 信 网 中 心 ( 主 页, 右 下 角 位 置 的 常 用 下 载, 或 校 园 网 用 户 自 服 务 ( 首 页

龚 亚 夫 在 重 新 思 考 基 础 教 育 英 语 教 学 的 理 念 一 文 中 援 引 的 观 点 认 为 当 跳 出 本 族 语 主 义 的 思 维 定 式 后 需 要 重 新 思 考 许 多 相 连 带 的 问 题 比 如 许 多 发 音 的 细 微 区 别 并 不 影 响 理 解 和

登录、注册功能的测试用例设计.doc

HSK( 一 级 ) 考 查 考 生 的 日 常 汉 语 应 用 能 力, 它 对 应 于 国 际 汉 语 能 力 标 准 一 级 欧 洲 语 言 共 同 参 考 框 架 (CEF) A1 级 通 过 HSK( 一 级 ) 的 考 生 可 以 理 解 并 使 用 一 些 非 常 简 单 的 汉 语


Microsoft Word - 第3章.doc

Cybozu Garoon 3 管理员手册

评 委 : 李 炎 斌 - 个 人 技 术 标 资 信 标 初 步 审 查 明 细 表 序 号 投 标 单 位 投 标 函 未 按 招 标 文 件 规 定 填 写 漏 填 或 内 容 填 写 错 误 的 ; 不 同 投 标 人 的 投 标 文 件 由 同 一 台 电 脑 或 同 一 家 投 标 单

国债回购交易业务指引

工 程 造 价 咨 询 企 业 管 理 系 统 操 作 手 册 目 录 1 造 价 企 业 登 录 企 业 基 本 信 息 查 看 企 业 人 员 信 息 查 看 企 业 基 本 信 息 操 作 企 业 简 介 企 业 章

世华财讯模拟操作手册

全国教师资格认定管理信息系统

4 进 入 交 互 区 设 置 的 组 件 管 理, 在 组 件 管 理 中, 教 师 可 以 选 择 课 程 空 间 中 的 所 有 组 件, 并 通 过 点 击 启 用 或 不 启 用 选 定 组 件 在 课 程 空 间 中 的 显 示 5 进 入 工 作 室 管 理 的 工 作 室 首 页,

深圳市新亚电子制程股份有限公司

Microsoft Word - 文件汇编.doc

全国艺术科学规划项目

操作手册

,,,,, :,, (.,, );, (, : ), (.., ;. &., ;.. &.., ;, ;, ),,,,,,, ( ) ( ),,,,.,,,,,, : ;, ;,.,,,,, (., : - ),,,, ( ),,,, (, : ),, :,

 编号:

第 一 部 分 MagiCAD for Revit 安 装 流 程


一 公 共 卫 生 硕 士 专 业 学 位 论 文 的 概 述 学 位 论 文 是 对 研 究 生 进 行 科 学 研 究 或 承 担 专 门 技 术 工 作 的 全 面 训 练, 是 培 养 研 究 生 创 新 能 力, 综 合 运 用 所 学 知 识 发 现 问 题, 分 析 问 题 和 解 决

18 上 报 该 学 期 新 生 数 据 至 阳 光 平 台 第 一 学 期 第 四 周 至 第 六 周 19 督 促 学 习 中 心 提 交 新 增 专 业 申 请 第 一 学 期 第 四 周 至 第 八 周 20 编 制 全 国 网 络 统 考 十 二 月 批 次 考 前 模 拟 题 第 一 学

采 取 行 动 的 机 会 90% 开 拓 成 功 的 道 路 2

评 委 : 徐 岩 宇 - 个 人 技 术 标 资 信 标 初 步 审 查 明 细 表 序 号 投 标 单 位 投 标 函 未 按 招 标 文 件 规 定 填 写 漏 填 或 内 容 填 写 错 误 的 ; 不 同 投 标 人 的 投 标 文 件 由 同 一 台 电 脑 或 同 一 家 投 标 单

马 克 思 主 义 公 正 观 的 基 本 向 度 及 方 法 论 原 则!! # #

i 1) 系 统 运 作 前 设 定 *1. [2.1 网 页 主 机 名 称 设 定 ] -- 设 定 校 务 系 统 的 主 机 IP 地 址, 以 供 其 他 个 人 电 脑 连 接 及 使 用 该 系 统 *2. [2.3.1 输 入 / 修 改 学 校 资 料 ] -- 输 入 系 统 使

火车浏览器脚本制作教程

Microsoft Word - 第7章 图表反转形态.doc

2006年顺德区高中阶段学校招生录取分数线

目 录 一 激 活 账 号... 2 二 忘 记 密 码 后 如 何 找 回 密 码?... 3 三 如 何 管 理 学 校 信 息 及 球 队 学 生 教 师 等 信 息... 6 四 如 何 发 布 本 校 校 园 文 化? 五 如 何 向 教 师 发 送 通 知? 六

全国建筑市场注册执业人员不良行为记录认定标准(试行).doc

目 录 第 一 章 博 星 卓 越 电 子 商 务 营 销 策 划 实 践 平 台 硬 件 使 用 介 绍... 3 第 二 章 博 星 卓 越 电 子 商 务 营 销 策 划 实 践 平 台 管 理 员 端 功 能 使 用 介 绍 系 统 管 理 员 登 陆 班

Template BR_Rec_2005.dot

0 年 上 半 年 评 价 与 考 核 细 则 序 号 部 门 要 素 值 考 核 内 容 考 核 方 式 考 核 标 准 考 核 ( 扣 原 因 ) 考 评 得 3 安 全 生 产 目 30 无 同 等 责 任 以 上 道 路 交 通 亡 人 事 故 无 轻 伤 责 任 事 故 无 重 大 质 量

第3章 创建数据库

<4D F736F F D D323630D6D0B9FAD3A6B6D4C6F8BAF2B1E4BBAFB5C4D5FEB2DFD3EBD0D0B6AF C4EAB6C8B1A8B8E6>

三门峡市质量技术监督局清单公示

一、资质申请

金 不 少 于 800 万 元, 净 资 产 不 少 于 960 万 元 ; (3) 近 五 年 独 立 承 担 过 单 项 合 同 额 不 少 于 1000 万 元 的 智 能 化 工 程 ( 设 计 或 施 工 或 设 计 施 工 一 体 ) 不 少 于 2 项 ; (4) 近 三 年 每 年

云信Linux SSH认证代理用户手册

定 位 和 描 述 : 程 序 设 计 / 办 公 软 件 高 级 应 用 级 考 核 内 容 包 括 计 算 机 语 言 与 基 础 程 序 设 计 能 力, 要 求 参 试 者 掌 握 一 门 计 算 机 语 言, 可 选 类 别 有 高 级 语 言 程 序 设 计 类 数 据 库 编 程 类

引言

上海证券交易所会议纪要

四川省农村义务教育学生

øÕªß∂À≤Ÿ◊˜ ÷≤·

标题

一 开 放 性 的 政 策 与 法 规 二 两 岸 共 同 的 文 化 传 承 三 两 岸 高 校 各 自 具 有 专 业 优 势 远 见 杂 志 年 月 日

( ) 信 号 与 系 统 Ⅰ 学 科 基 础 必 修 课 教 周 2016 年 06 月 13 日 (08:00-09:35) ( )

类 似 地, 又 可 定 义 变 下 限 的 定 积 分 : ( ). 与 ψ 统 称 为 变 限 积 分. f ( ) d f ( t) dt,, 注 在 变 限 积 分 (1) 与 () 中, 不 可 再 把 积 分 变 量 写 成 的 形 式 ( 例 如 ) 以 免 与 积 分 上 下 限 的

电信系教学大纲的基本规范

<4D F736F F D20B9D8D3DAB0BABBAAA3A8C9CFBAA3A3A9D7D4B6AFBBAFB9A4B3CCB9C9B7DDD3D0CFDEB9ABCBBE C4EAC4EAB6C8B9C9B6ABB4F3BBE1B7A8C2C9D2E2BCFBCAE92E646F6378>

微软用户

<4D F736F F D C3E6CFF2B6D4CFF3A3A8B5DAC8FDD5C220C0E0CCD8D0D4A3A92E646F63>

业务方案篇

乐视云视频发行平台 操作手册 V1.1

<433A5C C6B73625C B746F705CB9FABCCAD6D0D2BDD2A9D7A8D2B5B8DFBCB6BCBCCAF5D6B0B3C6C6C0C9F3C9EAC7EBD6B8C4CFA3A CDA8D3C3B0E6A3A92E646F63>

物 流 从 业 人 员 职 业 能 力 等 级 证 书 分 为 四 个 级 别, 分 别 为 初 级 助 理 级 中 级 和 高 级 ; 采 购 从 业 人 员 职 业 能 力 等 级 证 书 分 为 三 个 级 别, 分 别 为 中 级 高 级 和 注 册 级 请 各 有 关 单 位 按 照 通

随着执业中医师资格考试制度的不断完善,本着为我校中医学专业认证服务的目的,本文通过对我校中医类毕业生参加2012年和2013年的中医执业医师考试成绩及通过率、掌握率进行分析,并与全国的平均水平进行差异比较分析,以此了解我校执业中医师考试的现状,进而反映我校中医类课程总体教学水平,发现考核知识模块教学中存在的不足,反馈给相关学院和教学管理部门,以此提高教学和管理水平。

徐天宏:《基因天堂》.doc

名 称 生 命 科 学 学 院 环 境 科 学 1 生 物 学 仅 接 收 院 内 调 剂, 初 试 分 数 满 足 我 院 生 物 学 复 试 最 低 分 数 线 生 命 科 学 学 院 生 态 学 5 生 态 学 或 生 物 学 生 命 科 学 学 院

珠江钢琴股东大会

系统设计文档_样稿管理模块 V1.1_.doc

正 规 培 训 达 规 定 标 准 学 时 数, 并 取 得 结 业 证 书 二 级 可 编 程 师 ( 具 备 以 下 条 件 之 一 者 ) (1) 连 续 从 事 本 职 业 工 作 13 年 以 上 (2) 取 得 本 职 业 三 级 职 业 资 格 证 书 后, 连 续 从 事 本 职 业

( 二 ) 现 行 统 一 高 考 制 度 不 利 于 培 养 人 的 创 新 精 神,,,,,,,,,,,,, [ ],,,,,,,,,,, :, ;,,,,,,? ( 三 ) 现 行 统 一 高 考 制 度 不 利 于 全 体 学 生 都 获 得 全 面 发 展,, [ ],,,,,,,,,,,


黄 金 原 油 总 持 仓 增 长, 同 比 增 幅 分 别 为 4.2% 和 4.1% 而 铜 白 银 以 及 玉 米 则 出 现 减 持, 减 持 同 比 减 少 分 别 为 9.4%,9.4% 以 及 6.5% 大 豆, 豆 粕 结 束 连 续 4 周 总 持 仓 量 增 长, 出 现 小 幅

目 录 页 1. 欢 迎 使 用 网 上 预 约 面 谈 访 问 系 统 新 用 户 新 用 户 登 入 帐 户 程 序 启 动 网 上 预 约 面 谈 访 问 帐 户 核 对 帐 户 的 地 址 资 料


3 月 30 日 在 中 国 证 券 报 上 海 证 券 报 证 券 时 报 证 券 日 报 和 上 海 证 券 交 易 所 网 站 上 发 出 召 开 本 次 股 东 大 会 公 告, 该 公 告 中 载 明 了 召 开 股 东 大 会 的 日 期 网 络 投 票 的 方 式 时 间 以 及 审

生产支援功能 使用说明书(IP-110 篇)

¹ º ¹ º 农 业 流 动 人 口 是 指 户 口 性 质 为 农 业 户 口 在 流 入 地 城 市 工 作 生 活 居 住 一 个 月 及 以 上 的 流 动 人 口 非 农 流 动 人 口 是 指 户 口 性 质 为 非 农 户 口 在 流 入 地 城 市 工 作 生 活 居 住 一 个

证券代码: 证券简称:长城电脑 公告编号:

目 录 版 本 更 新 说 明 导 读 读 者 对 象 手 册 内 容 简 介 软 件 简 介 基 本 术 语 技 术 支 持 基 本 流 程 操 作 步 骤... 8

<4D F736F F D20BFC9B1E0B3CCD0F2BFD8D6C6CFB5CDB3C9E8BCC6CAA6B9FABCD2D6B0D2B5B1EAD7BC2E646F63>

课程类 别

2014年中央财经大学研究生招生录取工作简报

新, 各 地 各 部 门 ( 单 位 ) 各 文 化 事 业 单 位 要 高 度 重 视, 切 实 加 强 领 导, 精 心 组 织 实 施 要 根 据 事 业 单 位 岗 位 设 置 管 理 的 规 定 和 要 求, 在 深 入 调 查 研 究 广 泛 听 取 意 见 的 基 础 上, 研 究 提

关于修订《沪市股票上网发行资金申购

附 件 : 上 海 市 建 筑 施 工 企 业 施 工 现 场 项 目 管 理 机 构 关 键 岗 位 人 员 配 备 指 南 二 一 四 年 九 月 十 一 日 2

姓名

(Microsoft Word - NCRE\314\345\317\265\265\367\325\37313\324\27221\272\3051.doc)

中 国 软 科 学 年 第 期!!!

工 程 勘 察 资 质 标 准 根 据 建 设 工 程 勘 察 设 计 管 理 条 例 和 建 设 工 程 勘 察 设 计 资 质 管 理 规 定, 制 定 本 标 准 一 总 则 ( 一 ) 本 标 准 包 括 工 程 勘 察 相 应 专 业 类 型 主 要 专 业 技 术 人 员 配 备 技 术

公 开 刊 物 须 有 国 内 统 一 刊 (CN), 发 表 文 章 的 刊 物 需 要 在 国 家 新 闻 出 版 广 电 总 局 ( 办 事 服 务 便 民 查 询 新 闻 出 版 机 构 查 询 ) 上 能 够 查 到 刊 凡 在 有 中 国 标 准 书 公 开

目 录 办 公 OA 介 绍... 3 办 公 OA... 4 一. 收 件 箱 发 布 信 件 查 看 个 人 信 件... 7 二. 公 共 留 言 发 布 公 共 留 言 查 看 公 共 留 言... 9 三. 校 长 荐

抗 战 时 期 国 民 政 府 的 银 行 监 理 体 制 探 析 % # % % % ) % % # # + #, ) +, % % % % % % % %

Transcription:

第 3 章 感 悟 Hibernate 操 作 数 据 的 方 便 对 于 J2EE 轻 量 级 架 构 而 言,Hibernate 是 一 个 重 要 的 构 成 部 分, 它 让 开 发 人 员 像 存 取 java 对 象 一 样 存 储 数 据,Struts 和 Spring 尽 管 基 于 MVC 但 更 多 的 是 基 于 业 务 逻 辑 和 视 图 层 的 架 构, 在 数 据 层 仅 仅 是 轻 描 淡 写, 如 果 不 使 用 Hibernate, 它 们 往 往 会 使 用 传 统 的 JDBC 做 为 其 数 据 层 本 章 首 先 将 比 较 JDBC 技 术 的 各 种 不 方 便 之 处, 然 后 提 出 ORM 概 念, 最 后 将 介 绍 Hibernate 技 术 3.1 前 提 工 作 本 章 所 有 的 示 例 都 基 于 一 个 测 试 数 据 库 testdb. 使 用 的 是 MySql 数 据 库 3.0 版 假 设 读 者 已 经 安 装 好 MySql3.0 所 以 关 于 MySql 的 安 装 这 里 不 再 介 绍, 笔 者 向 大 家 介 绍 一 个 非 常 实 用 的 MySql 客 户 端 软 件 SQLyog, 可 以 通 过 http://www.google.com 得 到 这 个 软 件 的 非 常 多 的 下 载 网 页 SQLyog 的 安 装 非 常 简 单, 一 直 保 持 默 认 单 击 Next 按 钮 就 可 以 这 里 只 介 绍 下 如 何 配 置 SQLyog( 英 文 原 版 ) 使 其 连 接 一 个 具 体 的 MySql 服 务 安 装 好 后 的 SQLyog 会 在 桌 面 产 生 一 个 快 捷 方 式 如 图 3-1 所 示 : 图 3-1SQLyog 快 捷 方 式 双 击 此 快 捷 方 式, 进 入 到 登 录 界 面 如 图 3-2 所 示 : 图 3-2 配 置 sqlyog 界 面 上 面 是 一 个 已 经 配 置 好 了 的 界 面, 下 面 简 单 讲 解 下, MySQL Host Address 这 个 是 MySQL 服 务 的 IP 地 址, 由 于 笔 者 的 MySQL 和 SQLyog 都 是 安 装 在 同 一 台 电 脑 上, 所 以 使 用 localhost 就 可 以 User name: 是 连 接 MySQL 的 用 户 名, 这 里 使 用 具 有 最 高 权 限 的 root Password 是 密 码 Port 是 MySQL 的 监 听 端 口, 它 是 安 装 MySQL 时 候 指 定 的 端 口, 这 里 是 3305,( 可 能 你 的 MySQL 是 3306)

配 置 好 后 单 击 connect 按 钮 如 果 连 接 成 功 的 话, 就 会 出 现 到 SQLyog 的 主 界 面 如 图 3-3 所 示 : 图 3-3 SQLyog 的 主 界 面 从 这 个 主 界 面 的 可 以 看 到 已 经 建 立 好 的 book 等 数 据 库, 现 在 需 要 为 本 章 新 建 一 个 数 据 库 testdb, 在 菜 单 栏 中 选 择 DB Create Database 命 令, 将 弹 出 一 个 输 入 窗 口 如 图 3-4 所 示 : 图 3-4 新 建 数 据 库 输 入 新 建 的 数 据 名 称 testdb, 单 击 Create 按 钮, 将 完 成 数 据 库 的 创 建, 这 时 候 可 以 在 数 据 库 导 航 栏 中 看 到 新 建 的 testdb 如 图 3-5 所 示 : 图 3-5 新 建 好 的 数 据 库 testdb 接 下 来 需 要 在 这 个 数 据 库 中 新 建 三 张 本 章 示 例 将 使 用 到 的 表 : 学 生 基 本 信 息 表, 课 程 基 本 信 息 表, 学 生 选 课 关 系 表 在 testdb 选 择 状 态 下 ( 如 图 3-5) 在 菜 单 栏 中 选 择 DB Create Table 命 令 将 出 现 表 创 建 界 面 如 图 3-6 所 示 :

图 3-6 创 建 学 生 基 本 信 息 表 在 此 图 中 FileName 是 表 格 列 名,Datatype 是 列 的 数 据 类 型,Len 是 长 度, 图 3-6 创 建 的 是 学 生 基 本 信 息 表, 它 包 括 : Stu_id 学 号, 同 时 也 是 主 键 Stu_name 是 学 生 姓 名, gendar 是 性 别 单 击 Create Table 按 钮 后 按 照 提 示 输 入 表 名 stu_basic_info, 学 生 基 本 信 息 表 就 算 创 建 完 毕 然 后 使 用 同 样 的 办 法 分 别 创 建 课 程 基 本 信 息 表 (course_basic_info) 如 图 3-7 所 示 : 图 3-7 课 程 基 本 信 息 表 course_id 是 唯 一 标 识 一 个 课 程 的 主 键 id course_name 是 课 程 名 称 description 是 关 于 课 程 的 描 述 信 息 接 下 来 创 建 选 课 关 系 表 stu_relation_course, 如 图 3-8 所 示 :

图 3-8 学 生 选 课 关 系 表 Stu_id 选 课 学 生 学 号, 外 键 Course_id 课 程 id 外 键 Choice_date 选 课 日 期 Stu_id 和 course_id 都 是 外 键, 在 上 面 的 GUI 界 面 中 无 法 为 一 张 正 在 创 建 的 表 指 定 外 键, 指 定 外 键 的 办 法 是, 选 中 选 课 关 系 表 stu_relation_course, 如 图 3-9 所 示 : 图 3-9 选 择 表 stu_relation_course 然 后 选 择 菜 单 栏 中 的 Table Relationships/Foreign Keys 命 令 或 者 按 F10 弹 出 创 建 外 键 的 对 话 框 如 图 3-10 所 示 : 图 3-10 创 建 外 键 对 话 框 单 击 New 按 钮 弹 出 如 图 3-11 的 对 话 框

图 3-11 SQLyog 中 创 建 外 键 向 导 在 Referenced Table 的 下 拉 菜 单 中 选 择 表 stu_basic_info, 在 Constraint Name 中 填 写 一 个 名 称, 在 Source Column 中 选 择 stu_id, 在 Target Column 中 也 选 择 stu_id 最 终 配 置 好 的 界 面 如 图 3-12 所 示 : 图 3-12 设 置 学 生 号 为 外 键 单 击 Create 按 钮 完 成 创 建, 并 使 用 同 样 的 办 法 为 课 程 号 也 创 建 成 外 键 当 然 上 面 是 采 用 图 形 界 面 的 操 作 方 式 创 建 表 和 它 的 约 束, 也 可 以 直 接 使 用 sql 语 句 的 办 法, 比 如 学 生 选 课 关 系 表 的 创 建 SQL 为 : CREATE TABLE `stu_relation_course` ( `stu_id` varchar(10) default NULL, `course_id` int(2) default NULL, `choice_date` date default NULL, KEY `FK_stu_id` (`stu_id`), KEY `FK_course_id` (`course_id`), (`course_id`) REFERENCES `course_basic_info` (`course_id`), REFERENCES `stu_basic_info` (`stu_id`) CONSTRAINT `FK_course_id` FOREIGN KEY CONSTRAINT `FK_stu_id` FOREIGN KEY (`stu_id`) ) ENGINE=InnoDB DEFAULT CHARSET=gbk 对 于 上 面 这 段 Sql 语 句 不 同 的 数 据 库 可 能 会 有 所 差 异 下 面 的 一 个 工 作 就 是

为 这 三 张 表 填 充 测 试 数 据, 首 先 为 学 生 基 本 信 息 表 填 充 测 试 数 据, 在 SQLyog 中 编 辑 一 个 表 的 操 作 是 十 分 方 便 的, 做 法 是 选 中 需 要 修 改 的 表 如 学 生 基 本 信 息 表 stu_basic_info, 然 后 单 击 Table Data 标 签 页 如 图 3-13 所 示 : 图 3-13 学 生 基 本 信 息 stu_basic_info 表 图 中 可 见 已 经 为 学 生 基 本 信 息 表 添 加 了 张 三 等 三 人 的 基 本 信 息 ( 不 要 忘 记 单 击 保 存 按 钮 才 能 生 效 ) 使 用 同 样 的 操 作 方 式 为 课 程 基 本 信 息 填 充 测 试 数 据 如 图 3-14 所 示 : 图 3-14 课 程 基 本 信 息 表 所 有 测 试 数 据 最 后 一 个 是 学 生 选 课 关 系 表 如 图 3-15 所 示 : 图 3-15 学 生 选 课 关 系 表 一 个 成 熟 的 数 据 库 管 理 系 统 都 具 有 权 限 机 制, 以 上 的 操 作 是 通 过 root 即 具 有 顶 级 权 限 的 用 户 登 录 到 数 据 库 中 的, 而 在 应 用 程 序 中 可 能 是 不 安 全 或 者 干 脆 是 不 允 许 的, 因 此 最 好 单 独 为 应 用 程 序 分 配 角 色 和 用 户 在 SQLyog 中 创 建 一 个 用 户 角 色 是 非 常 方 便 的, 选 中 testdb 这 个 表 单 击 它, 然 后 在 菜 单 栏 中 选 择 Tools User Manager Add Users 命 令 将 弹 出 如 图 3-16 所 示 的 对 话 框 : 图 3-16 添 加 用 户 对 话 框 UserName: 添 加 一 个 用 户 名, 这 里 已 经 添 加 为 test Host: 主 机 名 称, 保 持 默 认 Password: 密 码, 这 里 为 test

Retype Password: 重 新 输 入 密 码 可 以 看 到 不 同 版 本 的 MySQL 支 持 不 一 样 的 权 限, 为 了 简 单 起 见 这 里 单 件 select All 从 而 使 得 test 这 个 用 户 具 有 了 所 有 权 限, 最 后 单 击 Create 按 钮 完 成 对 test 用 户 的 创 建 前 期 的 数 据 库 初 始 化 工 作 到 此 完 成 3.2 传 统 的 JDBC 方 式 连 接 数 据 库 介 绍 JDBC 是 一 组 封 装 了 底 层 数 据 库 细 节 的 Java API, 就 其 功 能 本 身 而 言 并 没 什 么 可 以 挑 剔, 而 且 的 确 需 要 承 认 JDBC 的 稳 定 和 功 能 齐 全 但 它 的 一 个 最 大 的 缺 点 是 不 容 易 使 用, 要 熟 悉 的 使 用 JDBC 对 于 普 通 程 序 员 来 说 仍 然 是 一 件 困 难 不 小 的 事 情 下 面 举 一 例 来 说 明 这 一 问 题, 针 对 3.1 中 创 建 的 testdb, 如 果 提 出 一 这 样 的 一 个 需 求 : 将 张 三 的 选 课 信 息 列 出 来, 我 们 期 望 得 到 的 结 果 如 图 3-16 所 示 : 图 3-17 张 三 的 选 课 信 息 下 面 使 用 程 序 实 现, 以 MyEclipse 为 例 使 用 在 前 几 章 介 绍 的 知 识 在 MyEclipse 中 创 建 一 个 Java Project 命 名 为 :hibernate ( 后 面 介 绍 Hibernate 时 候 仍 然 使 用 这 个 工 程 ), 创 建 好 后 的 工 程 如 图 3-17 所 示 : 图 3-18 名 为 hibernate 的 一 个 Java Project 正 如 图 中 所 示, 一 个 普 通 的 java 工 程 其 最 原 始 的 面 貌 是 非 常 简 洁 的, 下 一 步 是 需 要 导 入 连 接 MySQL 数 据 库 所 需 要 的 jar 包 它 是 必 须 的,JDBC 必 须 通 过 它 才 能 访 问 MySQL 数 据 库, 同 样 的, 如 果 是 其 它 数 据 库 比 如 Oracle, 也 需 要 类 似 的 包 在 这 里 我 们 可 以 使 用 mysql-connector-java-3.1.0-bin.jar( 笔 者 的 Mysql 数 据 库 是 3.0 版 本 ), 这 个 包 可 以 从 Mysql 的 官 方 网 站 上 下 载 到 如 果 你 的 MySQL 数 据 库 是 其 它 版 本, 则 必 须 使 用 对 应 的 版 本 的 驱 动 包 下 载 完 毕 后, 在 MyEclipse 中 选 择 hibernate 这 个 工 程, 如 图 3-17 就 是 是 选 中 状 态, 右 击 选 择 build path Add External Archives 命 令 将 弹 出 如 图 3-18 所 示 的 文 件 选 择 对 话 框 : 图 3-19 文 件 选 择 对 话 框

正 如 你 所 见, 文 件 类 型 只 能 是 jar 或 者 zip 为 什 么 zip 也 是 可 以 的 呢? 事 实 上,jar 包 是 一 种 压 缩 了 的 文 件, 而 使 用 的 压 缩 算 法 恰 好 是 zip 选 择 图 中 的 jar 包, 单 件 打 开 按 钮, 就 能 完 成 jar 包 的 导 入 导 入 包 后 的 hibernate 这 一 工 程 如 图 3-19 所 示 : 图 3-20 包 导 入 后 的 hibernate 接 下 来 的 工 作 是 编 写 代 码, 需 要 做 的 是 在 hibernate 这 个 工 程 中 创 建 一 个 包 命 名 为 test. 然 后 在 test 包 下 新 建 一 个 类 命 名 为 TestJDBC, 创 建 好 后 的 hibernate 工 程 如 图 3-20 所 示 : 图 3-21 TestJDBC 创 建 完 后 的 hibernate 最 后 一 件 事 情 是 在 TestJDBC 编 写 实 际 的 java 代 码, 针 对 本 节 开 始 提 出 的 需 求 编 写 代 码 如 下 所 示 ( 代 码 具 体 内 容 的 含 义 会 在 后 面 详 细 讲 解 ): package test; import java.sql.connection; import java.sql.drivermanager; import java.sql.resultset; import java.sql.resultsetmetadata; import java.sql.statement; import java.text.simpledateformat; import java.util.date; /** * 使 用 JDBC 方 式 访 问 数 据 库 * @author Administrator * public class TestJDBC { /** * 连 接 数 据 库 的 库 名, 用 户, 密 码 信 息 private static String url = "jdbc:mysql://localhost:3305/testdb"; private static String username = "test"; private static String password = "test"; /** * 一 个 连 接 一 个 对 象 只 会 产 生 一 个 连 接 private Connection con;

/** * 一 个 语 句 每 个 操 作 都 会 产 生 一 个 语 句 private Statement stmt; /** * 装 载 驱 动 并 确 保 系 统 启 动 后 只 装 载 一 次 static { try { Class.forName("com.mysql.jdbc.Driver"); catch (Exception e) { System.out.println(e.getMessage()); /** * 构 造 函 数 public TestJDBC() { try { // 创 建 一 个 连 接 setcon(drivermanager.getconnection(url, username, password)); catch (Exception e) { e.printstacktrace(); /** * 执 行 一 条 sql 语 句, 简 单 起 见, 将 结 果 以 String 类 型 二 维 数 组 的 形 式 返 回 public String[][] execquery(string sqlstr) { try { try { // 创 建 一 个 statement setstmt(getcon().createstatement( ResultSet.TYPE_SCROLL_INSENSITIVE,// 指 定 游 标 类 型 ResultSet.CONCUR_UPDATABLE)); // sqlserver 不 支 持 这 种 游 标 类 型 / 并 发 组 合 catch (Exception ee) { // 专 为 sqlserver 设 置 游 标 类 型 / 并 发 组 合 setstmt(getcon().createstatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)); ResultSet rs = getstmt().executequery(sqlstr);// 将 sqlstr 发 送 给 数 据 库 并 执 行 ResultSetMetaData rsmd = rs.getmetadata();// 使 用 这 个 结 果 集 是 为 了 得 到 列 的 信 息, 而 这 在 ResultSet 中 是 无 法 获 得 的

int collen = rsmd.getcolumncount();// 得 到 列 的 个 数 rs.last();// 游 标 指 向 最 后 一 行 String result[][] = new String[rs.getRow()][collen]; rs.beforefirst();// 将 游 标 重 新 指 向 第 一 行 的 前 一 行 while (rs.next()) {// 遍 历 结 果 集 for (int i = 1; i <= collen; i++) { String data = ""; Object obj = rs.getobject(i);// 返 回 的 结 果 都 是 对 象 if (obj instanceof Date) {// 对 日 期 类 型 的 对 象 进 行 格 式 化 处 理, 这 里 不 是 必 须 的 Date ts = (Date) obj; SimpleDateFormat format = new SimpleDateFormat( "yyyy-mm-dd"); data = format.format(ts); else { try { 制 类 型 转 化 为 字 符 串 类 型 data = (String) obj;// 为 了 简 单 起 见, 将 所 有 的 类 型 强 catch (Exception e) { data = obj.tostring(); result[rs.getrow() - 1][i - 1] = data; return result; catch (Exception e) { e.printstacktrace(); return null; // ---------getter 和 setter 方 法 区 -------------- public Connection getcon() { return con; public void setcon(connection con) { this.con = con; public Statement getstmt() {

return stmt; public void setstmt(statement stmt) { this.stmt = stmt; // 关 闭 资 源 public void close(){ try { getstmt().close(); getcon().close(); catch (Exception e) { e.printstacktrace(); public static void main(string[] args) { TestJDBC jdbcobj = new TestJDBC();// 实 例 化 对 象 // 编 写 sql 查 询 语 句 String sqlstr = "select s1.stu_id,s1.stu_name,s1.gendar,s3.course_name,s3.description," + "s2.choice_date from stu_basic_info s1,stu_relation_course s2," + "course_basic_info s3 where s1.stu_id='a0111' and " + "s1.stu_id=s2.stu_id and s2.course_id=s3.course_id"; // 执 行 sql 并 得 到 结 果 String result[][]=jdbcobj.execquery(sqlstr); // 输 出 结 果 printresult(result); // 关 闭 资 源 jdbcobj.close(); // 输 出 打 印 结 果 private static void printresult(string[][] result) { 选 课 日 期 "); System.out.println(" 学 号 姓 名 性 别 课 程 名 课 程 描 述 for (int i = 0; i < result.length; i++) { for(int j=0;j<6;j++ ){ System.out.print(result[i][j]+" "); System.out.println("");// 回 车

针 对 上 面 这 段 代 码 下 面 给 出 详 细 的 讲 解, 使 用 JDBC 访 问 数 据 库 有 一 个 固 定 的 顺 序 : 装 载 驱 动 这 是 一 切 工 作 之 前 的 首 要 工 作, 这 体 现 在 下 面 这 段 代 码 : /** * 装 载 驱 动 并 确 保 系 统 启 动 后 只 装 载 一 次 static { try { Class.forName("com.mysql.jdbc.Driver"); catch (Exception e) { System.out.println(e.getMessage()); 这 里 使 用 static 方 式 执 行 一 段 静 态 的 代 码, 它 所 带 来 的 好 处 是 这 段 代 码 永 远 只 会 执 行 一 次, 因 为 装 载 驱 动 这 个 工 作 一 次 装 载 完 毕, 后 面 再 对 数 据 库 进 行 访 问 时 不 需 要 重 新 装 载, 如 果 每 次 都 重 新 装 载, 必 定 会 使 得 性 能 大 大 降 低 其 次 com.mysql.jdbc.driver 这 个 类 是 存 在 mysql-connector-jdbc-3.1.0.bin.jar 这 个 包 中 的, 如 果 在 先 前 没 有 导 入 这 个 包, 那 么 这 里 就 会 出 现 java.sql.sqlexception: No suitable driver 错 误 建 立 connection 每 次 对 数 据 库 的 访 问 都 需 要 动 态 的 与 数 据 库 创 建 一 个 连 接, 然 后 的 增, 删, 改, 查 等 动 作 都 是 在 这 个 连 接 下 进 行 的,TestJDBC 体 现 这 一 点 的 代 码 在 它 的 构 造 函 数 上 : /** * 构 造 函 数 public TestJDBC() { try { // 创 建 一 个 连 接 setcon(drivermanager.getconnection(url, username, password)); catch (Exception e) { e.printstacktrace(); 使 用 构 造 函 数 建 立 连 接 使 得 用 户 实 例 化 一 个 TestJDBC 对 象 时 候, 就 已 经 完 成 了 连 接 的 创 建, 自 然 也 完 成 了 驱 动 的 装 载 创 建 statement 对 每 一 个 sql 语 句 被 执 行 前 都 要 创 建 一 个 statement, 在 TestJDBC 中 体 现 在 下 面 这 段 代 码 : try {

种 游 标 类 型 / 并 发 组 合 // 创 建 一 个 statement setstmt(getcon().createstatement( catch (Exception ee) { ResultSet.TYPE_SCROLL_INSENSITIVE,// 指 定 游 标 类 型 ResultSet.CONCUR_UPDATABLE)); // sqlserver 不 支 持 这 // 专 为 sqlserver 设 置 游 标 类 型 / 并 发 组 合 setstmt(getcon().createstatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)); 从 代 码 中 可 以 看 到, 建 立 一 个 连 接 的 关 键 代 码 是 使 用 connection 对 象 的 createstatement 方 法, 这 也 是 为 什 么 必 须 在 此 之 前 创 建 connection 对 象 上 面 这 段 代 码 可 能 读 者 会 比 较 难 以 理 解, 主 要 是 createstatement 的 两 个 参 数, 它 们 在 这 里 不 是 必 须 的, 表 示 的 是 游 标 类 型 对 于 本 示 例 而 言 完 全 可 以 去 掉 里 面 参 数, 使 得 它 变 成 为 setstmt(getcon().createstatement()); 不 过 笔 者 想 告 诉 大 家 的 是 在 某 些 场 合 这 两 个 参 数 是 非 常 有 必 要 的 对 于 mysql,oracle 数 据 库 使 用 try 中 的 方 式 完 全 没 有 问 题, 而 对 于 sqlserver 数 据 库 则 会 抛 出 异 常 而 不 得 不 使 用 catch 中 的 那 种 方 式 这 体 现 了 一 点 :JDBC 程 序 员 要 关 心 的 不 仅 仅 是 业 务 逻 辑, 还 有 各 种 数 据 库 系 统 的 差 异 执 行 sql 语 句 上 面 的 工 作 就 绪 后 就 可 以 通 过 调 用 statement 对 象 的 executequery() 方 法 执 行 sql 语 句 了,TestJDBC 中 体 现 这 点 的 核 心 代 码 是 : ResultSet rs = getstmt().executequery(sqlstr);// 将 sqlstr 发 送 给 数 据 库 并 执 行 ResultSetMetaData rsmd = rs.getmetadata();// 使 用 这 个 结 果 集 是 为 了 得 到 列 的 信 息, 而 这 在 ResultSet 中 是 无 法 获 得 的 通 过 代 码 可 以 看 到 执 行 sqlstr 的 结 果 被 封 装 在 一 个 ResultSet 对 象 中, 而 最 难 堪 的 是 它 并 不 包 含 所 有 信 息, 比 如 要 取 得 列 的 个 数 信 息, 还 必 须 得 借 助 于 ResultSetMetaData 这 也 是 JDBC 难 以 使 用 的 另 一 个 原 因 关 闭 资 源 JDBC 程 序 员 必 须 要 养 成 的 一 个 好 习 惯 的 是 在 资 源 使 用 完 毕 后 关 闭 它 TestJDBC 中 体 现 这 点 的 代 码 是 : // 关 闭 资 源 public void close(){ try { getstmt().close(); getcon().close(); catch (Exception e) { e.printstacktrace(); 通 过 代 码 可 以 看 到, 需 要 关 闭 的 资 源 主 要 是 statement 和 connection 如 果 一 个 大 意 的 JDBC 程 序 员 总 是 忘 记 完 毕 资 源, 那 么 后 果 尽 管 不 会 太 严 重, 但 数 据 库 因 此 而 无 法 访 问 或 者 抛 出 奇 怪 的 异 常 则 是 完 全 有 可 能 的 通 过 以 上 的 分 析 可 以 总 结 出 使 用 传 统 的 JDBC 连 接 数 据 库 的 几 大 弊 端 : (1) 步 骤 复 杂 尽 管 可 以 将 装 载 驱 动, 建 立 连 接, 创 建 语 句 等 步 骤 封 装 起 来 使 其 变 成 一 个 通

用 的 访 问 接 口, 但 对 于 没 有 良 好 的 通 用 编 程 能 力 的 JDBC 程 序 员 而 言 则 是 一 件 比 较 困 难 的 事 情, 于 是 会 导 致 像 TestJDBC 这 样 的 代 码 在 整 个 应 用 中 到 此 可 见 如 果 某 个 地 方 需 要 修 改 比 如 数 据 库 连 接 地 址 或 者 用 户 名 或 者 密 码, 则 到 处 要 修 改 (2) 需 要 编 写 长 长 的 sql 语 句 对 于 本 节 开 始 处 将 张 三 的 选 课 信 息 列 出 来 这 一 需 求 并 不 算 复 杂, 但 是 需 要 为 此 编 写 的 sql 语 句 却 一 点 也 不 简 洁, 如 下 所 示 : // 编 写 sql 查 询 语 句 String sqlstr = "select s1.stu_id,s1.stu_name,s1.gendar,s3.course_name,s3.description," + "s2.choice_date from stu_basic_info s1,stu_relation_course s2," + "course_basic_info s3 where s1.stu_id='a0111' and " + "s1.stu_id=s2.stu_id and s2.course_id=s3.course_id"; 从 一 堆 单 引 号 中 推 测 一 段 sql 语 句 的 意 图 是 一 件 不 容 易 的 事 情 但 是 当 需 求 变 更 的 时 候 则 又 是 一 件 不 得 不 做 的 苦 差 事, 如 果 你 用 JDBC 编 程 的 话 (3) 平 台 移 植 困 难 突 然 哪 天 mysql 变 得 不 堪 重 负, 而 需 要 将 其 移 植 到 oracle 或 者 sqlserver 时, 上 面 的 代 码 是 否 可 以 保 证 在 一 丝 不 动 的 情 况 下 还 能 正 常 的 工 作 则 是 一 个 疑 问 不 然 也 不 会 在 创 建 statement 编 写 参 数 的 时 候 有 那 么 多 的 顾 虑 了 (4) 意 外 的 性 能 损 失 理 论 上 来 说 采 用 最 原 始 的 方 式 其 性 能 应 该 是 最 好 的 不 否 认 这 个 事 实, 但 是 其 前 提 是 JDBC 程 序 员 足 够 的 了 解 JDBC API 举 个 例 子, 如 果 现 在 有 一 个 新 的 需 求 要 求 在 stu_basic_info 表 中 插 入 100 条 数 据 或 者 更 多 JDBC 程 序 员 一 不 小 心 就 会 使 用 一 个 for 循 环 创 建 100 条 insert 语 句, 然 后 一 条 一 条 的 插 入 事 实 上, 使 用 JDBC 的 批 处 理 功 能 可 以 大 大 的 提 高 性 能 于 是 不 得 不 说 如 果 你 有 过 多 的 选 择, 就 必 然 会 迷 失 方 向 3.3 ORM 简 介 和 Hibernate 概 述 既 然 JDBC 有 如 此 多 的 缺 点, 那 么 是 否 可 以 找 到 一 个 更 好 的 办 法 用 来 弥 补 这 些 不 足 呢 幸 运 的 是 这 种 办 法 已 经 被 提 升 到 理 论 的 高 度, 人 们 称 其 为 ORM 思 想 本 节 将 讲 述 ORM 思 想 的 基 本 概 念, 和 一 个 实 现 了 ORM 思 想 的 实 体 Hibernate 的 概 述 3.3.1 ORM 简 介 ORM 的 全 称 是 (Object Relational Mapping), 意 为 对 象 关 系 映 射 这 里 的 关 系 与 关 系 数 据 库 中 的 关 系 是 一 个 概 念 早 在 数 据 库 这 个 概 念 提 出 的 年 代, 人 们 就 探 讨 以 什 么 样 的 形 式 存 储 数 据, 主 要 有 三 种 形 式 的 讨 论 : 面 向 层 次 结 构, 面 向 关 系 结 构, 面 向 对 象 三 种 方 式 都 有 各 种 的 优 缺 点, 但 是 面 向 关 系 是 最 成 熟, 最 具 有 数 学 依 据 一 种 方 式, 于 是 面 向 关 系 的 数 据 存 储 方 式 至 今 仍 然 是 主 流 尽 管 使 用 面 向 关 系 的 方 式 存 储 数 据 是 成 熟 和 合 理 的, 但 是 在 使 用 面 向 关 系 方 式 访 问 和 操 作 数 据 则 是 一 件 不 容 易 的 事 情, 它 是 导 致 在 应 用 程 序 中 编 写 长 长 sql 语 句 的 根 本 原 因, 典 型 的 是 JDBC 方 式 的 数 据 访 问 ORM 是 针 对 面 向 关 系 返 回 数 据 方 式 的 缺 点 而 提 出 的 一 种 数 据 访 问 方 式, ORM 旨 在 寻 找 一 种 关 系 到 对 象 的 映 射 关 系, 使 得 程 序 开 发 人 员 能 像 操 控 对 象 一 样

操 作 关 系 数 据 库 中 的 数 据 对 于 一 个 使 用 面 向 对 象 的 语 言 进 行 面 向 对 象 的 开 发 的 程 序 员 而 言, 使 用 面 向 对 象 的 方 式 操 作 数 据 是 在 自 然 不 过 的 了 3.3.2Hibernate 概 述 隶 属 于 Jboss 组 织 的 Hibernate 是 目 前 比 较 流 行 的 一 个 ORM 组 件, 它 实 现 了 ORM 的 框 架 构 思, 成 功 的 将 关 系 数 据 映 射 为 普 通 对 象 不 仅 仅 如 此,Hibernate 包 括 众 多 的 方 便 的 API 供 开 发 人 员 使 用, 并 且 有 自 己 的 查 询 体 系 HQL 目 前 的 Hibernate 相 关 开 发 包 主 要 包 括 以 下 几 个 : Hibernate Core 这 个 包 包 含 了 所 有 Hibernate 的 核 心 功 能, 理 论 上 来 说 使 用 这 一 个 包 就 可 以 使 用 Hibernate 进 行 开 发 应 用 Hibernate Tools 这 个 软 件 包 主 要 用 来 完 成 逆 向 或 者 正 向 工 作 正 向 工 作 是 指 根 据 Java 对 象 生 成 Hibernate 配 置 文 件 逆 向 工 作 是 根 据 数 据 库 结 构 生 成 Hibernate 配 置 文 件 和 Java 对 象 Hibernate EntityManager 这 个 包 是 针 对 EJB3.0 规 范 而 开 发 出 来 的, 它 实 现 了 EJB3.0 中 定 义 的 接 口 Hibernate Annotations 这 个 包 主 要 用 来 完 成 一 些 特 殊 的 注 释, 比 如 Hibernate Validator 框 架 中 使 用 的 验 证 注 释 Nhibernate 这 个 包 也 包 含 了 Hibernate 的 核 心 功 能, 与 Hibernate Core 不 同 的 是 它 是 用 于.Net 环 境 3.4 Hibernate 下 载 和 使 用 本 节 将 讲 述 如 何 获 得 Hibernate, 并 通 过 一 个 具 体 实 例 讲 解 Hibernate 的 使 用 3.4.1 Hibernate 的 下 载 可 以 从 官 方 网 站 http://www.hibernate.org/ 中 下 载 到 3.3.2 中 提 到 的 各 种 包, 一 般 下 载 Hibernate Core 包 就 可 以 了 如 果 是 使 用 MyEclipse 这 样 的 IDE 工 具 则 不 需 要 下 载,MyEclipse 集 成 了 Hibernate 3.4.2 Hibernate 的 使 用 以 在 MyEclipse 中 为 例, 编 写 一 个 使 用 Hibernate 的 例 子 需 求 是 : 基 于 3.1 节 创 建 的 testdb 和 3.2 节 中 的 工 程 hibernate, 打 印 所 有 学 生 的 基 本 信 息, 即 将 stu-basic_info 表 中 的 所 有 数 据 打 印 在 控 制 台 详 细 步 骤 如 下 : 在 MyEclipse 的 菜 单 栏 中 选 择 Window Open Perspectives MyEclipse Database Explorer 命 令 中 打 开 透 视 图 MyEclipse Database Explorer 如 图 3-22 所 示 :

图 3-22 Database Explorer 透 视 图 在 上 图 中 可 以 看 到 视 图 DB Browser 在 其 空 白 处 右 击 选 择 New... 命 名 将 弹 出 如 图 3-23 所 示 的 对 话 框 : 图 3-23 数 据 库 配 置 对 付 框 各 个 选 项 的 基 本 含 义 如 下 : Driver template: 驱 动 模 板, 对 于 不 同 的 版 本 不 同 类 型 的 数 据 库 驱 动 模 板 都 是 不 同 的 Driver name: 驱 动 名 称, 可 以 任 意 写 Connection URL: 连 接 URL 地 址, 这 和 在 应 用 程 序 中 编 写 的 连 接 数 据 库 地 址 是 一 样 的, 不 同 的 数 据 库 这 个 地 址 的 写 法 也 不 一 样 User name: 连 接 数 据 库 的 用 户 名, 它 必 须 是 在 数 据 库 中 存 在 的 用 户 名 Password: 连 接 数 据 库 的 密 码

Driver JARs: 连 接 数 据 库 需 要 使 用 到 的 驱 动 包, 不 同 的 数 据 库 驱 动 包 不 一 样 Driver classname: 使 用 的 驱 动 类, 由 于 一 个 包 中 往 往 会 有 多 个 可 选 的 驱 动 一 般 保 持 默 认 即 可 下 面 是 针 对 testdb 数 据 库 的 配 置, 如 图 3-24 所 示 : 图 3-24 配 置 testdb 单 件 Finish 按 钮 就 可 以 完 成 配 置 在 Database Explorer 中 配 置 好 数 据 库 后, 回 到 Java Perspective 将 工 程 hibernate 中 的 mysql 驱 动 包 去 掉, 因 为 在 3.2 节 加 入 了 此 包, 而 这 里 已 经 不 再 使 用 这 种 方 式 添 加 驱 动 包 去 掉 一 个 外 部 连 接 的 jar 包 的 办 法 是 选 中 这 个 jar 包 右 击 选 择 Build Path Remove from Build Path 命 令 接 下 来 要 做 的 是 要 为 hibernate 这 个 工 程 添 加 hibernate 的 核 心 包 有 两 者 办 法, 一 种 是 从 官 方 网 站 下 载 到 这 些 包 然 后 使 用 外 部 连 接 的 办 法 导 入 另 一 种 办 法 是 使 用 MyEclipse 自 带 的 Hibernate 能 力 方 法 是 在 工 程 被 选 中 的 状 态 下 选 择 MyEclipse Add Hiberate Capabilities 命 令, 将 弹 出 如 图 3-25 所 示 的 对 话 框 :

图 3-25 为 工 程 添 加 Hibernate 这 是 一 个 库 的 选 择 界 面, 保 持 默 认 选 择 最 新 版 本 的 3.1Core Libraries 就 可 以 单 件 Next 按 钮 进 入 如 图 3-26 所 示 的 对 话 框 : 图 3-26 配 置 文 件 的 存 放 路 径 设 置 这 里 需 要 解 释 的 是 Configuration Folder 它 是 指 hibernate 的 一 些 配 置 文 件 存 放 的 路 径 如 果 选 择, 则 默 认 为 default 包 Configuration File Name 是 Hibernate 配 置 文 件 的 名 称, 它 是 可 以 修 改 的 不 过 一 般 保 持 默 认 关 于 这 些 配 置 文 件 的 具 体 含 义 会 在 后 面 讲 解 这 里 不 做 任 何 修 改 单 件 Next 按 钮 进 入 下 一 步, 如 图 3-27 所 示 :

图 3-27 选 择 数 据 库 对 话 框 在 DB Driver 中 选 择 刚 才 在 Database Explorer 中 的 配 置 好 了 的 testdb 后 面 的 选 项 将 自 动 填 充, 如 图 3-28 所 示 : 图 3-28 选 择 数 据 源 单 击 Next 按 钮 进 入 下 一 步, 如 图 3-29 所 示 :

图 3-29 配 置 sessionfactory 这 一 步 是 用 来 配 置 sessionfactory 的, 可 以 跳 过 去, 但 是 建 议 配 置 一 下, 其 中 Java source folder 是 java 程 序 的 文 件 夹, 可 以 任 意 设 置,Java Package 是 包 也 可 以 任 意 设 置 配 置 好 的 sessionfactory 如 图 3-30 所 示 所 示 : 图 3-30 配 置 好 了 的 SessionFactory 单 件 Finish 按 钮 就 可 以 完 成 Hibernate 的 添 加 最 后 的 工 程 hibernate 如 图 3-31 图 3-31 具 有 Hibernate 能 力 的 工 程 hiberante 接 下 来 的 事 情 是 需 要 对 testdb 进 行 逆 向 工 程 用 前 面 的 办 法 再 次 打 开 MyEclipse Database Explorer 然 后 在 DB Browser 中 选 中 testdb 点 击 如 图 3-32 所 示 的 图 表 按 钮, 从 而 打 开 testdb 的 连 接

图 3-32 Open Connection 图 标 展 开 testdb 数 据 库 直 到 可 以 看 到 其 所 有 表 如 图 3-33 所 示 : 图 3-33 testdb 的 所 有 表 选 中 其 中 的 stu_basic_info 有 表 右 击 选 择 Hibernate Reverser Engineering 将 弹 出 如 3-34 所 示 的 配 置 对 话 框 : 图 3-34 配 置 hibernate 逆 向 文 件 Java src folder: 一 般 在 这 里 选 择 一 个 工 程 的 src 目 录 是 hibernate 逆 向 工 程 的 目 标 工 程 Java package: 这 是 Hibernate 配 置 文 件 所 存 放 的 包 目 录 它 相 对 于 Java src folder, 如 果 这 个 包 不 存 在 则 会 自 动 创 建, 就 象 这 里 的 hibernateconfig Hibernate mapping file: 这 是 Hibernate 各 个 表 的 映 射 文 件 Java Data Object: 关 系 表 通 过 ORM 映 射 后 生 成 的 JavaBean Java Data Acess Object(DAO): 对 象 的 操 作 类 这 里 暂 时 不 用 关 系 其 具 体 的 含 义, 单 击 Finish 按 钮 等 待 逆 向 工 程 完 成 后, 打 开 MyEclipse J2EE 透 视 图, 发 现 现 在 的 hibernate 工 程 多 了 很 多 自 动 生 成 的 代 码 或 配 置 文 件 如 图 3-35 所 示 :

图 3-35 逆 向 工 程 后 的 hibernate 工 程 仔 细 分 析 一 下 这 个 代 码 结 构,hibernateConfig 包 下 包 含 了 自 动 生 成 的 DAO 和 hbm.xml 文 件 以 及 SessionFactory 类 ( 之 前 test 目 录 下 的 SessionFactory 类 可 以 删 除 ) 以 及 JavaBean 在 hibernate 工 程 的 根 目 录 下 另 一 个 重 要 的 配 置 文 件 是 hibernate.cfg.xml 这 是 一 个 最 基 本 的 Hibernate 应 用 所 具 有 的 代 码 架 构, 下 面 针 对 各 类 文 件 概 要 的 讲 解 其 在 Hibernate 中 的 地 位 和 作 用 HibernateSessionFactory: 一 个 实 现 工 厂 模 式 的 用 类 管 理 数 据 库 连 接 的 类 这 个 类 由 MyEclipse 自 动 生 成, 便 于 理 解 笔 者 为 其 加 入 了 中 文 注 释, 代 码 如 下 所 示 : package hibernateconfig; import org.hibernate.hibernateexception; import org.hibernate.session; import org.hibernate.cfg.configuration; /** * Configures and provides access to Hibernate sessions, tied to the * current thread of execution. Follows the Thread Local Session * pattern, see {@link http://hibernate.org/42.html. public class HibernateSessionFactory { /** * Location of hibernate.cfg.xml file. * Location should be on the classpath as Hibernate uses * #resourceasstream style lookup for its configuration file. * The default classpath location of the hibernate config file is * in the default package. Use #setconfigfile() to update * the location of the configuration file for the current session. //cfg 配 置 文 件 所 在 的 位 置 private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml"; private static final ThreadLocal<Session> threadlocal = new ThreadLocal<Session>(); private static Configuration configuration = new Configuration(); private static org.hibernate.sessionfactory sessionfactory; private static String configfile = CONFIG_FILE_LOCATION; static { try {// 装 载 配 置 文 件 configuration.configure(configfile);

// 实 例 化 一 个 sessionfactory sessionfactory = configuration.buildsessionfactory(); catch (Exception e) { System.err.println("%%%% Error Creating SessionFactory %%%%"); e.printstacktrace(); private HibernateSessionFactory() { /** 从 sessionfactory 中 得 到 一 个 session * Returns the ThreadLocal Session instance. Lazy initialize * the <code>sessionfactory</code> if needed. * * @return Session * @throws HibernateException public static Session getsession() throws HibernateException { Session session = (Session) threadlocal.get(); if (session == null!session.isopen()) { if (sessionfactory == null) { rebuildsessionfactory(); session = (sessionfactory!= null)? sessionfactory.opensession() : null; threadlocal.set(session); return session; /** 重 新 创 建 session factory * Rebuild hibernate session factory * public static void rebuildsessionfactory() { try { configuration.configure(configfile); sessionfactory = configuration.buildsessionfactory(); catch (Exception e) { System.err.println("%%%% Error Creating SessionFactory %%%%"); e.printstacktrace(); /** * Close the single hibernate session instance.

* 关 闭 session * @throws HibernateException public static void closesession() throws HibernateException { Session session = (Session) threadlocal.get(); threadlocal.set(null); if (session!= null) { session.close(); /** * return session factory * public static org.hibernate.sessionfactory getsessionfactory() { return sessionfactory; /** * return session factory * 设 置 配 置 文 件 * session factory will be rebuilded in the next call public static void setconfigfile(string configfile) { HibernateSessionFactory.configFile = configfile; sessionfactory = null; /** * return hibernate configuration * 得 到 一 个 配 置 类 public static Configuration getconfiguration() { return configuration; sessionfactory 中 的 session 和 HttpSession 在 概 念 上 是 完 全 不 同 的, 前 者 更 类 似 于 使 用 JDBC 方 式 连 接 数 据 库 时 需 要 创 建 的 Connection 对 象 Hibernate 将 这 种 连 接 集 中 在 一 个 工 厂 中 进 行 管 理 通 过 上 面 的 代 码 可 以 看 到 用 户 程 序 得 到 一 个 session 的 基 本 流 程 是, 首 先 是 通 过 Configuration 类 装 载 hibernate.cfg.xml 文 件 然 后 通 过 对 这 个 配 置 文 件 的 解 析 得 到 数 据 库 相 关 信 息 比 如 连 接 URL 最 终 会 实 例 化 一 个 sessionfactory 对 象 用 户 程 序 通 过 getsession() 方 法 从 这 个 sessionfactory 中 申 请 一 个 session 也 就 相 当 于 与 数 据 库 建 立 了 一 个 连 接 必 要 情 况 下, 客 户 可 以 通 过 close 方 法 将 资 源 关 闭 掉 DAO 数 据 访 问 对 象 DAO 的 英 文 全 称 是 (Data Access Object) 意 为 数 据 访 问 对 象, 通 过 DAO 可 以 方

便 的 对 数 据 进 行 各 种 操 作, 因 为 它 封 装 了 操 作 的 细 节, 在 hibernate 这 个 工 程 中 所 有 的 DAO 文 件 以 DAO 结 尾 如 StuBasicInfoDAO, 这 也 是 由 MyEclipse 自 动 生 成 代 码 如 下 所 示 : package hibernateconfig; import java.util.list; import java.util.set; import org.apache.commons.logging.log; import org.apache.commons.logging.logfactory; import org.hibernate.lockmode; import org.hibernate.query; import org.hibernate.criterion.example; /** * Data access object (DAO) for domain model class StuBasicInfo. * * @see hibernateconfig.stubasicinfo * @author MyEclipse Persistence Tools // 之 所 以 继 承 BaseHibernateDAO 是 因 为 BaseHibernateDAO 实 现 了 getsession 方 法 public class StuBasicInfoDAO extends BaseHibernateDAO { // 使 用 log4j 做 为 日 志 管 理 private static final Log log = LogFactory.getLog(StuBasicInfoDAO.class); // property constants // 与 表 对 应 的 属 性 public static final String STU_NAME = "stuname"; public static final String GENDAR = "gendar"; // 保 存 一 个 瞬 时 对 象 public void save(stubasicinfo transientinstance) { log.debug("saving StuBasicInfo instance"); try { getsession().save(transientinstance); log.debug("save successful"); catch (RuntimeException re) { log.error("save failed", re); throw re; // 删 除 一 个 持 久 对 象 public void delete(stubasicinfo persistentinstance) { log.debug("deleting StuBasicInfo instance"); try { getsession().delete(persistentinstance); log.debug("delete successful"); catch (RuntimeException re) { log.error("delete failed", re); throw re;

// 通 过 主 键 找 对 象 public StuBasicInfo findbyid(java.lang.string id) { log.debug("getting StuBasicInfo instance with id: " + id); try { StuBasicInfo instance = (StuBasicInfo) getsession().get( "hibernateconfig.stubasicinfo", id); return instance; catch (RuntimeException re) { log.error("get failed", re); throw re; // 通 过 示 例 找 对 象 public List findbyexample(stubasicinfo instance) { log.debug("finding StuBasicInfo instance by example"); try { List results = getsession().createcriteria( "hibernateconfig.stubasicinfo").add( Example.create(instance)).list(); log.debug("find by example successful, result size: " + results.size()); return results; catch (RuntimeException re) { log.error("find by example failed", re); throw re; // 通 过 一 个 具 体 属 性 找 对 象 public List findbyproperty(string propertyname, Object value) { log.debug("finding StuBasicInfo instance with property: " + propertyname + ", value: " + value); try { String querystring = "from StuBasicInfo as model where model." + propertyname + "=?"; Query queryobject = getsession().createquery(querystring); queryobject.setparameter(0, value); return queryobject.list(); catch (RuntimeException re) { log.error("find by property name failed", re); throw re; // 通 过 学 生 姓 名 查 找 对 象 public List findbystuname(object stuname) { return findbyproperty(stu_name, stuname); // 通 过 学 生 性 别 查 找 对 象 public List findbygendar(object gendar) { return findbyproperty(gendar, gendar);

// 查 找 出 所 有 对 象 public List findall() { log.debug("finding all StuBasicInfo instances"); try { String querystring = "from StuBasicInfo"; Query queryobject = getsession().createquery(querystring); return queryobject.list(); catch (RuntimeException re) { log.error("find all failed", re); throw re; // 合 并 一 个 游 离 对 象 public StuBasicInfo merge(stubasicinfo detachedinstance) { log.debug("merging StuBasicInfo instance"); try { StuBasicInfo result = (StuBasicInfo) getsession().merge( detachedinstance); log.debug("merge successful"); return result; catch (RuntimeException re) { log.error("merge failed", re); throw re; // 如 果 无 法 判 断 一 个 对 象 是 瞬 时 的 还 是 游 离 的 则 使 用 这 个 方 法 public void attachdirty(stubasicinfo instance) { log.debug("attaching dirty StuBasicInfo instance"); try { getsession().saveorupdate(instance); log.debug("attach successful"); catch (RuntimeException re) { log.error("attach failed", re); throw re; public void attachclean(stubasicinfo instance) { log.debug("attaching clean StuBasicInfo instance"); try { getsession().lock(instance, LockMode.NONE); log.debug("attach successful"); catch (RuntimeException re) { log.error("attach failed", re); throw re; 通 过 对 上 面 的 代 码 进 行 分 析, 可 以 看 到 它 对 外 提 供 很 多 的 访 问 接 口, 使 得 用

户 程 序 在 查 找 或 者 更 新 对 象 时 候 变 得 更 加 简 单 方 便 这 个 类 使 用 到 Hibernate 中 几 个 核 心 的 概 念 和 几 个 重 要 的 API, 这 里 一 一 讲 解 如 下 : 瞬 时 对 象 : 简 而 言 之, 它 就 是 一 个 普 通 对 象 是 同 new 操 作 符 产 生 的 持 久 对 象 : 存 在 于 session 的 Map 容 器 中 的 对 象 游 离 对 象 : 一 个 执 久 对 象 所 关 联 的 session 被 关 闭 或 者 被 销 毁 则 会 有 持 久 态 变 为 游 离 态 需 要 了 解 的 是 一 个 瞬 时 对 象 与 session 关 联 后 就 会 变 成 持 久 对 象, 同 样 一 个 游 离 对 象 再 次 与 一 个 session 关 联 起 来 的 时 候 仍 然 为 变 回 为 持 久 状 态 关 联 的 方 式 有 多 种, 常 见 是 通 过 调 用 session 的 相 关 方 法 比 如 update 关 于 上 面 提 到 的 三 种 对 象 的 具 体 含 义 细 节 可 以 查 看 专 门 论 述 Hibernate 的 书 籍 此 外 上 面 代 码 中 的 黑 体 部 分 代 表 了 Hibernate 中 的 几 个 基 本 的 API 这 里 一 一 介 绍 如 下 : save(): 将 一 个 瞬 时 对 象 保 存 到 数 据 库 中, 同 时 这 个 瞬 时 对 象 变 为 持 久 对 象 delete(): 从 数 据 中 删 除 一 个 持 久 对 象 get(): 从 数 据 库 中 获 得 一 个 持 久 对 象 createquery(): 使 用 HQL 语 法 查 询 对 像 同 时 通 过 代 码 可 以 发 现 以 上 的 几 个 方 法 都 是 通 过 session 调 用 的 所 以 在 一 切 工 作 的 开 始 需 要 实 例 化 一 个 session 对 象, 实 现 这 个 功 能 的 类 是 BaseHibernateDAO, 代 码 如 下 所 示 : package hibernateconfig; import org.hibernate.session; /** * Data access object (DAO) for domain model * @author MyEclipse Persistence Tools public class BaseHibernateDAO implements IBaseHibernateDAO { // 从 session 工 厂 中 获 得 一 个 session public Session getsession() { return HibernateSessionFactory.getSession(); 这 类 仅 包 含 一 个 方 法 getsession, 方 法 中 也 仅 含 有 一 条 语 句, 那 就 是 通 过 session 工 厂 获 得 一 个 session 然 而 这 是 所 有 DAO 需 要 的 一 个 操 作, 因 此 所 有 的 DAO 可 以 通 过 继 承 它 从 而 减 少 代 码 编 写 量 Hbm.xml 描 述 表 结 构 信 息 的 配 置 文 件 数 据 库 中 的 一 张 表 都 具 有 列 名 等 信 息, 这 些 信 息 通 过 Hibernate 的 工 具 可 以 逆 向 工 程 为 一 个 描 述 性 的 配 置 文 件, 一 般 以 hbm.xml 结 尾 对 于 stu_basic_info 这 张 表 所 产 生 的 hbm.xml 文 件 内 容 如 下 所 示 : <?xml version="1.0" encoding="utf-8"?> <!-- Hibernate DTD 定 义 从 这 里 可 以 看 出 Hibernate 的 版 本 --> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools --> <!-- 根 元 素 --> <hibernate-mapping> <!-- class name 属 性 代 表 stu_basic_info 表 逆 向 工 程 后 生 成 的 JavaBean 文 件 路 径 table 是 实 际 表 名 --> <class name="hibernateconfig.stubasicinfo" table="stu_basic_info" catalog="testdb"> <!-- 描 述 表 中 的 主 键 name 是 StuBasicInfo 属 性 名 称 type 是 对 应 的 java 数 据 类 型 --> <id name="stuid" type="java.lang.string"> <!-- column name 属 性 代 表 实 际 列 名 length 代 码 长 度 --> <column name="stu_id" length="10" /> <generator class="assigned" /> </id> <!-- 学 生 姓 名 属 性 描 述 --> <property name="stuname" type="java.lang.string"> <column name="stu_name" length="20" /> </property> <!-- 学 生 性 别 描 述 --> <property name="gendar" type="java.lang.string"> <column name="gendar" length="2" /> </property> <!-- 和 其 它 表 的 引 用 关 系 --> <set name="sturelationcourses" inverse="true"> <key> <column name="stu_id" length="10" /> </key> <one-to-many class="hibernateconfig.sturelationcourse" /> </set> </class> </hibernate-mapping> 为 了 便 于 理 解 这 个 配 置 文 件 中 给 予 了 中 文 注 释, 需 要 解 释 的 是 对 于 不 同 的 表 它 的 hbm.xml 文 件 不 总 是 这 样, 在 结 构 和 内 容 上 会 有 所 差 异 需 要 特 别 注 意 的 是 在 本 示 例 中 并 没 有 对 产 生 一 个 StuRelationCourse 的 JavaBean, 因 为 本 节 的 示 例 不 需 要 使 用 到 stu_relation_couse 这 个 表 但 是 此 处 却 引 用 了 一 个 不 存 在 的 类, 这 样 会 在 运 行 时 出 现 异 常, 所 以 建 议 将 set 元 素 的 所 有 内 容 删 除 删 除 后 的 hbm.xml 文 件 如 下 所 示 : <?xml version="1.0" encoding="utf-8"?> <!-- Hibernate DTD 定 义 从 这 里 可 以 刚 才 Hibernate 的 版 本 --> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools -->

<!-- 根 元 素 --> <hibernate-mapping> <!-- class name 属 性 代 表 stu_basic_info 表 逆 向 工 程 后 生 成 的 JavaBean 文 件 路 径 table 是 实 际 表 名 --> <class name="hibernateconfig.stubasicinfo" table="stu_basic_info" catalog="testdb"> <!-- 描 述 表 中 的 主 键 name 是 StuBasicInfo 属 性 名 称 type 是 对 应 的 java 数 据 类 型 --> <id name="stuid" type="java.lang.string"> <!-- column name 属 性 代 表 实 际 列 名 length 代 码 长 度 --> <column name="stu_id" length="10" /> <generator class="assigned" /> </id> <!-- 学 生 姓 名 属 性 描 述 --> <property name="stuname" type="java.lang.string"> <column name="stu_name" length="20" /> </property> <!-- 学 生 性 别 描 述 --> <property name="gendar" type="java.lang.string"> <column name="gendar" length="2" /> </property> </class> </hibernate-mapping> JavaBean:ORM 中 的 O JavaBean 可 以 简 单 的 认 为 是 一 个 具 有 缺 省 构 造 函 数, 属 性 都 有 setter 和 getter 方 法 的 一 个 Java 类 本 质 上 它 是 一 个 普 通 的 Java 类 在 J2EE 中, 它 一 般 充 当 数 据 传 输 对 象 (DTO) 的 角 色 对 于 Java 程 序 员 而 言, 使 用 Java 类 访 问 数 据 比 使 用 sql 语 句 访 问 数 据 更 加 自 然 通 过 MyEclipse 的 自 带 工 具 可 以 自 动 生 成 一 张 关 系 表 所 对 应 的 JavaBean, 比 如 这 里 的 stu_basic_info 所 对 应 的 stubasicinfo 代 码 如 下 所 示 : package hibernateconfig; import java.util.hashset; import java.util.set; /** * StuBasicInfo generated by MyEclipse Persistence Tools // 自 动 生 成 的 JavaBean public class StuBasicInfo implements java.io.serializable { // Fields, 下 面 属 性 的 写 法 和 实 际 的 列 名 写 法 习 惯 是 不 一 样 的, 它 们 一 般 使 用 Java 变 量 的 命 名 规 则 // 学 号 private String stuid; // 姓 名

private String stuname; // 性 别 private String gendar; // 选 课 关 系 表 private Set sturelationcourses = new HashSet(0); // Constructors /** default constructor public StuBasicInfo() { /** minimal constructor public StuBasicInfo(String stuid) { this.stuid = stuid; /** full constructor public StuBasicInfo(String stuid, String stuname, String gendar, Set sturelationcourses) { this.stuid = stuid; this.stuname = stuname; this.gendar = gendar; this.sturelationcourses = sturelationcourses; // Property accessors public String getstuid() { return this.stuid; public void setstuid(string stuid) { this.stuid = stuid; public String getstuname() { return this.stuname; public void setstuname(string stuname) { this.stuname = stuname; public String getgendar() { return this.gendar; public void setgendar(string gendar) { this.gendar = gendar;

public Set getsturelationcourses() { return this.sturelationcourses; public void setsturelationcourses(set sturelationcourses) { this.sturelationcourses = sturelationcourses; 对 于 这 个 自 动 生 成 的 JavaBean 需 要 解 释 的 是 它 的 属 性 对 应 着 表 中 的 列, 但 是 命 名 采 用 了 Java 变 量 的 命 名 风 格 且 它 的 名 称 必 须 与 hbm.xml 文 件 中 相 关 配 置 保 持 一 致 Hibernate.cfg.xml 数 据 库 连 接 信 息 配 置 文 件 在 为 hibernate 这 个 工 程 添 加 Hibernate 能 力 的 时 候 便 有 一 项 是 配 置 这 个 文 件 的 它 的 名 称 可 以 更 改, 而 且 一 个 工 程 中 可 以 有 多 个 cfg.xml 文 件 在 hibernate 这 个 工 程 中 这 个 文 件 的 代 码 如 下 所 示 : <?xml version='1.0' encoding='utf-8'?> <!-- Hibernate 的 DTD 定 义 从 这 里 可 以 看 出 Hibernate 的 版 本 --> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> --> <!-- Generated by MyEclipse Hibernate Tools. 一 个 Hibernate 的 配 置 开 始 <hibernate-configuration> <session-factory> <!-- 连 接 数 据 库 使 用 的 用 户 名 --> <property name="connection.username">test</property> <!-- 连 接 数 据 的 url 地 址 --> <property name="connection.url"> jdbc:mysql://localhost:3305/testdb </property> <!-- 数 据 库 方 言 --> <property name="dialect"> org.hibernate.dialect.mysqldialect </property> <!-- profile 文 件 名 配 置 --> <property name="myeclipse.connection.profile">testdb</property> <!-- 连 接 数 据 库 的 密 码 --> <property name="connection.password">test</property> <!-- 驱 动 类 路 径 --> <property name="connection.driver_class"> com.mysql.jdbc.driver </property> <!-- 表 映 射 文 件 列 表, 这 里 一 般 是 多 个 --> <mapping resource="hibernateconfig/stubasicinfo.hbm.xml"></mapping>

</session-factory> </hibernate-configuration> 通 过 这 个 配 置 文 件 可 以 看 到, 它 包 含 的 信 息 基 本 包 括 : 数 据 库 连 接 地 址, 数 据 库 用 户 名, 密 码, 驱 动 类 路 径,hbm.xml 文 件 列 表 Hibernate 通 过 Configure 类 对 这 些 信 息 进 行 组 织 并 且 实 例 化 出 一 个 SessionFactory 对 象 到 此 所 有 能 够 自 动 生 成 的 代 码 和 前 期 工 作 都 已 经 就 绪, 接 下 来 的 就 是 需 要 手 工 编 写 业 务 逻 辑 代 码 在 test 包 下 新 建 一 个 类 命 名 为 GetStuInfoServ 这 个 类 的 作 用 是 调 用 上 面 生 成 的 DAO 访 问 数 据 库 中 并 将 结 果 显 示 在 控 制 台, 代 码 如 下 所 示 : package test; import java.util.iterator; import java.util.list; import hibernateconfig.stubasicinfo; import hibernateconfig.stubasicinfodao; /** * 得 到 学 生 的 所 有 信 息 * @author Administrator * public class GetStuInfoServ { public static void main(string[] args) { // 实 例 化 一 个 DAO StuBasicInfoDAO dao=new StuBasicInfoDAO(); // 调 用 DAO 提 供 的 API, 得 出 所 有 的 学 生 基 本 信 息 对 象 List objlist=dao.findall(); // 迭 代 的 获 得 所 有 每 一 个 学 生 基 本 信 息 对 象 for (Iterator iter = objlist.iterator(); iter.hasnext();) { StuBasicInfo student = (StuBasicInfo) iter.next(); // 输 出 学 生 基 本 信 息 对 象 中 的 内 容 printresult(student); // 在 控 制 台 输 出 学 生 基 本 信 息 private static void printresult(stubasicinfo student) { System.out.println(" 学 号 :"+student.getstuid()+ " 姓 名 :"+student.getstuname()+ " 性 别 :"+student.getgendar());

这 个 类 的 逻 辑 非 常 的 简 单, 首 先 实 例 化 一 个 DAO 然 后 使 用 DAO 封 装 好 的 API 将 所 有 的 学 生 信 息 以 对 象 形 式 存 储 在 List 容 器 中, 最 后 依 次 将 这 个 List 中 的 元 素 取 出 并 在 控 制 台 打 印 打 印 结 果 如 下 所 示 : log4j:warn No appenders could be found for logger (hibernateconfig.stubasicinfodao). log4j:warn Please initialize the log4j system properly. 学 号 :A0111 姓 名 : 张 三 性 别 : 男 学 号 :A0112 姓 名 : 李 四 性 别 : 男 学 号 :A0113 姓 名 : 王 艳 性 别 : 女 结 果 如 我 们 所 期 望 但 是 发 现 有 log4j 警 告 取 出 这 个 警 告 的 办 法 是 在 hibernate 这 个 工 程 目 录 下 编 写 一 个 简 单 的 log4j.properties 文 件 其 内 容 如 下 所 示 : # 在 stdout 输 出 错 误 信 息, 这 样 调 试 信 息 将 不 会 输 出 log4j.rootlogger=error, stdout # 定 义 log4j 的 显 示 方 式 log4j.appender.stdout=org.apache.log4j.consoleappender // 使 用 模 式 匹 配 log4j.appender.stdout.layout=org.apache.log4j.patternlayout #log4j 的 输 出 日 期 格 式 log4j.appender.stdout.layout.conversionpattern=[%-5p]%d{yyyy-mm-dd HH:mm:ss%c - %m%n 这 段 配 置 的 说 明 已 给 出 了 中 文 注 释, 关 于 log4j 更 加 详 细 的 配 置 可 以 在 Apache 的 官 方 网 站 上 查 询 到 3.5 Hiberate 的 映 射 配 置 在 3.4 节 中 通 过 一 个 实 例 介 绍 了 Hibernate 一 些 基 本 知 识, 同 时 读 者 可 以 了 解 到 一 张 存 在 数 据 库 中 的 关 系 表, 需 要 被 逆 向 工 程 为 一 个 xml 格 式 的 映 射 文 件, 一 般 以 hbm.xml 结 尾, 本 节 将 详 细 的 讲 述 与 映 射 相 关 的 基 本 知 识 下 面 的 实 例 仍 然 基 于 3.4 节 中 创 建 的 hibernate 工 程 3.3.1 主 键 生 成 策 略 在 MyEclipse 中 打 开 3.4 节 所 创 建 的 hibernate 工 程 下 的 StuBasicInfo.hbm.xml 文 件, 如 下 所 示 : <?xml version="1.0" encoding="utf-8"?> <!-- Hibernate DTD 定 义 从 这 里 可 以 刚 才 Hibernate 的 版 本 --> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools --> <!-- 根 元 素 -->

<hibernate-mapping> <!-- class name 属 性 代 表 stu_basic_info 表 逆 向 工 程 后 生 成 的 JavaBean 文 件 路 径 table 是 实 际 表 名 --> <class name="hibernateconfig.stubasicinfo" table="stu_basic_info" catalog="testdb"> <!-- 描 述 表 中 的 主 键 name 是 StuBasicInfo 属 性 名 称 type 是 对 应 的 java 数 据 类 型 --> <id name="stuid" type="java.lang.string"> <!-- column name 属 性 代 表 实 际 列 名 length 代 码 长 度 --> <column name="stu_id" length="10" /> <generator class="assigned" /> </id> <!-- 学 生 姓 名 属 性 描 述 --> <property name="stuname" type="java.lang.string"> <column name="stu_name" length="20" /> </property> <!-- 学 生 性 别 描 述 --> <property name="gendar" type="java.lang.string"> <column name="gendar" length="2" /> </property> </class> </hibernate-mapping> 黑 色 加 粗 部 分 是 一 个 id 元 素, 它 描 述 了 表 的 主 键 信 息, 通 过 这 个 描 述 可 以 了 解 到 stu_basic_info 这 张 表 的 主 键 是 stu_id, 长 度 是 10, 类 型 是 字 符 型 然 而 我 们 还 看 到 一 个 名 为 generator 的 元 素 那 么 它 具 有 什 么 样 的 含 义 呢? generator 是 主 键 生 成 器, 它 负 责 生 成 表 的 主 键, 生 成 策 略 依 据 class 属 性 的 值 Hibernate 通 常 具 有 以 下 几 种 主 键 生 成 器 assigned: 如 果 没 有 对 一 个 主 键 没 有 明 确 指 定 主 键 生 成 策 略, 一 般 就 会 使 用 这 个 默 认 的 策 略, 它 实 际 上 可 以 看 成 是 无 策 略 increment: 自 动 增 长 策 略, 针 对 的 数 据 类 型 是 short,int. 或 者 long. identity: 如 果 数 据 库 支 持 自 动 增 长 列, 比 如 MySQL, 则 可 以 通 过 这 个 策 略 生 成 自 动 增 长 主 键, 针 对 的 数 据 类 型 是 short,int. 或 者 long. sequence: 如 果 数 据 库 支 持 sequence 增 长 方 式, 比 如 Oracle, 则 可 以 通 过 这 个 策 略 生 成 自 动 增 长 主 键, 针 对 的 数 据 类 型 是 short,int. 或 者 long. uuid: 这 种 是 针 对 字 符 型 的 主 键 生 成 策 略 uuid 是 一 个 算 法 名 称 所 谓 的 主 键 生 成 策 略 一 般 只 在 插 入 一 条 记 录 的 时 候 才 有 意 义, 使 用 以 上 的 策 略 (assigned 除 外 ) 后, 如 果 需 要 往 表 中 插 入 一 条 记 录, 用 户 不 需 要 关 心 如 何 生 成 主 键 的 值,Hibernate 根 据 指 定 的 策 略 自 动 生 成 一 个 唯 一 的 值 然 而 对 于 stu_basic_info 这 张 表 中 的 主 键 stu_id, 由 于 它 代 表 的 是 有 具 体 含 义 的 学 号, 所 以 不 能 使 用 任 何 主 键 生 成 策 略 ( 所 以 是 assigned). 3.3.3 各 种 集 合 映 射 的 配 置 在 3.4 节 中 为 了 测 试 的 方 便 对 StuBasicInfo.hbm.xml 文 件 删 除 了 一 段 配 置 信 息, 删 除 的 配 置 片 段 如 下 所 示 : <set name="sturelationcourses" inverse="true">

<key> </key> <column name="stu_id" length="10" /> <one-to-many class="hibernateconfig.sturelationcourse" /> </set> 这 段 配 置 信 息 代 表 了 Hibernate 中 集 合 映 射 的 配 置, 这 里 的 元 素 名 称 set 和 java 中 的 Set 在 概 念 上 是 一 致 的, 它 是 指 不 能 重 复 且 没 有 顺 序 的 一 类 对 象 的 集 合 Hibenate 中 的 集 合 映 射 包 括 List,Set,Bag 等, 它 们 在 配 置 上 都 是 类 似 的, 这 里 仅 以 set 为 例 介 绍 集 合 映 射 的 配 置 下 面 以 字 母 顺 序 介 绍 set 元 素 的 各 个 属 性 含 义 : access: 访 问 策 略 batch-size: 如 果 使 用 延 迟 加 载, 它 表 示 一 次 读 取 数 据 的 数 量 所 谓 延 迟 加 载 是 指,Hibernate 在 从 数 据 库 中 加 载 数 据 时 候, 并 不 是 在 初 始 化 的 时 候 立 即 一 次 性 的 将 所 有 数 据 加 载 到 系 统 中, 而 是 在 使 用 的 时 候 进 行 加 载, 这 种 情 况 比 较 适 合 与 数 据 量 比 较 多 的 情 况 下 catalog: 数 据 库 的 目 录 名, 一 般 MySQL 数 据 库 会 使 用 到 这 个 属 性 cascade: 级 联 策 略 一 般 是 由 于 一 个 表 有 被 其 它 表 外 键 引 用, 被 引 用 表 的 修 改 往 往 需 要 考 虑 引 用 表 是 否 也 要 做 相 应 的 修 改, 以 保 持 数 据 的 完 整 性 这 个 属 性 有 5 个 值 :all 对 于 所 有 的 操 作 都 必 须 进 行 级 联 操 作 None 对 于 所 有 的 操 作 不 进 行 如 何 级 联 操 作,save-update 保 存 和 更 新 操 作 时 候 才 进 行 级 联 操 作 delete : 在 执 行 删 除 操 作 时 进 行 级 联 操 作, all-delete-orphan: 引 用 关 系 被 删 除 后 进 行 级 联 删 除 fetch: 预 先 抓 取 策 略 所 使 用 的 抓 取 方 式 有 两 种 选 择 一 种 是 join 方 式 外 连 接 抓 取 另 一 种 是 select 方 式 抓 取, 预 先 抓 取 是 相 当 于 延 迟 加 载 而 言 inverse: 是 否 控 制 关 联 关 系 lazy: 是 否 采 用 延 迟 加 载, 值 为 true 的 时 候 进 行 延 迟 加 载 mutable: 被 关 联 的 对 象 是 否 可 以 修 改 name: 属 性 名 称 order-by: 排 序 规 则 schema: 与 catalog 类 似 的 一 个 属 性, 一 般 但 数 据 库 是 Oracle 的 时 候 会 使 用 到 这 个 属 性 subselect: 设 置 一 个 子 查 询, 它 接 受 一 个 SQL 表 达 式 table: 数 据 库 表 名 称 where: 过 滤 条 件, 对 于 任 何 查 询 都 会 附 加 此 过 滤 条 件 对 于 上 面 所 有 的 属 性 一 般 都 有 默 认 设 置, 在 实 际 配 置 时 候 需 要 修 改 默 认 配 置 的 才 需 要 明 确 的 书 写, 否 则 保 持 默 认 即 可 对 于 其 它 类 型 的 集 合 映 射 配 置 都 非 常 类 似, 这 里 不 再 过 多 介 绍 3.3.4 关 系 映 射 的 配 置 存 在 关 系 数 据 库 中 的 表 并 不 是 毫 无 关 联 的 存 在 的, 它 们 可 能 存 在 互 相 参 照 的 情 况 表 与 表 之 间 便 会 因 此 产 生 联 系, 表 之 间 的 关 联 关 系 可 以 总 结 为 M:N,M 和 N 都 可 以 是 1 到 任 意 本 小 节 将 介 绍 如 何 在 Hibernate 配 置 文 件 中 配 置 这 些 关 联 关 系, 举 其 中 一 例 讲 解 如 下 : 3.3.4.1 一 对 一 关 联 一 对 一 的 关 系 在 现 实 世 界 中 无 处 不 在, 比 如 绝 大 多 少 高 校 一 个 学 生 只 能 有 一

张 毕 业 证 书, 为 了 测 试 一 对 一 的 关 联 需 要 在 本 章 开 始 创 建 的 testdb 数 据 库 中 新 建 一 张 表, 名 称 为 毕 业 证 书 表 (diploma), 建 表 语 句 如 下 所 示 create table diploma( id int primary key, stu_id varchar(10) unique, diploma_info varchar(100), constraint fk_diploma foreign key (stu_id) references stu_basic_info(stu_id) ); 在 SQLyog 中 运 行 上 面 这 个 sql 语 句 将 创 建 表 diploma, 它 的 主 键 是 id, 用 来 唯 一 标 识 一 张 毕 业 证 书, 外 键 是 stu_id, 它 是 一 个 唯 一 外 键, 因 为 一 张 证 书 只 能 对 应 一 个 学 生, 此 外 还 有 一 个 用 来 描 述 毕 业 证 书 信 息 的 列 diploma_info 为 这 个 表 输 入 测 试 数 据, 输 入 测 试 数 据 后 的 表 diploma 如 下 图 3-36 所 示 : 图 3-36 diploma 表 这 样 学 生 和 毕 业 证 书 就 建 立 了 一 对 一 的 关 联 由 于 新 增 了 数 据 库 表, 所 以 对 于 需 要 为 这 张 表 进 行 Hibernate 逆 向 工 程, 由 于 关 联 到 stu_basic_info 这 张 表, 使 用 前 面 逆 向 工 程 的 办 法 针 对 表 stu_basic_info 打 开 如 图 3-37 所 示 的 对 话 框 : 图 3-37 重 新 对 stu_basic_info 逆 向 工 程 对 话 框 与 前 面 的 做 法 不 同 的 是, 这 里 不 要 直 接 单 击 Finish 按 钮, 而 是 单 击 Next 按 钮, 进 入 下 一 步 的 对 话 框, 如 图 3-38 所 示 :

所 示 : 图 3-38 配 置 对 话 框 这 里 暂 时 不 需 要 做 任 何 修 改 和 配 置 直 接 单 击 Next 按 钮 进 入 下 一 步, 如 图 3-39 图 3-39 关 联 选 择 对 话 框 一 从 这 个 对 话 框 中 可 以 看 到 stu_basic_info 这 张 表, 它 表 示 当 前 逆 向 工 程 的 表 集 合, 这 里 只 有 一 张 表, 因 为 开 始 我 们 只 选 择 了 这 张 表, 勾 选 Include referenced tables (A-)B) 和 Include referencing tables (A<-B), 勾 选 完 成 后 结 果 如 图 3-40 所 示 :

图 3-40 关 联 选 择 对 话 框 二 可 以 看 到 相 关 的 表 都 被 选 中, 由 于 testdb 中 所 有 的 表 都 彼 此 相 关 所 以 这 里 的 表 集 合 实 际 上 是 testdb 中 的 所 有 表, 这 时 候 单 击 Finish 按 钮 将 完 成 逆 向 工 程 更 新 后 的 StuBasicInfo.hbm.xml 文 件 如 下 所 示 : <?xml version="1.0" encoding="utf-8"?> <!-- Hibernate DTD 定 义 从 这 里 可 以 刚 才 Hibernate 的 版 本 --> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools --> <!-- 根 元 素 --> <hibernate-mapping> <!-- class name 属 性 代 表 stu_basic_info 表 逆 向 工 程 后 生 成 的 JavaBean 文 件 路 径 table 是 实 际 表 名 --> <class name="hibernateconfig.stubasicinfo" table="stu_basic_info" catalog="testdb"> <!-- 描 述 表 中 的 主 键 name 是 StuBasicInfo 属 性 名 称 type 是 对 应 的 java 数 据 类 型 --> <id name="stuid" type="java.lang.string"> <!-- column name 属 性 代 表 实 际 列 名 length 代 码 长 度 --> <column name="stu_id" length="10" /> <generator class="assigned" /> </id> <!-- 学 生 姓 名 属 性 描 述 --> <property name="stuname" type="java.lang.string"> <column name="stu_name" length="20" /> </property> <!-- 学 生 性 别 描 述 --> <property name="gendar" type="java.lang.string"> <column name="gendar" length="2" />

</property> <!-- 由 外 键 所 引 起 的 一 对 多 关 联 --> <set name="sturelationcourses" inverse="true"> <key> <column name="stu_id" length="10" /> </key> <one-to-many class="hibernateconfig.sturelationcourse" /> </set> <!-- 由 外 键 所 引 起 的 一 对 多 关 联, 这 里 实 际 上 是 一 对 一 关 联, 一 对 一 是 一 个 特 殊 的 一 对 多 关 联 --> <set name="diplomas" inverse="true"> <key> <column name="stu_id" length="10" unique="true" /> </key> <one-to-many class="hibernateconfig.diploma" /> </set> </class> </hibernate-mapping> 黑 体 部 分 是 新 增 的 内 容, 它 将 毕 业 证 书 表 (diplomas) 对 stu_id 的 外 键 引 用 反 应 了 出 来 新 创 建 的 diplomas.hbm.xml 文 件 如 下 所 示 : <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools --> <hibernate-mapping> <!-- 毕 业 证 书 表 配 置 文 件 --> <class name="hibernateconfig.diploma" table="diploma" catalog="testdb"> <!-- 主 键 --> <id name="id" type="java.lang.integer"> <column name="id" /> <generator class="assigned" /> </id> <!-- 唯 一 外 键 的 方 式 产 生 的 一 对 一 关 联 --> <many-to-one name="stubasicinfo" class="hibernateconfig.stubasicinfo" fetch="select"> <column name="stu_id" length="10" unique="true" /> </many-to-one> <!-- 证 书 的 其 它 信 息 --> <property name="diplomainfo" type="java.lang.string"> <column name="diploma_info" length="100" /> </property> </class> </hibernate-mapping> 上 面 配 置 信 息 中 的 黑 体 部 分 是 使 用 <many-to-one> 体 现 唯 一 外 键 方 式 的 一 对

一 关 联 下 面 来 看 下 更 新 后 的 StuBasicInfo.java 程 序 代 码 如 下 所 示 : package hibernateconfig; import java.util.hashset; import java.util.set; /** * StuBasicInfo generated by MyEclipse Persistence Tools * 由 学 生 基 本 信 息 表 逆 向 工 程 所 产 生 的 POJO public class StuBasicInfo implements java.io.serializable { // Fields // 学 号 private String stuid; // 姓 名 private String stuname; // 性 别 private String gendar; // 选 课 关 系 private Set sturelationcourses = new HashSet(0); // 毕 业 证 书 private Set diplomas = new HashSet(0); // Constructors /** default constructor public StuBasicInfo() { /** minimal constructor public StuBasicInfo(String stuid) { this.stuid = stuid; /** full constructor public StuBasicInfo(String stuid, String stuname, String gendar, Set sturelationcourses, Set diplomas) { this.stuid = stuid; this.stuname = stuname; this.gendar = gendar; this.sturelationcourses = sturelationcourses; this.diplomas = diplomas; // Property accessors //getter 和 setter 方 法 区 public String getstuid() { return this.stuid;

public void setstuid(string stuid) { this.stuid = stuid; public String getstuname() { return this.stuname; public void setstuname(string stuname) { this.stuname = stuname; public String getgendar() { return this.gendar; public void setgendar(string gendar) { this.gendar = gendar; public Set getsturelationcourses() { return this.sturelationcourses; public void setsturelationcourses(set sturelationcourses) { this.sturelationcourses = sturelationcourses; public Set getdiplomas() { return this.diplomas; public void setdiplomas(set diplomas) { this.diplomas = diplomas; 这 个 类 由 hibernate 逆 向 工 程 所 产 生 一 个 制 品, 它 对 应 数 据 库 中 的 stu_basic_info 表, 一 般 类 中 的 一 个 属 性 对 应 表 中 的 一 个 列, 但 这 里 有 两 个 特 殊 的 属 性 如 黑 体 所 示, 它 们 并 不 是 指 stu_basci_info 表 中 的 列, 事 实 上 它 们 是 在 体 现 一 种 关 联, 通 过 这 两 个 属 性 可 以 知 道 一 个 学 生 对 应 X 张 毕 业 证 书, 和 Y 个 选 课 关 系 X 和 Y 是 0 到 任 意 具 体 值 从 这 个 类 中 是 无 法 体 现 的 但 可 以 肯 定 的 是 X 一 定 为 1 或 者 0. 这 是 由 于 学 生 和 毕 业 证 书 是 一 一 对 应 的 关 系 所 决 定 的 不 过 在 Diploma.java 中 这 个 关 联 关 系 要 显 得 明 朗 的 多, 代 码 如 下 所 示 : package hibernateconfig; /**

* Diploma generated by MyEclipse Persistence Tools // 毕 业 证 书 对 应 的 JavaBean public class Diploma implements java.io.serializable { // Fields // 唯 一 表 示 一 张 毕 业 证 书 的 主 键 private Integer id; // 学 生 基 本 信 息 private StuBasicInfo stubasicinfo; // 证 书 基 本 信 息 private String diplomainfo; // Constructors /** default constructor public Diploma() { /** minimal constructor public Diploma(Integer id) { this.id = id; /** full constructor public Diploma(Integer id, StuBasicInfo stubasicinfo, String diplomainfo) { this.id = id; this.stubasicinfo = stubasicinfo; this.diplomainfo = diplomainfo; // Property accessors public Integer getid() { return this.id; public void setid(integer id) { this.id = id; public StuBasicInfo getstubasicinfo() { return this.stubasicinfo; public void setstubasicinfo(stubasicinfo stubasicinfo) { this.stubasicinfo = stubasicinfo; public String getdiplomainfo() {

return this.diplomainfo; public void setdiplomainfo(string diplomainfo) { this.diplomainfo = diplomainfo; 在 这 个 类 中,Diploma 直 接 拥 有 一 个 对 StuBasicInfo 对 象 的 引 用, 所 以 可 以 明 显 的 看 出 一 张 毕 业 证 书 对 应 一 个 学 生 有 了 上 面 的 配 置 基 础, 那 么 现 在 要 通 过 一 个 学 生 去 获 取 毕 业 证 书 信 息 该 如 何 去 做 呢? 可 能 你 会 这 样 编 写 代 码 : package test; import java.util.list; import hibernateconfig.diploma; import hibernateconfig.diplomadao; import hibernateconfig.stubasicinfo; import hibernateconfig.stubasicinfodao; /** * 得 到 学 生 的 相 关 信 息 * @author Administrator * public class GetStuInfoServ { public static void main(string[] args) { // 通 过 StuBasciInfoDAO 取 得 一 个 学 生 姓 名 StuBasicInfoDAO studentdao=new StuBasicInfoDAO(); StuBasicInfo student=studentdao.findbyid("a0113"); String name=student.getstuname();// 学 生 姓 名 // 通 过 DiplomaDAO 取 得 学 生 的 毕 业 证 书 信 息 DiplomaDAO diplomadao=new DiplomaDAO(); List diplomalist=diplomadao.findbyproperty("stubasicinfo", student);// 通 过 属 性 查 找 对 象 Diploma diploma=(diploma)diplomalist.get(0);// 由 于 是 一 一 对 应, 所 以 list 中 只 会 有 一 个 元 素 System.out.println(name+":"+diploma.getDiplomaInfo());// 输 出 信 息

这 段 代 码 使 用 的 算 法 比 较 简 单, 由 于 是 跨 表 查 询, 所 以 先 使 用 StuBasicInfoDAO 从 学 生 基 本 信 息 表 中 取 出 姓 名 信 息, 然 后 再 实 例 化 一 个 DiplomaDAO 对 象 通 过 StuBasicInfoDAO 查 询 到 的 学 生 信 息 去 查 找 这 个 学 生 在 Diploma 中 的 证 书 信 息 最 后 打 印 出 来 的 结 果 自 然 也 是 正 确 的 不 过 在 这 种 场 合 下, 这 种 做 法 显 然 是 多 此 一 举, 改 进 后 的 代 码 如 下 所 示 : package test; import java.util.iterator; import java.util.set; import hibernateconfig.diploma; import hibernateconfig.stubasicinfo; import hibernateconfig.stubasicinfodao; /** * 得 到 学 生 的 相 关 信 息 * @author Administrator * public class GetStuInfoServ { public static void main(string[] args) { // 通 过 StuBasciInfoDAO 取 得 一 个 学 生 姓 名 StuBasicInfoDAO studentdao=new StuBasicInfoDAO(); StuBasicInfo student=studentdao.findbyid("a0113"); String name=student.getstuname();// 学 生 姓 名 Set diplomaset=student.getdiplomas();// 取 得 证 书 集 合 对 象, 事 实 上 只 有 一 个 元 素 for (Iterator iter = diplomaset.iterator(); iter.hasnext();) { Diploma diploma = (Diploma) iter.next(); System.out.println(name+":"+diploma.getDiplomaInfo());// 输 出 信 息 改 进 后 的 代 码, 充 分 利 用 了 Hibernate 的 特 性, 只 实 例 化 一 个 DAO 的 情 况 下 直 接 级 联 查 询 它 所 关 联 的 表, 配 合 一 定 的 加 载 策 略, 这 种 方 式 将 是 最 自 然, 方 便, 高 效 的, 因 此 是 推 荐 的 做 法 使 用 同 样 的 方 式 可 以 通 过 Diploma 对 象 获 得 一 个 学 生 的 基 本 信 息 这 体 现 了 Hibernate 关 系 映 射 中 的 双 向 性 质 通 过 修 改 配 置 可 以 将 双 向 映 射 变 为 单 向 映 射, 所 谓 单 向 映 射 是 指 只 能 从 A 端 级 联 访 问 到 B 端, 而 不 能 从 B 端 访 问 到 A 端 此 外 还 需 要 说 明 的 是 本 实 例 中 的 一 对 一 关 联 是 指 基 于 唯 一 外 键 方 式, 另 外 还 可 以 是 基 于 主 键 相 等 方 式 Hibernate 中 的 关 系 映 射 除 了 一 对 一 关 联, 还 有 一 对 多 关 联, 多 对 一 关 联, 多 多 多 关 联, 它 们 也 都 有 单 向 和 双 向 性 质 关 于 它 们 的 配 置 基 本 类 似 于 一 对 一 关 联 这 里 不 再 详 细 讲 解, 读 者 可 以 查 看 专 门 的 Hibernate 书 籍