...

電子カルテ共有システムの実現 ~デザインパターンと Web

by user

on
Category: Documents
50

views

Report

Comments

Transcript

電子カルテ共有システムの実現 ~デザインパターンと Web
平成 17 年度社会工学類卒業論文
電子カルテ共有システムの実現
~デザインパターンと Web サービスの適用~
1.目
学籍番号
200201050
主専攻
経営工学主専攻
氏名
村田 洋
指導教員
佐藤 亮 教授
的
本研究では医療機関間でカルテ情報を共有するための仕組みを明らかにし、情報共有
を実現する新システムの提案を行う。また情報を共有する技術として Web サービスを適
用し、デザインパターンを導入することでシステムの保守・再利用性の向上を図る。こ
のシステムの構築によって医療機関間でのカルテ情報の連携を確かめることを目的とす
る。
2.特
色
本研究では UML を用いて分析・設計を行い、Windows 環境下以外でも開発・保守が
可能な Java プラットフォーム上で電子カルテ共有システムを構築した。またカルテ情報
を共有する技術として Web サービスを適用し、データモデルには医療界標準規格になり
つつある MML と ICD-10 を一部採用した。更にプログラムの保守・再利用性の向上を図
るためにデザインパターンを導入し、医療機関間でのカルテ情報の共有を実現した。
3.結
論
本研究では Web サービスを用いた電子カルテ共有システムを構築し、医療機関間でカ
ルテ情報を共有するための仕組みを明らかにした。またデータモデルの一部を医療界標
準規格になりつつある MML と ICD-10 に準拠させたことで、将来の医療界に適用可能な
システムを開発することが出来た。更にデザインパターンを採用したことにより、プロ
グラムの保守・再利用性を高めることが出来た。これは今後の保守作業時の時間を短縮
させ、コストパフォーマンスの改善を図ることができたことを示す。
平成 17 年度
卒業論文
電子カルテ共有システムの実現
~デザインパターンと Web サービスの適用~
筑波大学 第三学群 社会工学類 経営工学主専攻
学籍番号
村田
担当指導教官
200201050
洋
佐藤 亮
平成 18 年 1 月 25 日
教授
1.
序論 ..................................................................................................................................3
2.
医療界の現状....................................................................................................................4
2.1.
2.1.1.
電子カルテシステム ..........................................................................................4
2.1.2.
オーダリングシステム.......................................................................................5
2.2.
3.
4.
6.
医療システムを取り囲む環境 ...................................................................................5
2.2.1.
同種システムの混在 ..........................................................................................5
2.2.2.
医療情報の標準化..............................................................................................5
問題の定義とシステムの提案 ........................................................................................10
3.1.
問題の定義 ..............................................................................................................10
3.2.
電子カルテ共有システムの提案と意義 ..................................................................10
Web サービス.................................................................................................................11
4.1.
Web サービスとは ..................................................................................................11
4.2.
Web アプリケーションと Web サービス................................................................11
4.3.
Web サービスの要素技術........................................................................................12
4.3.1.
SOAP(Simple Object Access Protocol) .....................................................12
4.3.2.
WSDL(Web Services Description Language) ..........................................13
4.3.3.
UDDI(Universal Description, Discovery, and Integration) ....................13
4.4.
5.
医療界で導入されているシステム............................................................................4
Apache Axis を用いた Web サービス.....................................................................14
デザインパターン...........................................................................................................15
5.1.
デザインパターンとは ............................................................................................15
5.2.
デザインパターンの意義 ........................................................................................15
5.3.
デザインパターンの種類 ........................................................................................15
5.4.
Iterator パターンについて .....................................................................................16
電子カルテ共有システムの分析と設計..........................................................................18
6.1.
UML とは ...............................................................................................................18
6.1.1.
ユースケース図................................................................................................18
6.1.2.
ユースケース記述............................................................................................18
6.1.3.
シーケンス図 ...................................................................................................19
6.1.4.
クラス図...........................................................................................................20
6.2.
ドメイン分析(設計) ............................................................................................21
6.2.1.
用語の定義.......................................................................................................21
6.2.2.
ユースケース図およびユースケース記述........................................................22
6.2.3.
シーケンス図 ...................................................................................................25
6.3.
システム分析(設計) ............................................................................................27
6.3.1.
クラス図...........................................................................................................27
1
6.4.
7.
実装 ................................................................................................................................30
7.1.
開発環境..................................................................................................................30
7.2.
利用したアプリケーションの特徴および利点........................................................30
7.2.1.
Java プラットフォームでの開発の利点 .........................................................30
7.2.2.
Apache Axis による開発の利点 ......................................................................31
7.2.3.
JSP(Java Server Pages)の特徴......................................................................31
7.2.4.
JDBC(Java DataBase Connectivity)の役割..................................................31
7.3.
データモデルの構築................................................................................................32
7.3.1.
MML テーブルの採用 .....................................................................................32
7.3.2.
ICD-10 対応電子カルテ用標準病名マスターの採用.......................................32
7.3.3.
データモデル ...................................................................................................33
7.4.
サーバ側 Web サービス ..........................................................................................33
7.4.1.
コーディング ...................................................................................................33
7.4.2.
デプロイ...........................................................................................................35
7.5.
クライアント側 Web アプリケーション.................................................................37
7.5.1.
WSDL 文書の取得...........................................................................................37
7.5.2.
スタブの生成 ...................................................................................................37
7.5.3.
コーディング ...................................................................................................38
7.6.
8.
デザインパターンの適用 ........................................................................................29
実行結果..................................................................................................................38
結論 ................................................................................................................................42
謝辞........................................................................................................................................45
附録........................................................................................................................................46
A)
Web サービス側 Java プログラム ..........................................................................46
B)
Web アプリケーション側 Java プログラム ...........................................................53
C)
その他のファイル ...................................................................................................57
2
1. 序論
私たちが医療機関に掛かった際、初診の場合は医師に自分の既往歴や服用している薬剤
等を口頭で説明しなければならない。また過去のカルテがその医療機関に存在しないため、
医師は患者の特徴を限られた範囲でしか得ることができない。これは医療機関間での情報
の共有が図られていないことが原因に挙げられる。
私は臨床医師へのヒアリング調査を行った。その結果、各診療科が独自にシステムを導
入しているため、診療科間の連携が図られていないことが分かった。更に医療機関間にお
いても設立の背景等の理由から、導入しているシステムの形態が各々異なっている事が判
明した。このような現状から現在の医療界では複数の医療機関でカルテ情報を共有し、医
療機関間を横断的に連携するシステムの構築が必要であると考えられる。
本論文ではカルテ情報を医療機関間で共有するシステムを構築する。新システムには
MML(Medical Markup Language)と ICD-10(International statistical Classification of
Diseases and related health problem 10th revision)という医療界において標準化されつ
つある規格を採用し、将来の医療システムに適応可能なシステムの開発を目指す。また情
報を共有する技術として Web サービスを適用する。更にプログラム内部にデザインパター
ンを組み込むことでシステムの保守・再利用性の向上を図る。本研究ではこのシステム構
築を通じて医療機関間でカルテ情報を共有する仕組みを明らかにすることを目的とする。
図 1 システム概要
3
2. 医療界の現状
2.1. 医療界で導入されているシステム
2.1.1. 電子カルテシステム
電子カルテシステムの定義は日本医療情報学会「電子カルテの定義に関する日本医療情
報学会の見解」[1]によって以下のように定義されている。
【定義】
電子カルテの定義を「通常の電子カルテ(Bottom-line)」と「ペーパーレス電子カル
テ」に分けて記載する。実際にはこの二つの中間にさまざまな電子化達成度の電子カル
テが存在しうる。
1.通常のもの(最低限の機能用件)
①
すべての業種目はカバーしなくても、多くの業種についてオーダ通信システムお
よびオーダ結果参照システムが稼動し、それぞれの業種についての診療録情報の基
本となっていること。
②
診療録を構成するすべての情報種はカバーしないが、多くの情報種について同時
に多箇所で、迅速に、充分に古いものも参照できること。また、それらの情報はさ
まざまな軸(時系列、特定の科のもの、特定の診療部門のもの、パスウェイ形式な
ど)で展開参照することが可能であること。
③
これらのデータの将来機種更新後の新システムへの移行を考え、また、不特定の
他医療施設との情報連携のためにも、できる限り HL7、DICOM などの標準的なデ
ータ形式およびコードを使用していること。さらに、紙やフィルムなどの従来媒体
の情報と電子化情報の関連性が損なわないようにすること。
④
画面を直接参照して、あるいは画面を利用して、患者への情報提供が紙によるも
のより格段に改善していること。
⑤
プライバシー保護が確保される運用であること。また紙やフィルムなどの従来媒
体による原本保存を行わない情報種に関しては、電子保存の 3 条件(真正性の確保、
見読性の確保、保存性の確保)を満足する運用であること。
2.ペーパーレス電子カルテ
①
診療録を構成するすべての情報種が電子的に扱われ、同時に多箇所で、迅速に、
十分に古いものも参照でいること。また、それらの情報は様々な軸(時系列、特定
の科のもの、特定の診療部門のもの、パスウェイ形式など)で展開参照することが
可能であること。
②
これらのデータの将来機種更新後の新システムへの移行を考え、また、不特定の
他医療施設との情報連携のためにも、出来る限り HL7、DICOM などの標準的なデ
ータ形式およびコードを使用していること。さらに、紙やフィルムなどの従来媒体
の情報と電子化情報の関連性が損なわないようにすること。
③
1.の③、④、⑤を満たすこと。
図 2.1 電子カルテの定義[1](抜粋)
上記2.で示されている定義が現在の電子カルテの理想である。
4
2.1.2. オーダリングシステム
オーダリングシステムとは「情報および院内物流の円滑化[1]」を目指したシステムであ
る。そのため患者に処方した薬やレントゲン予約等の情報は電子化されているが、具体的
な症状や治療情報は電子化されていない。
2.2. 医療システムを取り囲む環境
本節では医療システムを取り囲む環境について概観する。はじめに現在の医療システム
には同様のシステムが多く存在し、かつ互換性が図られていない理由を述べる。次に互換
性を図るための標準化の取り組みについて説明する。
2.2.1. 同種システムの混在
現在の病院で利用されているシステムは主に「電子カルテシステム」や「オーダリング
システム」等がある。しかし病院内のシステムは個人情報を伴うため非常に閉ざされた環
境で構築されており、病院ごとに仕様が異なっている。また、医療システムは総合病院の
みならず多くの診療所でも導入が進んでいる。しかし総合病院と単科かかりつけ医の医療
機関では考慮しなければならない点が異なり、単純に同じシステムとはいかない1。また、
同じ規模の医療機関でもこれまで情報のやりとりが紙媒体で行われてきたため、データエ
ントリーに関する運用処理が異なっていることが多い。
さらに、現在の医療界では全体をとりまとめる組織がない。そのため各診療科が独立に
組織化されており、汎用性のあるシステムが存在していない。
以上から同様のシステムが数多く存在する一方で、互換性が図られにくくなってしまっ
ている現状が分かる。
2.2.2. 医療情報の標準化
先に述べた現状を踏まえ、医療情報学の分野では医療情報の標準化が進められている。
現在提案されている規格は主に次の通りである。
医療情報の規格化
1. 医療情報交換のための記述言語に関する規格
MML(Medical Markup Language)
CLAIM(CLinical Accounting InforMation)
2. 医療情報そのものの交換のための規格
HL7(Health Level 7)
ICD-10(International statistical Classification of Diseases and related health problem
10th revision)
DICOM(Digital Imaging and Communication in Medicine)
1
病院によっても「特定機能病院」
「地域中核病院」
「民間総合病院」等、いくつかの種類に分けられる。
5
規格は大きく 2 つに分けられる。1 つは異なる医療機関の間や異種システム間で情報をや
り取りするための記述言語に対する規格である。もう 1 つは「医療情報のコード化」
「医用
画像のフォーマット化(DICOM など)」
「薬剤の分類体系化」のように、医療情報そのもの
の交換のための規格である。
記述言語に対する規格には「MML(Medical Markup Language)」「CLAIM(CLinical
Accounting InforMation)」があり、異なるシステム間や遠隔地医療機関の間での診療情報、
個人情報や会計情報などの電子的なやり取りが促進され、広域的なコラボレーションが実
現することになる。
本論文では「MML」および疾病分類コード「ICD-10」を採用してシステム開発を行う。
以下、各規格について説明する。
2.2.2.1. MML(Medical Markup Language)
MML(Medical Markup Language の略称。以下 MML と記す)は、異なる医療機関の
間で診療データを正しく交換する為に考えられた規格である。MML は特定非営利活動法人
MedXML コンソーシアム[2](以下 MedXML と記す)によって開発、維持管理されており、
XML 技術を用いて開発されている。さらに MedXML では MML を構築するために、情報
の属性項目を 36 個のテーブルで定義している。
以下、MML の概要と 36 個のテーブルについて簡潔に説明する。
MML の概要
①
<Mml>
バージョン、作成日、URL
<MmlHeader>
作成者情報、患者 ID、toc*
</MmlHeader>
<MmlBody>
文章ヘッダー(docInfo)、コンテンツ(患者情報や診療歴等)
</MmlBody>
</Mml>
MML は以上のような形式で記述される言語である。主に HTML の記述法と似ている。
<MmlBody>内では次のような項目が記述される。

*
文章ヘッダー(docInfo)内
・記載日
・親文書 ID
・記載者
・グループ ID
・文書種別、タイトル
・アクセス権
・文書 ID
・外部参照リスト
toc(table of contents)はその情報を参照するだけで、ボディに何が書かれているかが分かる。
6

コンテンツ内
・患者情報
・経過記録情報
・健康保険情報
・手術記録情報
・診断履歴情報
・臨床サマリー情報
・生活習慣情報
・検歴情報
・基礎的診療情報
・報告書情報
・初診時特有情報
・紹介状
上記のような情報が、それぞれ定められたタグによって記述されることで、情報の交
換をスムーズに行っている。
例:名前を記述する
<mmlNm:fullname>村田洋</mmlNm:fullname>
②
MML 構築のための 36 個のテーブル
以下のテーブルが定義されている。
表 2.1 MML テーブル一覧
テーブル番号
テーブル名
MML0001
Check digit schema (チェックディジット方式,HL7-0061 準拠)
MML0002
Address Type (HL7-0190 準拠)
MML0003
Telecommunication Equipment Type (HL7 table0202 準拠)
MML0004
Extraction policy (抽出基準)
MML0005
Content module type (記載内容モジュールの種別)
MML0006
Access (アクセス権者)
MML0007
Generation purpose (文書詳細種別)
MML0008
Document relation (関連文書との関係)
MML0009
Other ID type (その他の ID 種別)
MML0010
Sex (性別)
MML0011
Marital Status (婚姻状態,HL7table0002 準拠)
MML0012
Diagnosis category 1
MML0013
Diagnosis category 2
MML0014
Diagnosis category 3
MML0015
Diagnosis category 4
MML0016
Outcome (転帰)
MML0017
Allergy Severity (アレルギー反応程度)
7
MML0018
ABO blood type (ABO 式血液型)
MML0019
Rho(D) blood type (Rho(D)式血液型)
MML0020
Relative code (続柄コード)
MML0021
Type of surgery (手術区分)
MML0022
Classification of surgical staffs (手術スタッフ区分)
MML0023
Classification of anesthesiologists (麻酔医区分)
MML0024
ID type (ID 区分)
MML0025
Name representation code (表記コード,HL7table4000 準拠)
MML0026
Creator license code (記録者分類および医療資格コード)
MML0027
Facility ID type (施設 ID 区分)
MML0028
Medical Department ID type (医科診療科コード)
MML0029
Department ID type
MML0030
Dental Department ID type (歯科診療科コード)
MML0031
Insurance Class (保健種別)
MML0032
Pay Ratio Type (負担方法コード)
MML0033
Medical Role
MML0034
アクセス許可区分
MML0035
施設アクセス権定義
MML0036
個人アクセス権定義
2.2.2.2. ICD-10(International statistical Classification of Diseases and related
health problem 10th revision)
表 2.2 疾病分類コード「ICD-10」
ICD-10 の大分類(疾病の分類)
1 A00-B99
感染症および寄生虫症
2 C00-D48
新生物
3 D50-D89
血液および造血器の疾患ならびに免疫機構の障害
4 E00-E90
内分泌、栄養および代謝疾患
5 F00-F99
精神および行動の障害
6 G00-G99
神経系の疾患
7 H00-H59
眼および付属器の疾患
8 H60-H95
耳および乳様突起の疾患
9 I00-I99
循環器系の疾患
10 J00-J99
呼吸器系の疾患
11 K00-K93
消化器系の疾患
8
12 L00-L99
皮膚および皮下組織の疾患
13 M00-M99
筋骨格系および結合組織の疾患
14 N00-N99
尿路性器系の疾患
15 O00-O99
妊娠、分娩および産褥
16 P00-P96
周産期に発生した病態
17 Q00-Q99
先天奇形、変形および染色体異常
18 R00-R99
症状、徴候および異常臨床所見・異常検査所見で他に分類されないもの
19 S00-T98
損傷、中毒およびその他の外因の影響
20 V00-Y98
傷病および死亡の外因
21 Z00-Z99
健康状態に影響をおよぼす要因および保健サービスの利用
ICD-10 は WHO(世界保健機関)が作成した医療情報をやり取りする際の標準規格であ
る。現在、電子カルテなどの疾病分類コード[3]として用いられている。また医療行政上の
疾病の分類などに使われ、広く認知され始めている。
9
3. 問題の定義とシステムの提案
3.1. 問題の定義
本論文では第 2 章で説明した医療界の現状を踏まえ、次のように問題を定義する。

医療機関によって導入されているシステムの形態が異なり連携が図られていない

医師は初診患者の病歴を口頭でしか知ることができない

医療情報を医療機関間で共有する仕組みが必要である

医療情報の標準化を踏まえたシステムが必要である
3.2. 電子カルテ共有システムの提案と意義
本節では第 1 節で定義した問題に対して電子カルテ共有システムを提案すると同時に、
その意義について述べる。
はじめに異なる医療機関間で任意のカルテ情報を共有できるシステムを提案する。次に
システムを実装する上で、医療情報の標準化を踏まえた開発を行う。なお情報を共有する
仕組みとして Web サービス技術を適用し、医療情報標準化に関しては MML テーブルと
ICD-10 対応電子カルテ用標準病名マスターを採用することとする。更にプログラム内部に
デザインパターンという技術を組み込むことでシステムの保守・再利用性の向上を目指す。
電子カルテ共有システム開発の意義は 3 点挙げられる。1 点目は医療機関間でカルテ情報
が共有されることにより、医師が初診患者の既往歴を参照できることにある。2 点目は患者
のカルテ情報が一元化されることで、医療従事者がより適切な処置を行うことができる点
にある。そして 3 点目はカルテが紙ベースから電子オンラインベースに移ることで、紙資
源の省力化を図ることが挙げられる。
カルテ情報が共有化されることにより、緊急時や在宅医療等でも救命救急士や医師はよ
り多くの具体的な情報を入手することができる。また過去の情報を参照することにより、
適切かつ迅速な処置を行うことができると予想される。
次に省資源化に関して、現在医療機関では1患者1カルテが良いとされている。しかし
大規模病院では1患者1カルテの実現が困難となっている。そこで電子カルテ共有システ
ムを導入することにより、患者情報の一元化と省資源化を促進することができると考える。
10
4. Web サービス
4.1. Web サービスとは
Web サービスとはインターネット上でメッセージを送受信しあって、システムを連携さ
せる技術体系のことである。またこの技術体系を利用したサービスのことも指す。
Web サービスの大きな特徴は人を介さずに多くのサービスを利用できる点にある。従っ
てシステムとシステムが自動的に連携され、多様なサービスを提供する事が可能となる。
図 4.1 Web サービス
上図は Web サービスの概念図である。クライアントは1つの Web アプリケーションにア
クセスするだけで、複数の Web サービスからデータを取得することができる。
4.2. Web アプリケーションと Web サービス
本論文では電子カルテ共有システムの開発にあたって、ユーザインタフェースとしての
Web アプリケーション作成も兼ねる。そのため本節では Web アプリケーションと Web サ
ービスの違いを示しておく。
Web アプリケーションと Web サービスはサービスの提供対象が異なっている。Web アプ
リケーションは人に対してサービスを提供するが、Web サービスはアプリケーションに対
してサービスを提供する。概念図を以下に示す。
図 4.2 Web アプリケーションと Web サービス
11
4.3. Web サービスの要素技術
Web サービスを実現するための主な技術は SOAP、WSDL、UDDI である。Web サービ
スは人ではなく他のアプリケーションによって呼び出されるため、主に次の 3 つの機能を
備えている。
4.3.1. SOAP(Simple Object Access Protocol)
SOAP は Web サービスを利用するための技術である。Web サービスはインターネット上
でメッセージを送受信することで実現される。その送受信についてのフォーマットを定め
た規格が SOAP である。
4.3.1.1. XML(eXtensible Markup Language)
SOAP では Web サービスで利用するメッセージ形式を XML 形式で定義している。XML
とはマークアップ言語の一種で HTML もその一つである。しかし HTML はタグによって
固定された意味のメッセージしか記述できないが、
XML は柔軟にタグの意味を定義できる。
また XML は単なるテキストデータであるのでプラットフォームに依存することなく送受
信ができる。
4.3.1.2. SOAP メッセージ
Web サービスでは送受信するメッセージを SOAP メッセージと呼ぶ。SOAP メッセージ
には SOAP エンベロープ(封筒)が入っている。また SOAP エンベロープはヘッダ部分と
ボディ部分から構成されている(図 4.3)。
図 4.3 SOAP メッセージの構造[4]
ヘッダ部分は認証やトランザクション管理などに必要な情報が記述される。ボディ部分
には送受信するメッセージ自身が記述される。
12
4.3.2. WSDL(Web Services Description Language)
WSDL は Web サービスを記述するための言語である。Web サービスは別のアプリケー
ションから呼び出される。そのため Web サービスがどのような機能を持ち、どのようなデ
ータを処理するか等を他のアプリケーションが理解できるように記述する必要がある。つ
まり WSDL は Web サービスのインタフェース仕様を記述するために策定された XML 形式
の言語である。
また WSDL で記述した XML 文書のことを WSDL 文書と呼ぶ。WSDL 文書には Web サ
ービスのインタフェースが記述されている。具体的にはサービスを利用するためのメソッ
ドやデータ形式等が記述されている。従ってアプリケーションが Web サービスを利用する
際にはあらかじめ WSDL 文書を取得しておかなければならない。
図 4.4 WSDL 文書の役割
4.3.3. UDDI(Universal Description, Discovery, and Integration)
UDDI は Web サービスを登録・検索するため技術である。Web サービスはインターネッ
ト上に点在している。そこでどのような機能を持つ Web サービスがどこに存在しているの
かを管理する必要がある。その仕組みを定めた規格が UDDI である。いわばインターネッ
ト上の電話帳のようなものである。
図 4.5 UDDI の役割[5]
13
4.4. Apache Axis を用いた Web サービス
Apache Axis は SOAP や WSDL を実装したミドルソフトの 1 つである。前節で Web サ
ービスに必要な要素技術を説明した。本節では Apache Axis を用いる事で SOAP や WSDL
に直接触れることなく、Web サービスを実現する方法を説明する。
図 4.6
Apache Axis の役割[16]
図 4.6 はユーザが Web サービスを利用する上での Apache Axis の役割を示している。
まずユーザはあらかじめ利用したい Web サービスから WSDL 文書を入手している必要
がある。WSDL 文書の取得は UDDI を利用する事で可能となる。次にユーザはアプリケー
ションを通して Web サービスに必要な情報を送信する。送信されたデータは XML パーサ
によって XML 形式に変換される。その後 Apache Axis は WSDL 文書を参照しながら送信
されてきた XML データをもとに SOAP メッセージを生成する。生成された SOAP メッセ
ージはインターネットを介して Web サービス側へ送信される。
次に Web サービス側では初めに Apache Axis によって SOAP メッセージを受信する。さ
らに Apache Axis は SOAP メッセージを解析し XML データを抽出した後、XML パーサへ
XML データを送信する。XML パーサでは XML データをアプリケーションが利用できる形
式に変換する。そうして Web サービス内のアプリケーションはユーザから送信されたデー
タを受け取ることが出来る。
その後アプリケーション内で適切な処理が行われ、結果が返される。Web サービス内ア
プリケーションからユーザへの情報の伝達は逆の順序を辿ることで実現される。
このように Apache Axis はクライアント側および Web サービス側の窓口の役割を果たし
ていることが分かる。また Apache Axis が WSDL 文書を自動的に参照し SOAP メッセー
ジを生成することで、ユーザが WSDL と SOAP に直接触れることなく Web サービスを利
用していることが分かる。
14
5. デザインパターン
5.1. デザインパターンとは
デザインパターンとはソフトウェア設計において頻出する問題とそれに対する解決策を
まとめ[6]、パターンとして体系化したものである。主に 23 のパターンが機能ごとに体系化
されている。また各パターンには「State パターン」のようにそれぞれに名前が付けられて
いる。
5.2. デザインパターンの意義
デザインパターンの意義はソフトウェア設計において問題を解決するためのヒントを与
えてくれることと、システムの保守性・再利用性を高めることにある。また開発者に共通
の「設計用語」を提供する役割も持っている。
システムの保守性・再利用性を高めるとはクラスを部品として使えるようにするという
ことである。例えば 1 つのクラスを修正したとしても、他のクラスの修正は少なくて済む
場合に保守性・再利用性が高いと言える。
また開発者に共通の「設計用語」を提供するとは、これまで「設計」に関する共通用語
がなかったことに起因する。これまでアルゴリズムやデータ構造の分野では共通の用語が
多く存在してきた。例えば「ソート」「バックトラック法」「スタック」「二分木」「再帰」
などである。しかし、これよりも抽象度の高い「設計」に関する共通用語はこれまでほと
んど存在しなかった。
デザインパターンは開発者にとっての共通の用語を提供し、開発や保守の場面において
最適な環境を用意してくれる技法である。
5.3. デザインパターンの種類
デザインパターンの主な 23 種類について説明する(表 5.1)。
表 5.1 デザインパターンの種類[7]
デザインパターン名
意味(概要)
Iterator
数え上げる
Adapter
一皮かぶせて再利用
Template Method
Factory Method
意味(詳細)
数え上げる
サブクラスにまかせる
Singleton
Prototype
Builder
一皮かぶせて再利用
具体的な処理をサブクラスにまかせる
インスタンス作成をサブクラスにまかせる
たった 1 つのインスタンス
インスタンスを作る
Abstract Factory
コピーしてインスタンスを作る
複雑なインスタンスを組み立てる
関連する部品を組み合わせて製品を作る
15
Bridge
分けて考える
Strategy
Composite
Visitor
飾り枠と中身の同一視
構造を渡り歩く
Chain of Responsibility
Façade
シンプルにする
Mediator
アルゴリズムをごっそり切り替える
容器と中身の同一視
同一視
Decorator
機能の階層と実装の階層を分ける
Observer
構造を渡り歩きながら仕事をする
責任のたらい回し
シンプルな窓口
相手は相談役 1 人だけ
状態の変化を通知する
状態を管理する
Memento
State
状態を保存する
状態をクラスとして表現する
Flyweight
無駄をなくす
Proxy
Command
クラスで表現する
Interpreter
同じものを共有して無駄をなくす
必要になってから作る
命令をクラスにする
文法規則をクラスで表現する
5.4. Iterator パターンについて
Iterator パターンは数え上げるような機能を持つプログラムに対して有効である。電子カ
ルテ共有システムではカルテを検索し、何件のカルテが存在するかを数え上げている。そ
こで本論文では電子カルテ共有システムに Iterator パターンを適用する。本節ではその
Iterator パターンについて詳しく述べる。
Iterator パターンには 2 つのインタフェースと 2 つ以上の実装クラスから構成される。
ク
ラス図2は以下の通りである。
図 5.1 Iterator パターンのクラス図
2
クラス図については次章で詳述する。
16
Aggregate クラスと Iterator クラスはインタフェースとして配置されている。それぞれ
iterator メソッドと hasNext メソッド、next メソッドが記述されているが、具体的な実装
は 行 っ て い な い 。 具 体 的 な 実 装 を 行 っ て い る の は ConcreteAggregate ク ラ ス と
ConcreteIterator クラスである。
プログラムをインタフェースと実装に分けることでプログ
ラムの動作は Iterator インタフェースで行われているように見える。さらに実装のみが
ConcreteIterator クラスで行われているため、
一方のプログラム修正は他方に影響を及ぼさ
ない。従って保守性に優れていることが分かる。
図 5.2 Iterator パターンの概念図
図 5.2 では Iterator パターンの概念図を示している。インタフェースクラスには
Aggregate クラスと Iterator クラスが対応し、
具体的な実装クラスには ConcreteAggregate
クラスと ConcreteIterator クラスが対応する。
また Iterator クラスの特徴として、インタフェースクラス1つに対して具体的な実装ク
ラスを複数持つことが出来る。例えば「カルテ数え上げる」というインタフェースでも、
「カ
ルテを患者氏名順に数え上げる」ことも可能であるし、
「カルテを患者 ID 順に数え上げる」
ことも可能である。複数の具体的な実装クラスを1つのインタフェースクラスで管理でき
る事も Iterator パターンの特徴である。
17
6. 電子カルテ共有システムの分析と設計
ここではシステム開発の際に用いられる UML というオブジェクト指向言語を用いて分
析と設計を行う。また以下の工程に沿ってシステムの分析、設計を行っていく。
1.
ドメイン分析(設計)
2.
システム分析(設計)
この分析、設計工程は一部に佐原 伸 著「デザインパターン
オブジェクト指向分析/設
計技法」を参考にしている。
6.1. UML とは
UML は Unified Modeling Language の略称でプログラム設計図の統一表記法である。
現在ではオブジェクト指向における表記法としてデファクトスタンダード化されており、
分析から設計、実装まで終始一貫して使用されている技術である。
本節ではユースケース図、ユースケース記述、シーケンス図、およびクラス図について
説明する。
6.1.1. ユースケース図
ユースケース図はシステムのサービスを表現するための図である。ユーザがシステムを
どのように操作するか、またシステムの機能として何が存在するかを把握することができ
る。ユースケース図は次に示す要素で構成される。
図 6.1 ユースケース図の要素
アクターはサービスの利用者を表す。ユースケースはシステムを使用する方法であり、
ユーザのニーズを表している。
6.1.2. ユースケース記述
ユースケース記述とはユースケースの各機能を文字で記述したものである。ユースケー
ス記述はシナリオとも呼ばれる。ユースケース記述は補足的に記述されることが多いが、
本論文では[8]を参考に「ユースケース名」「概要」「文脈(全体の流れ)」「基本パス(通常
の流れ)」「代替パス(通常以外の流れ)
」「前件」「後件」で分析していく。
18
6.1.3. シーケンス図
シーケンス図とはオブジェクト間の相互関係を時系列に沿って表現した図である。縦軸
は時間を表し、横軸には個々のオブジェクトを表記する。オブジェクト間のやり取りは主
に矢印によって表される。
本論文では現在 Object Management Group によって定義されている UML2.0 を用いて
シーケンス図を記述する。従来の UML1.x で用いられているシーケンス図との決定的な差
は分岐処理や並行処理の記述が可能になった点である。分岐処理とは if 文を用いた条件分
岐等を指し、並行処理とはスレッドでの処理等を指す。以下に分岐処理でのシーケンス図
記述方法を示す。
図 6.2 シーケンス図の分岐処理記述法[9]
図 6.2 のシーケンス図は下図のプログラムを表現したものである。
public class Foo{
private static Bar bar = new Bar();
private static Hoge hoge = new Hoge();
public static void main(String[] args){
if(x = 0){
bar.methid1();
}
else{
hoge.method2();
}
}
}
図 6.3 分岐処理プログラム
19
6.1.4. クラス図
クラス図はシステムに対してどのようなモノ、概念が存在するのかを図示するために用
いられる。またプログラム中のメソッド名や属性を記述することができる。しかし記述で
きる内容は静的な構造のみであるため、動的な処理に関しては記述できない。
本論文で用いる表記法は図 6.4 の通りである[7]。
Color
Fruit
color
Basket
fruits
A. インタフェースと実装
B. 集約
C. クラスの生成
図 6.4 クラス図の表記法
A.に関しては Printable インタフェースクラスでメソッドの名前と型を定義している。し
かし具体的な実装は PrintClass クラスで行っている。インタフェースと実装が分かれてい
る場合には A.の矢印を用いる。
B.に関しては集約を表している。Basket クラスではインスタンス変数として fruits を保
持し、Fruit クラスでは color というインスタンス変数を保持している。集約ではクラス間
に「has-a」の関係があることを示している。
そして C.ではクラス間の関連を表している。矢印に黒三角をつけて関係を表記すること
で、使用、生成、通知の 3 種類を表すことが出来る。それぞれ記述できる単語は次の通り
である。
表 6.1 クラスの関連
単語
意味
Uses
使用する
Creates
生成する
Notifies
通知する
20
6.2. ドメイン分析(設計)
本節から電子カルテ共有システムの分析、設計に入る。ドメイン分析(設計)ではシス
テムによって解決すべき問題領域がどこまでか、また問題領域では何をしているのかをモ
デル化する。
6.2.1. 用語の定義
用語とはオブジェクト名や操作名を指す。曖昧な用語(例えば「ユーザ」や「組織」な
ど)を的確な表現で以下に定義していく。
·
利用者
電子カルテ共有システムの利用者。主にカルテ情報を閲覧する医療従事者と患者
からなる。
·
医療従事者
医師、看護師、薬剤師、理学療法士、作業療法士、診療放射線技師、臨床検査技
師 等の電子カルテに接する機会のある人。
·
患者
医療行為を受けている人、または受けていた人。
·
電子カルテ
患者の基本個人情報、診療録が記載されたデータの集まり。
·
医療機関
医療行為を行う組織すべてを指す。特定機能病院、地域中核病院、民間総合病院、
地域診療所等がある。
21
6.2.2. ユースケース図およびユースケース記述
ユースケース図は以下の通りである。
図 6.5 ユースケース図
はじめにユーザはカルテ情報の検索を行う。その後カルテ情報(詳細)の取得を行うこ
とができ、その後さらに患者基本情報の取得を行うことができる。
以下、各ユースケースについて処理の流れを記述したユースケース記述を示す。
ユースケース記述「カルテ情報の検索」
·
ユースケース名
·
カルテ情報の検索
概要
外部の医療機関から Web サービスを用いてカルテ情報を検索し入手する。
·
文脈
利用者がカルテ情報を閲覧する際に、Web サービスを用いて複数の医療機関か
らカルテ情報を入手、一覧表示させる。
·
·
基本パス[取得可能]
前件
-- インターネットに接続されている必要がある。
·
-- 外部医療機関に取得したいカルテ情報がある。
後件
-- 複数の医療機関からカルテ情報を取得する。
·
-- 取得した情報を一覧表示させる。
代替パス[接続不能]
·
前件
·
-- インターネットに接続されていない。
後件
-- エラーの表示。
22
·
代替パス[取得情報なし]
·
前件
-- 外部医療機関に取得したいカルテ情報がない。
·
後件
-- エラーの表示。
·
代替パス[入力情報の不足]
·
前件
-- 検索・取得に必要な属性情報が入力されていない。
·
後件
-- エラーの表示。
ユースケース記述「カルテ情報(詳細)の取得」
·
ユースケース名
カルテ情報(詳細)の取得
·
概要
検索されたカルテ情報に関して、さらに詳細なカルテ情報を取得する。
·
文脈
利用者はカルテ情報の検索結果画面から特定のカルテを選択する。Web サービ
スによって詳細なカルテ情報を取得し、表示させる。
·
基本パス[取得可能]
·
前件
-- インターネットに接続されている必要がある。
-- 外部医療機関に指定したカルテ情報が存在する。
·
後件
-- 指定したカルテの全情報を取得する。
-- 取得した情報を表示させる。
·
·
代替パス[接続不能]
前件
-- インターネットに接続されていない。
·
後件
-- エラーの表示。
·
代替パス[カルテ情報なし]
·
前件
-- 外部医療機関に取得したいカルテ情報が存在しない。
·
後件
-- エラーの表示。
23
·
代替パス[入力情報の不足]
·
前件
-- 検索・取得に必要な属性情報が入力されていない。
·
後件
-- エラーの表示。
ユースケース記述「患者基本情報の取得」
·
ユースケース名
·
概要
患者基本情報の取得
取得済みカルテに記載されている患者の基本情報を、Web サービスを用いて取
·
得する。
文脈
利用者はあらかじめカルテ情報(詳細)を取得しており、カルテに記載されて
·
いる患者に関して基本情報を取得し、表示させる。
基本パス[取得可能]
·
前件
-- インターネットに接続されている必要がある。
-- 外部医療機関に指定した患者の基本情報が存在する。
·
後件
-- 指定した患者の全基本情報を取得する。
-- 取得した情報を表示させる。
·
代替パス[接続不能]
·
前件
-- インターネットに接続されていない。
·
後件
·
-- エラーの表示。
代替パス[患者基本情報なし]
·
前件
·
-- 外部医療機関に取得したい患者の基本情報が存在しない。
後件
-- エラーの表示。
·
·
代替パス[入力情報の不足]
前件
-- 検索・取得に必要な属性情報が入力されていない。
·
後件
-- エラーの表示。
24
6.2.3. シーケンス図
シーケンス図によるオブジェクト間通信を下記に示す。以下、各機能別に図示する。
図 6.6 カルテ情報の検索に関するシーケンス図
図 6.6 はカルテ検索画面からキーワードに該当したカルテ一覧を取得するまでのシーケ
ンス図である。ユーザは検索したい患者の姓を入力し、ボタンをクリックすることでクラ
イアント側のシステムがその情報を取得する。その後クライアント側システムは Web サー
ビスへ接続し、カルテの該当件数やカルテオブジェクトを取得していく。順次カルテ情報
を表示していき、最後にカルテ検索画面へ戻ることが出来る。
25
以下の図 6.7、図 6.8 は各々ユーザが指定したカルテと患者基本情報に関するデータを取
得するためのシーケンス図である。オブジェクト間の通信方法はほぼ同等である。またオ
ブジェクトが存在しないときは分岐処理を用いてエラー処理を行うように設計した。
図 6.7 カルテ情報(詳細)の取得に関するシーケンス図
図 6.8 患者基本情報の取得に関するシーケンス図
26
6.3. システム分析(設計)
システム分析(設計)ではクラス図による分析を行い、より精密な分析モデルを作る。
6.3.1. クラス図
ここで再度ユースケースの 3 つの機能を確認する。電子カルテ共有システムの 3 つの機
能とは以下の通りである。
1.
カルテ情報の検索
2.
カルテ情報(詳細)の取得
3.
患者基本情報の取得
本節では論述の都合上、はじめに 2.および 3.について説明し、1.については後述する。
図 6.9 カルテ情報(詳細)の取得に関するクラス図
図 6.9 ではカルテ情報
(詳細)
を取得する際のクラス図を示している。
ChartSearchService
クラスで ItemBean クラスのインスタンスを保持し、カルテオブジェクトの属性を取得す
る構造を示している。
27
図 6.10 患者基本情報の取得に関するクラス図
図 6.10 では患者基本情報の取得に関するプログラムの構造を示している。主な流れはカ
ルテ情報(詳細)の取得と同じである。
図 6.11 カルテ情報の検索に関するクラス図
28
図 6.11 ではユーザから受け取ったキーワードを元にカルテ情報を検索するプログラム構
造を示している。ChartSearchService クラスが SearchResult クラスのインスタンスを保
持し、SearchResult クラスが ItemBean クラスのインスタンスを保持していることが分か
る。
6.4. デザインパターンの適用
デザインパターンの Iterator パターンを図 6.14 に適用すると以下のようなクラス図に更
新できる。
図 6.12 デザインパターン適用後のクラス図
図 6.12 を参照するとインタフェースとして Aggregate クラスと Iterator クラスが加わっ
ていることが分かる。また、SearchResult クラスに対応する形態で SearchResultIterator
クラスが付加された。このようなクラス構成に更新することで数え上げる役割を Iterator
クラスおよび SearchResultIterator クラスに任せ、データを保持する役割を SearchResult
クラスと ItemBean クラスに任せることができた。このような役割分担を行い、インタフ
ェースと具体的な実装を区別することで保守性・再利用性を高めることができた。
29
7. 実装
7.1. 開発環境
(1) サーバ側Web サービス
【OS】Windows XP Professional Version 2002 Service Pack 2
【Web サーバ】Apache Tomcat 5.5.12
【開発言語】Java
【Java 開発環境】J2SE Development Kit 5.0 Update 5
【データベースサーバ】MySQL 5.0.15
【データベース接続ドライバ】MySQL Connector Java 3.2.0 alpha
【SOAP モジュール】Apache Axis 1.3 Final
(2) クライアント側Web アプリケーション
【OS】Windows XP Professional Version 2002 Service Pack 2
【Web サーバ】Apache Tomcat 5.5.12
【開発言語】Java、JSP
【Java 開発環境】J2SE Development Kit 5.0 Update 5
【SOAP モジュール】Apache Axis 1.3 Final
(3) その他
【ソフトウェア開発環境】eclipse 3.1
【MySQL 統括環境】MySQL Administrator 1.1
【eclipse データモデル開発ツール】Clayデータベースモデル 1.2.0 Core Edition
【eclipse Clayプラグイン動作環境】Graphical Editing Framework 3.1.1
【eclipse データベース操作ツール】QuantumDatabase plugin 3.0.1
7.2. 利用したアプリケーションの特徴および利点
7.2.1. Java プラットフォームでの開発の利点
Web サービスを構築するプラットフォームには Java プラットフォーム以外に.Net
Framework が存在する。.NET Framework は Microsoft 社が提供している Web サービス
等のアプリケーション開発プラットフォームである。
.NET Framework は Windows 環境下での開発が容易である一方、Windows 以外の環境
下では提供されない。つまり Windows 以外の環境で Web サービスを開発したり、Windows
で作成した Web サービスを他の環境下に移植したりする場合に.NET Framework を利用す
る事はできない。現在それを可能にするものは Java プラットフォームのみである。
本論文では今後の保守を踏まえて、異種システム間でもシステムの開発ができるよう
Java プラットフォームでの開発を行う。
30
7.2.2. Apache Axis による開発の利点
ここでは第 4 章第 4 節で示した Apache Axis を用いてプログラム開発を行う。その利点
は SOAP や WSDL に記述されている XML に直接触れる必要がない点にある。更に Java
によるプログラム開発が可能であったので Apache Axis を採用した。
7.2.3. JSP(Java Server Pages)の特徴
JSP とは Java 言語を利用して Web ページを動的に生成し、データを Web サーバからク
ライアントへ送信する技術である。JSP は以下のような特徴を持つ。

<% %>で囲まれた JSP タグの中に Java プログラムを記述する

JSP タグは HTML 内に埋め込むことができる

コンパイルが不要である

結果は通常の HTML 形式になる
以上の技術から、JSP は Web サービスなどでクライアント側のシステム開発に適してい
る。
7.2.4. JDBC(Java DataBase Connectivity)の役割
JDBC は MySQL と Java を連携させるための API である(図 7.1)
。
図 7.1
JDBC の役割
JDBC から MySQL に接続するためには、MySQL の root でログインし、ユーザを作成
して権限を与える必要がある。root とは管理者権限のことを指す。権限が与えられたユー
ザは Java プログラム内で SQL 文を記述し、データベースから情報を抽出することができ
る。
31
7.3. データモデルの構築
電子カルテ共有システムを構築するにあたり、本論文では医療情報の標準化も視野に入
れているため、データモデルを一部 MML テーブルに準拠させた。またプロトタイプに使
用するサンプルデータとして ICD-10 対応電子カルテ用標準病名マスターを一部採用した。
以下に詳細を述べる。
7.3.1. MML テーブルの採用
医療情報の標準化に則るため、データモデルの一部を医療情報標準規格の MML Version
3.0 に準拠させた。MML Version3.0 では第 2 章第 2 節で示した 36 個のテーブルが定義さ
れている。その中で次に示すテーブルの属性項目3を採用しデータモデルを構築した。
表 7.1 採用した MML テーブル[2]
MMLテーブル
MML テーブル名
番号
用途
MML0010
Sex
性別
MML0011
Marital Status
婚姻状態,HL7table0002 準拠
MML0018
ABO blood type
ABO 式血液型
MML0019
Rho(D) blood type
Rho(D)式血液型
MML0026
Creator license code
記録者分類および医療資格コード
MML0028
Medical Department ID type
医科診療科コード
7.3.2. ICD-10 対応電子カルテ用標準病名マスターの採用
財団法人医療情報システム開発センター[10]より ICD-10 に対応した標準病名マスターが
配布されている。現在の ICD-10 は第 10 版にあたる。
本論文では電子カルテ共有システムにおいてプロトタイプ用に ICD-10 対応電子カルテ
用標準病名マスターを採用する。属性項目は以下の通りである。
表 7.2 ICD-10 対応電子カルテ用標準病名マスターの属性項目
3
変更区分
ICD10
使用分野
病名管理番号
ICD10複数分類コード 変更履歴番号
病名表記
ICD10確度
更新日付
病名表記カナ
複数 ICD 候補
移行先病名管理番号
採択区分
レセ電算コード
単独使用禁止区分
病名交換用コード
レセ電算対応表記
保険請求外区分
属性項目の詳細は 7.3.3 節「データモデル」を参照
32
7.3.3. データモデル
以上を踏まえ、図 7.2 のようなデータモデルを構築した。
図 7.2 データモデル
7.4. サーバ側 Web サービス
本節ではサーバ側 Web サービスの実装を開発工程に沿って説明していく。
7.4.1. コーディング
初めにサーバ側での処理を Java によってコーディングする。電子カルテ共有システムで
は次の 3 つの機能を持つ。

クライアントから患者の名前データを受け取り、カルテを検索してカルテデータ(一
部)を返す

クライアントから指定されたカルテに関して、カルテデータ(全体)を返す

クライアントから指定された患者に関して、患者データを返す
これらの機能を実現するために次の 4 つの共通段階を設定した。
1.
データベースに接続する
2.
データベースから必要なデータを抽出する
3.
抽出したデータを保持する
4.
データベースから切断する
33
以下に 4 つの共通段階のソースコードを示す。
1.「データベースに接続する」
// ドライバクラスをロード
Class.forName("com.mysql.jdbc.Driver"); // MySQLの場合
sql = new String("select * from patient;");
// データベースへ接続
String url = "jdbc:mysql:///thesis?useUnicode=true&characterEncoding=SJIS";
Connection con = DriverManager.getConnection(url,"thesis","*********");
2.「データベースから必要なデータを抽出する」
// ステートメントオブジェクトを生成
Statement stmt = con.createStatement();
// クエリーを実行して結果セットを取得
ResultSet rs = stmt.executeQuery(sql);
// 検索された行数分ループ
while(rs.next()){
//患者名を取得
String patientLastNameKanji = rs.getString("patient_last_name_kanji");
//カルテIDを取得
int chartId = rs.getInt("chart_id");
// カルテ作成日を取得
int date = rs.getInt("date");
// 医療機関名を取得
String nameOfInstitution = rs.getString("name_of_institution");
// 医療従事者名を取得
String staffLastNameKanji = rs.getString("staff_last_name_kanji");
String staffFirstNameKanji = rs.getString("staff_first_name_kanji");
// 病名を取得
String nameOfDisease = rs.getString("name_of_disease");
3.「抽出したデータを保持する」
//ItemBeanクラスを用いてひとつのカルテを生成。
ItemBean item = new ItemBean();
item.setPatientLastNameKanji(patientLastNameKanji);
item.setChartId(chartId);
item.setDate(date);
item.setNameOfInstitution(nameOfInstitution);
item.setStaffLastNameKanji(staffLastNameKanji);
item.setStaffFirstNameKanji(staffFirstNameKanji);
item.setNameOfDisease(nameOfDisease);
//SearchResultクラスのオブジェクトとして格納する。
SearchResult alist = new SearchResult();
alist.add(item);
}
34
4.「データベースから切断する」
// データベースから切断
stmt.close();
con.close();
以上の段階を応用して各機能を実装した。
7.4.2. デプロイ
Web サービスとしてシステムを稼動させるためには、コーディングの内容を Web サーバ
に登録する必要がある。その作業がデプロイ(配置)である。
初めに Java でコーディングしたクラスファイルをアーカイブ化し、jar ファイルを生成
して(図 7.3)Web サーバ側の Apache Axis 内へコピーする必要がある。ファイル構成に
関しては附録に添付する。
C:\axis-1_3\Thesis\Electric_chart_sharing_system>jar cvMf chartSearchService.jar
medical_service\*.class
medical_service/Aggregate.class を追加中です。(入 = 165) (出 = 133)(19% 収縮されました)
medical_service/ChartSearchService.class を追加中です。(入 = 13430) (出 = 5786)(56% 収
縮されました)
medical_service/ItemBean.class を追加中です。(入 = 6881) (出 = 1880)(72% 収縮されまし
た)
medical_service/Iterator.class を追加中です。(入 = 187) (出 = 152)(18% 収縮されました)
medical_service/SearchResult.class を追加中です。(入 = 1081) (出 = 549)(49% 収縮されま
した)
medical_service/SearchResultIterator.class を追加中です。(入 = 1064) (出 = 589)(44% 収
縮されました)
図 7.3 jar ファイルの生成
またデプロイを行うには WSDD(Web Service Deployment Descriptor)ファイルを記述
する必要がある。WSDD ファイルとはどのクラスのどのメソッドを利用できるようにする
か等を記述するファイルである(図 7.4)
。
<deployment name="test" xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="urn:ChartSearchService" provider="java:RPC">
<parameter name="className" value="medical_service.ChartSearchService" />
<parameter name="allowedMethods" value="*" />
<parameter name="scope" value="session"/>
<beanMapping qname="ns:ItemBean" xmlns:ns="urn:medical_service"
languageSpecificType="java:medical_service.ItemBean"/>
</service>
</deployment>
図 7.4 WSDD ファイル
35
次にコマンドを利用してデプロイを行う(図 7.5)。
C:\axis-1_3\Thesis\Electric_chart_sharing_system>java org.apache.axis.client.Admin
Client -p 8080 deploy.wsdd
ファイルdeploy.wsddの処理中 / [en]-(Processing file deploy.wsdd)
<Admin>処理を実行しました / [en]-(Done processing)</Admin>
図 7.5 デプロイの実行
ここまでの作業によってデプロイが完了した。ここで実際にメソッドが登録されたかブ
ラウザ上で確認する事が出来る(図 7.6)。これは Apache Axis による機能で、指定 URL4に
アクセスすることで確認できる。
図 7.6 デプロイの確認
以上によりサーバ側 Web サービスの実装が終了した。
4
通常では http://localhost:8080/axis/servlet/AxisServlet となっている。
36
7.5. クライアント側 Web アプリケーション
本節ではクライアント側 Web アプリケーションの実装を開発工程に沿って説明していく。
7.5.1. WSDL 文書の取得
クライアントは利用する Web サービスの WSDL 文書をあらかじめ取得していなければ
ならない。本論文ではコマンドによって取得する(図 7.7)。
C:\axis-1_3\Thesis\Electric_chart_sharing_system>java org.apache.axis.wsdl.Java2
WSDL -o ChartSearchService.wsdl
-l "http://localhost:8080/axis/services/urn:ChartSearchService"
-n "urn:ChartSearchService"
-p"medical_service" "urn:medical_service"
-m "search","hasNext","getNext","operateOpenChart","getChartObject","operateOpen
PatientInfo","getPatientObject" medical_service.ChartSearchService
C:\axis-1_3\Thesis\Electric_chart_sharing_system>
図 7.7 WSDL 文書の取得
以上のコマンドによって WSDL 文書の取得が完了する。
7.5.2. スタブの生成
スタブとはあるプログラムが他のプログラムを呼び出す際に仲介となるプログラムのこ
とである。Web サービスでは Apache Axis を用いることで WSDL 文書からスタブを生成す
ることが出来る。生成されたスタブはクライアント側のローカルに保存され、クライアン
トはあたかもローカルのメソッドを呼び出しているかのような方法で Web サービスを呼び
出すことができる。
以下のコマンドによってスタブを生成できる(図 7.8)。
C:\axis-1_3\Thesis\Electric_chart_sharing_system>java org.apache.axis.wsdl.WSDL2
Java -p stub -d Session ChartSearchService.wsdl
C:\axis-1_3\Thesis\Electric_chart_sharing_system>
図 7.8 スタブの生成
37
7.5.3. コーディング
クライアント側 Web アプリケーションのコーディングは JSP によって行われる。機能は
主に次の 4 点が挙げられる。

ユーザに患者の姓の入力を促す。

Web サービス側へ患者の姓と検索命令を送信する

Web サービス側アプリケーションから返されたデータを取得する

結果を表示する
また電子カルテ共有システムではカルテ一覧、カルテ詳細内容、患者基本情報を閲覧で
きるように開発した。ソースコードは附録にて添付する。
7.6. 実行結果
ユーザの操作手順に従って説明する。
はじめにトップ画面にて検索したい患者の姓を入力する。ここでは「村田」が入力され
ている。入力が完了したら検索ボタンを押す。
図 7.9 トップ画面
38
検索ボタンが押されると患者名(姓)
「村田」に該当するカルテ一覧が表示される。一覧
画面にはカルテ No、カルテの作成日、医療機関名、担当医、診断病名が表示される。
図 7.10 検索結果画面
カルテ No にはリンクが貼られており、番号をクリックするとカルテの詳細が閲覧できる
(図 7.11)。
39
****
**
図 7.11 カルテ詳細画面
上図はカルテ No:1030 に関するカルテのデータである。カルテ詳細画面では患者基本情
報(一部)とカルテ作成者、医療機関名、確定保存日と診断等が記載されている。患者基
本情報というボタンを押すと更に詳細な患者の情報が閲覧できる(図 7.12)
。
カルテ画面下部の S(患者主訴)
、O(所見)、A(診断)、P(計画)とはカルテ記入の際
に頻繁に用いられている記載方法である。それぞれ Subjective、Objective、Assessment、
Plan の略称である。
40
図 7.12 患者基本情報画面
以上が電子カルテ共有システムの実行結果である。
41
8. 結論
本研究では医療界の現状を踏まえ、Web サービスとデザインパターンの技術を導入した
電子カルテ共有システムを開発した。
第 2 章では医療界で導入されているシステムを通じて現状を分析し、医療情報の標準化
が図られていることを確認した。
第 3 章では第 2 章で明らかになった問題を定義し、電子カルテ共有システムの提案と意
義を考察した。
第 4 章では情報共有を実現する Web サービス技術について詳述した。また Apache Axis
を用いることで Web サービスを容易に実現させる仕組みを明らかにした。
第 5 章ではデザインパターンを概観した。また本論文で導入した Iterator パターンにつ
いてクラス図とともに役割とその特徴を紹介した。
第 6 章では電子カルテ共有システムの分析と設計を行った。はじめに UML の分析手法を
確認し、第 2 節および第 3 節にて電子カルテ共有システムの 3 つの機能を分析、設計した。
そして第 4 節では Iterator パターンを適用し、クラス図の変化と保守性・再利用性の向上
について説明した。
第 7 章では具体的な実装について開発手順に沿った解説を行った。また本研究で用いた
開発ツールについても特徴と利点を説明した。第 3 節では医療情報の標準化を踏まえたデ
ータモデルの開発を行い、第 6 節ではユーザの立場での操作仕様を各画面の図とともに紹
介した。
以上から本研究では Web サービスを用いてカルテ情報を共有するシステムの提案・開発
を行った。またデータモデルの一部を医療界標準規格になりつつある MML と ICD-10 に準
拠させ、将来の医療界に適用可能なシステムを開発した。さらにプログラムの保守・再利
用性を高めるためにデザインパターンを採用した。これはシステムの保守作業時間を短縮
させ、コストパフォーマンスの改善を図ることが期待できる。以上のシステム開発を通じ
て、医療機関間でカルテ情報を共有する仕組みを明らかにした。
42
参考文献
[1] 池田正見、上野滋、大瀧誠、小塚和人、古屋好美、南山貴芳 著 「これからの電子医療
情報学~電子カルテの実際から医療連携システムの構築まで~」森北出版株式会社
2005.1.17 P100 図 2.14
[2] 特定非営利活動法人 MedXML コンソーシアム
http://www.medxml.net/, 2006.1.16
[3] World Health Organization
http://www3.who.int/icd/vol1htm2003/fr-icd.htm, 2006.1.24
[4] 本俊也 著 「詳解 Web サービス構築
次世代インターネット相互運用テクノロジーの
基礎と実践」ソフトバンクパブリッシング株式会社 2003.4.7 P32 fig3-6
[5] 株式会社日本ユニテック Digital Xpress 編集部 著 「SOAP/UDDI/WSDL Web サービ
ス技術 [基礎と実践] 徹底解説」株式会社技術評論社 2002.12.25 P140 図 6-3
[6] ネットワークプログラミングにおける各種パターン HORB デザインパターンの収集
http://www.horbopen.org/hq/Sympo-3/article/horb_conf2000.PDF, 2005.9.16
[7] 結城浩 著 「増補改訂版 Java 言語で学ぶデザインパターン入門」ソフトバンクパブ
リッシング株式会社 2005.3.31
[8] 佐原伸 著 「デザインパターン オブジェクト指向分析/設計技法」株式会社ソフト・リ
サーチ・センター 1999.5.25
[9] スタックアスタリスク IT エンジニア総合支援サイト 今日から始める UML モデリン
グ(UML2.0 版)
http://www.stackasterisk.jp/tech/engineer/uml03_02.jsp#2, 2006.1.24
[10] 財団法人医療情報システム開発センター
http://www.medis.or.jp/index.html, 2006.1.6
[11] 石田豊 著 「MySQL 入門以前」株式会社毎日コミュニケーションズ 2005.6.15
[12] 笠井謙一 著 「「設計の原理」を利用した研究室の知的情報管理システムの構築」筑波
大学第三学群社会工学類 平成 16 年度卒業論文 2005.1.26
43
[13] 土井隆寛 著 「Web サービスを用いた小売業・製造業間データ共有システムの構築」
筑波大学第三学群社会工学類 平成 16 年度卒業論文 2005.1.26
[14] 北村俊宏 著 「理容室における顧客管理と顧客サービスシステムの構築」筑波大学第
三学群社会工学類 平成 15 年度卒業論文 2004.1.28
[15] 鎌形俊幸 著 「レシピで選ぶ食料品注文システムの構築~Web サービスによるシステ
ム連携~」筑波大学第三学群社会工学類 平成 15 年度卒業論文 2004.1.28
[16] 前田杏奈 著 「Web サービスによるナレッジマネジメント 研究室における知識資源
のナレッジベース化」筑波大学第三学群社会工学類 平成 14 年度卒業論文 2003.1.29
[17] 小西敏郎、石原照夫 著 「電子カルテとクリティカルパスで医療が変わる 今始まる、
21 世紀の医療改革」株式会社インターメディカ 2004.3.25
[18] 中所武司、藤原克哉 著 「Information & Computing-104 Java による Web アプリ
ケーション入門-サーブレット・JSP・Struts-」株式会社サイエンス社 2005.2.10
[19] Programing Note
http://www.geocities.jp/woodstock_tomo/programing/, 2006.1.24
[20] Apache Web Services Wiki
http://wiki.apache.org/ws/FrontPage/Axis/AxisGeneral, 2006.1.20
[21] Java で Hello World! JDBC(MySQL)編
http://www.hellohiro.com/jdbcmysql.htm, 2005.12.7
44
謝辞
本研究全般に渡り、温かく親切にご指導頂きました佐藤亮先生に心から感謝申し上げま
す。またヒアリング調査を快く受諾して下さいました樋之津史郎先生、大変お忙しい中貴
重なご意見を賜りました我妻ゆき子先生、岡田昌史先生に厚く御礼申し上げます。
そして同じ研究室で日頃から細かなことに気付き的確な助言を与えてくれた大村君、特
に技術的な面で行き詰ったときに粘り強く相談に乗ってくれた土橋君、客観的な視点から
公平な意見と良き刺激を与えてくれた湯山君、そしていつも明るく場を和ませてください
ました川西さんをはじめ、豊富な知識と精神的な面でサポートをして下さった先輩方に深
く感謝致します。
最後に、本研究のみでなく大学生活全般においても支え続けてくれた父と母、そして兄
に感謝します。
45
附録
A) Web サービス側 Java プログラム
[ File: Aggregate.java ]
package medical_service;
public interface Aggregate {
public abstract Iterator iterator();
}
[ File: Iterator.java ]
package medical_service;
public interface Iterator {
public abstract boolean hasNext();
public abstract ItemBean[] getNext();
}
[ File: SearchResult.java ]
package medical_service;
import java.util.ArrayList;
import medical_service.ItemBean;
public class SearchResult implements Aggregate{
private ArrayList itemList;
public SearchResult() {
itemList = new ArrayList();
}
public void add(ItemBean item){
itemList.add(item);
}
public int getCount(){
return itemList.size();
}
public ItemBean getChartAt(int index){
return (ItemBean)itemList.get(index);
}
}
public Iterator iterator() {
return new SearchResultIterator(this);
}
[ File: SearchResultIterator.java ]
package medical_service;
public class SearchResultIterator implements Iterator {
private SearchResult sresult;
private int itemIndex;
private int itemsize;
public SearchResultIterator(SearchResult sresult) {
this.sresult = sresult;
this.itemIndex = 0;
this.itemsize = 5;
}
public boolean hasNext(){
return sresult.getCount() > itemIndex;
}
}
public ItemBean[] getNext(){
int isize = sresult.getCount() - itemIndex;
if(isize > itemsize) isize = itemsize;
ItemBean[] items = new ItemBean[isize];
for(int i=0; i<isize; i++){
items[i] = (ItemBean)sresult.getChartAt(itemIndex + i);
}
itemIndex += isize;
return items;
}
46
[ File: ItemBean.java ]
package medical_service;
public class ItemBean
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
implements java.io.Serializable{
int date;
String nameOfInstitution;
String staffLastNameKanji;
String staffFirstNameKanji;
String nameOfDisease;
int chartId;
int patientId;
String patientLastNameKanji;
String patientFirstNameKanji;
String patientLastNameAlphabet;
String patientFirstNameAlphabet;
int birthday;
String sexDescription;
String bloodTypeABO;
String bloodTypeRho;
String qualificationDescription;
String department;
String staffLastNameKanjiInEachChart;
String staffFirstNameKanjiInEachChart;
String nameOfInstitutionInEachChart;
int dateInEachChart;
String subject;
String object;
String assessment;
String plan;
private String telephoneNum;
private String address;
private String maritalStatus;
private ItemBean chartObject;
private ItemBean patientObject;
public ItemBean(){
}
public void setChartId(int chartId){
this.chartId = chartId;
}
public int getChartId(){
return chartId;
}
public void setDate(int date){
this.date = date;
}
public int getDate(){
return date;
}
public void setNameOfInstitution(String nameOfInstitution){
this.nameOfInstitution = nameOfInstitution;
}
public String getNameOfInstitution(){
return nameOfInstitution;
}
public void setStaffLastNameKanji(String staffLastNameKanji){
this.staffLastNameKanji = staffLastNameKanji;
}
public String getStaffLastNameKanji(){
return staffLastNameKanji;
}
public void setStaffFirstNameKanji(String staffFirstNameKanji){
this.staffFirstNameKanji = staffFirstNameKanji;
}
public String getStaffFirstNameKanji(){
return staffFirstNameKanji;
}
public void setNameOfDisease(String nameOfDisease){
this.nameOfDisease = nameOfDisease;
}
public String getNameOfDisease(){
return nameOfDisease;
}
//-------------------------------------------------(patientLastNameKanji を除く)----public void setPatientId(int patientId){
this.patientId = patientId;
}
public int getPatientId(){
return patientId;
}
public void setPatientLastNameKanji(String patientLastNameKanji){
this.patientLastNameKanji = patientLastNameKanji;
}
public String getPatientLastNameKanji(){
return patientLastNameKanji;
}
47
public void setPatientFirstNameKanji(String patientFirstNameKanji){
this.patientFirstNameKanji = patientFirstNameKanji;
}
public String getPatientFirstNameKanji(){
return patientFirstNameKanji;
}
public void setPatientLastNameAlphabet(String patientLastNameAlphabet){
this.patientLastNameAlphabet = patientLastNameAlphabet;
}
public String getPatientLastNameAlphabet(){
return patientLastNameAlphabet;
}
public void setPatientFirstNameAlphabet(String patientFirstNameAlphabet){
this.patientFirstNameAlphabet = patientFirstNameAlphabet;
}
public String getPatientFirstNameAlphabet(){
return patientFirstNameAlphabet;
}
public void setBirthday(int birthday){
this.birthday = birthday;
}
public int getBirthday(){
return birthday;
}
public void setSexDescription(String sexDescription){
this.sexDescription = sexDescription;
}
public String getSexDescription(){
return sexDescription;
}
public void setBloodTypeABO(String bloodTypeABO){
this.bloodTypeABO = bloodTypeABO;
}
public String getBloodTypeABO(){
return bloodTypeABO;
}
public void setBloodTypeRho(String bloodTypeRho){
this.bloodTypeRho = bloodTypeRho;
}
public String getBloodTypeRho(){
return bloodTypeRho;
}
public void setQualificationDescription(String qualificationDescription){
this.qualificationDescription = qualificationDescription;
}
public String getQualificationDescription(){
return qualificationDescription;
}
public void setDepartment(String department){
this.department = department;
}
public String getDepartment(){
return department;
}
public void setStaffLastNameKanjiInEachChart(String staffLastNameKanjiInEachChart){
this.staffLastNameKanjiInEachChart = staffLastNameKanjiInEachChart;
}
public String getStaffLastNameKanjiInEachChart(){
return staffLastNameKanjiInEachChart;
}
public void setStaffFirstNameKanjiInEachChart(String staffFirstNameKanjiInEachChart){
this.staffFirstNameKanjiInEachChart = staffFirstNameKanjiInEachChart;
}
public String getStaffFirstNameKanjiInEachChart(){
return staffFirstNameKanjiInEachChart;
}
public void setNameOfInstitutionInEachChart(String nameOfInstitutionInEachChart){
this.nameOfInstitutionInEachChart = nameOfInstitutionInEachChart;
}
public String getNameOfInstitutionInEachChart(){
return nameOfInstitutionInEachChart;
}
public void setDateInEachChart(int dateInEachChart){
this.dateInEachChart = dateInEachChart;
}
public int getDateInEachChart(){
return dateInEachChart;
}
public void setSubject(String subject){
this.subject = subject;
}
public String getSubject(){
48
}
return subject;
public void setObject(String object){
this.object = object;
}
public String getObject(){
return object;
}
public void setAssessment(String assessment){
this.assessment = assessment;
}
public String getAssessment(){
return assessment;
}
public void setPlan(String plan){
this.plan = plan;
}
public String getPlan(){
return plan;
}
//------------------------------------------------------------------------------public void setTelephoneNum(String telephoneNum){
this.telephoneNum = telephoneNum;
}
public String getTelephoneNum(){
return telephoneNum;
}
public void setAddress(String address){
this.address = address;
}
public String getAddress(){
return address;
}
public void setMaritalStatus(String maritalStatus){
this.maritalStatus = maritalStatus;
}
public String getMaritalStatus(){
return maritalStatus;
}
//------------------------------------------------------------------------------public void setChartObject(ItemBean chartObject){
this.chartObject = chartObject;
}
public ItemBean getChartObject(){
return chartObject;
}
public void setPatientObject(ItemBean patientObject){
this.patientObject = patientObject;
}
}
public ItemBean getPatientObject(){
return patientObject;
}
[ File: ChartSearchService.java ]
package medical_service;
import java.sql.*;
import java.io.*;
import org.apache.axis.transport.http.AxisHttpSession;
import org.apache.axis.MessageContext;
import medical_service.ItemBean;
import medical_service.SearchResult;
public class ChartSearchService {
private String sql="";
private SearchResult sresult = null;
private ItemBean cObject = null;
private ItemBean pObject = null;
private Iterator it = null;
public int search(String keyword){
sresult = searchItem(keyword);
it = sresult.iterator();
System.out.println(sresult.getCount());
return sresult.getCount();
}
public boolean hasNext(){
return sresult == null ? false : it.hasNext();
}
public ItemBean[] getNext(){
return sresult == null ? null : it.getNext();
}
49
public void operateOpenChart(int chartId){
cObject = openChart(chartId);
}
public ItemBean getChartObject(){
return cObject.getChartObject();
}
public void operateOpenPatientInfo(int patientId){
pObject = openPatientInfo(patientId);
}
public ItemBean getPatientObject(){
return pObject.getPatientObject();
}
private int searchPatientId(String keyword){
int sPatientId = 0;
try {
// ドライバクラスをロード
Class.forName("com.mysql.jdbc.Driver"); // MySQL の場合
sql = new String("select patient.patient_id, patient.patient_last_name_kanji from patient;");
// データベースへ接続
String url = "jdbc:mysql:///thesis?useUnicode=true&characterEncoding=SJIS";
Connection con = DriverManager.getConnection(url,"thesis","*****");
// ステートメントオブジェクトを生成
Statement stmt = con.createStatement();
// クエリーを実行して結果セットを取得
ResultSet rs = stmt.executeQuery(sql);
// 検索された行数分ループ
while(rs.next()){
//患者名を取得
String sPatientLastNameKanji = rs.getString("patient_last_name_kanji");
if(sPatientLastNameKanji.indexOf(keyword)>-1){
sPatientId = rs.getInt("patient_id");
}
}
}
// データベースから切断
stmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
return sPatientId;
private SearchResult searchItem(String keyword){
SearchResult alist = new SearchResult();
int sPatientId = searchPatientId(keyword);
try {
// ドライバクラスをロード
Class.forName("com.mysql.jdbc.Driver"); // MySQL の場合
sql
=
new
String("select
patient.patient_last_name_kanji,chart.chart_id,chart.date,medical_institution.name_of_institution,medical_staff.staff_last_name_kanji,medical
_staff.staff_first_name_kanji,
disease.name_of_disease
from
chart,patient,medical_institution,medical_staff,disease,
combination_of_patient_and_disease
where
chart.patient_id=patient.patient_id
and
patient.patient_id="+sPatientId+"
and
medical_institution.institution_id=chart.institution_id
and
chart.doctor_id=medical_staff.medical_staff_id
and
disease.disease_id=combination_of_patient_and_disease.disease_id and combination_of_patient_and_disease.chart_id=chart.chart_id order by
date;");
// データベースへ接続
String url = "jdbc:mysql:///thesis?useUnicode=true&characterEncoding=SJIS";
Connection con = DriverManager.getConnection(url,"thesis","*****");
// ステートメントオブジェクトを生成
Statement stmt = con.createStatement();
// クエリーを実行して結果セットを取得
ResultSet rs = stmt.executeQuery(sql);
// 検索された行数分ループ
while(rs.next()){
//患者名を取得
String patientLastNameKanji = rs.getString("patient_last_name_kanji");
//カルテ ID を取得
int chartId = rs.getInt("chart_id");
// カルテ作成日を取得
int date = rs.getInt("date");
// 医療機関名を取得
String nameOfInstitution = rs.getString("name_of_institution");
// 医療従事者名を取得
String staffLastNameKanji = rs.getString("staff_last_name_kanji");
String staffFirstNameKanji = rs.getString("staff_first_name_kanji");
// 病名を取得
String nameOfDisease = rs.getString("name_of_disease");
}
}
//ItemBean クラスを用いてひとつのカルテを生成。カルテ自体は SearchResult 型オブジェクト。
ItemBean item = new ItemBean();
item.setPatientLastNameKanji(patientLastNameKanji);
item.setChartId(chartId);
item.setDate(date);
item.setNameOfInstitution(nameOfInstitution);
item.setStaffLastNameKanji(staffLastNameKanji);
item.setStaffFirstNameKanji(staffFirstNameKanji);
item.setNameOfDisease(nameOfDisease);
alist.add(item);
// データベースから切断
stmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
return alist;
private ItemBean openChart(int chartId){
ItemBean chartPaper = new ItemBean();
try {
// ドライバクラスをロード
Class.forName("com.mysql.jdbc.Driver"); // MySQL の場合
50
sql
=
new
String("select
chart.chart_id,chart.patient_id,patient.patient_last_name_kanji,patient.patient_last_name_alphabet,patient.patient_first_name_kanji,patient.p
atient_first_name_alphabet,patient.birthday,sex.sex_description,blood_type_ABO.blood_type_ABO,blood_type_Rho.blood_type_Rho,qualification.qua
lification_description,medical_department.department,medical_staff.staff_last_name_kanji,medical_staff.staff_first_name_kanji,medical_institu
tion.name_of_institution,chart.date,chart.subject,chart.object,chart.assessment,chart.plan
from
chart,patient,sex,blood_type_ABO,blood_type_Rho,qualification,medical_staff,medical_department,staff_belonging,medical_institution
where
chart.chart_id="+chartId+"
and
patient.patient_id=chart.patient_id
and
sex.sex_id=patient.sex
and
blood_type_ABO.blood_type_id_ABO=patient.blood_type_ABO
and
blood_type_Rho.blood_type_id_Rho=patient.blood_type_Rho
and
qualification.qualification_id=medical_staff.qualification_id
and
medical_staff.medical_staff_id=chart.doctor_id
and
medical_department.department_id=staff_belonging.department_id
and
staff_belonging.medical_staff_id=medical_staff.medical_staff_id
and
medical_institution.institution_id=chart.institution_id;");
// データベースへ接続
String url = "jdbc:mysql:///thesis?useUnicode=true&characterEncoding=SJIS";
Connection con = DriverManager.getConnection(url,"thesis","*****");
// ステートメントオブジェクトを生成
Statement stmt = con.createStatement();
// クエリーを実行して結果セットを取得
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()){
// カルテ ID を取得
int chartId1 = rs.getInt("chart_id");
// 患者 ID を取得
int patientId = rs.getInt("patient_id");
// 患者名を取得
String patientLastNameKanji = rs.getString("patient_last_name_kanji");
String patientFirstNameKanji = rs.getString("patient_first_name_kanji");
String patientLastNameAlphabet = rs.getString("patient_last_name_alphabet");
String patientFirstNameAlphabet = rs.getString("patient_first_name_alphabet");
// 患者の生年月日を取得
int birthday = rs.getInt("birthday");
// 患者の性別を取得
String sexDescription = rs.getString("sex_description");
// 患者の血液型を取得
String bloodTypeABO = rs.getString("blood_type_ABO");
String bloodTypeRho = rs.getString("blood_type_Rho");
// 医療従事者の資格名を取得
String qualificationDescription = rs.getString("qualification_description");
// 医療従事者の専門科を取得
String department = rs.getString("department");
// 医療従事者名を取得
String staffLastNameKanjiInEachChart = rs.getString("staff_last_name_kanji");
String staffFirstNameKanjiInEachChart = rs.getString("staff_first_name_kanji");
// 医療機関名を取得
String nameOfInstitutionInEachChart = rs.getString("name_of_institution");
// カルテ作成日を取得
int dateInEachChart = rs.getInt("date");
// カルテの患者主訴を取得
String subject = rs.getString("subject");
// カルテの医師所見を取得
String object = rs.getString("object");
// カルテの医師診断を取得
String assessment = rs.getString("assessment");
// カルテの治療計画を取得
String plan = rs.getString("plan");
ItemBean chartObject = new ItemBean();
chartObject.setChartId(chartId1);
chartObject.setPatientId(patientId);
chartObject.setPatientLastNameKanji(patientLastNameKanji);
chartObject.setPatientFirstNameKanji(patientFirstNameKanji);
chartObject.setPatientLastNameAlphabet(patientLastNameAlphabet);
chartObject.setPatientFirstNameAlphabet(patientFirstNameAlphabet);
chartObject.setBirthday(birthday);
chartObject.setSexDescription(sexDescription);
chartObject.setBloodTypeABO(bloodTypeABO);
chartObject.setBloodTypeRho(bloodTypeRho);
chartObject.setQualificationDescription(qualificationDescription);
chartObject.setDepartment(department);
chartObject.setStaffLastNameKanjiInEachChart(staffLastNameKanjiInEachChart);
chartObject.setStaffFirstNameKanjiInEachChart(staffFirstNameKanjiInEachChart);
chartObject.setNameOfInstitutionInEachChart(nameOfInstitutionInEachChart);
chartObject.setDateInEachChart(dateInEachChart);
chartObject.setSubject(subject);
chartObject.setObject(object);
chartObject.setAssessment(assessment);
chartObject.setPlan(plan);
chartPaper.setChartObject(chartObject);
}
}
// データベースから切断
stmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
return chartPaper;
private ItemBean openPatientInfo(int patientId){
ItemBean patient = new ItemBean();
try {
// ドライバクラスをロード
Class.forName("com.mysql.jdbc.Driver"); // MySQL の場合
sql
=
new
String("select
patient.patient_id,patient.patient_last_name_kanji,patient.patient_last_name_alphabet,patient.patient_first_name_kanji,patient.patient_first_
name_alphabet,patient.birthday,sex.sex_description,blood_type_ABO.blood_type_ABO,blood_type_Rho.blood_type_Rho,patient.telephone_num,patient.
address,marital_status.status from patient,sex,blood_type_ABO,blood_type_Rho,marital_status where patient.patient_id="+patientId+" and
sex_id=patient.sex and blood_type_ABO.blood_type_id_ABO=patient.blood_type_ABO and blood_type_Rho.blood_type_id_Rho=patient.blood_type_Rho and
marital_status.status_id=patient.marital_status;");
// データベースへ接続
String url = "jdbc:mysql:///thesis?useUnicode=true&characterEncoding=SJIS";
Connection con = DriverManager.getConnection(url,"thesis","*****");
// ステートメントオブジェクトを生成
Statement stmt = con.createStatement();
// クエリーを実行して結果セットを取得
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()){
51
//
//
// 患者 ID を取得
int patientId = rs.getInt("patient_id");
// 患者名を取得
String patientLastNameKanji = rs.getString("patient_last_name_kanji");
String patientFirstNameKanji = rs.getString("patient_first_name_kanji");
String patientLastNameAlphabet = rs.getString("patient_last_name_alphabet");
String patientFirstNameAlphabet = rs.getString("patient_first_name_alphabet");
// 患者の生年月日を取得
int birthday = rs.getInt("birthday");
// 患者の性別を取得
String sexDescription = rs.getString("sex_description");
// 患者の血液型を取得
String bloodTypeABO = rs.getString("blood_type_ABO");
String bloodTypeRho = rs.getString("blood_type_Rho");
// 患者の電話番号を取得
String telephoneNum = rs.getString("telephone_num");
// 患者の住所を取得
String address = rs.getString("address");
// 患者の婚姻状態を取得
String maritalStatus = rs.getString("status");
ItemBean patientObject = new ItemBean();
patientObject.setPatientId(patientId);
patientObject.setPatientLastNameKanji(patientLastNameKanji);
patientObject.setPatientFirstNameKanji(patientFirstNameKanji);
patientObject.setPatientLastNameAlphabet(patientLastNameAlphabet);
patientObject.setPatientFirstNameAlphabet(patientFirstNameAlphabet);
patientObject.setBirthday(birthday);
patientObject.setSexDescription(sexDescription);
patientObject.setBloodTypeABO(bloodTypeABO);
patientObject.setBloodTypeRho(bloodTypeRho);
patientObject.setTelephoneNum(telephoneNum);
patientObject.setAddress(address);
patientObject.setMaritalStatus(maritalStatus);
patient.setPatientObject(patientObject);
}
}
}
// データベースから切断
stmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
return patient;
52
B) Web アプリケーション側 Java プログラム
[ File: thesisPotal.html ]
<html>
<head><title>電子カルテ共有システム</title></head>
<body>
<hr>
<br>
<font size=5 color="#696969">電子カルテ共有システム</font>
<br>
<font size=1>卒業論文製作システム</font>
<br>
<form action="/thesisPotal/ViewResult.jsp" method="post">
<b>患者の姓を入力してください。</b><br>
キーワード: <input type="text" id="keyword" name="keyword" value="村田">
<input type="submit" id="submit" name="submit" value="検索">
</form>
<hr>
<font size=1>
<i>電子カルテ共有システムの実現 ~デザインパターンと Web サービスの適用~<br>
筑波大学第三学群社会工学類
村田 洋</i><br>
</font>
</body>
</html>
[ File: ViewResult.jsp ]
<%@ page contentType="text/html; charset=Shift_JIS" pageEncoding="Shift_JIS" %>
<%@ page import='stub.*' session='true' %>
<html>
<head><title>電子カルテ共有システム 検索結果</title></head>
<body>
<hr>
<br>
<font size=5 color="#696969">電子カルテ共有システム
<br>
<font size=1>卒業論文製作システム</font>
<br>
<br>
<%
検索結果</font>
stub.ChartSearchService port = (stub.ChartSearchService)session.getAttribute("PORT");
if(port == null){
port = new ChartSearchServiceServiceLocator().getUrnChartSearchService();
((UrnChartSearchServiceSoapBindingStub)port).setMaintainSession(true);
String param=request.getParameter("keyword");
String keyword=new String(param.getBytes("iso-8859-1"),"Shift_JIS");
if(port.search(keyword)<1){
session.setAttribute("KEYWORD", keyword);
%>
<jsp:forward page="./ViewDnetResult.jsp" />
<%
}
%>
<%
<%
if(port.hasNext()){
stub.ItemBean[] items = port.getNext();
<b>
out.println(items[0].getPatientLastNameKanji());%>
様のカルテを表示します。</b><br><br>
<table id="result" width="650" border="1">
<tr>
<td><p align="center">カルテ No</p></td>
<td><p align="center">日付</p></td>
<td><p align="center">医療機関名</p></td>
<td><p align="center">担当医(姓)</p></td>
<td><p align="center">担当医(名)</p></td>
<td><p align="center">病名</p></td>
</tr>
"\">"+s1+"</a></p></td>");
%>
<%
}
session.setAttribute("PORT", port);
}
String s1, s2, s3, s4, s5, s6;
for(int i=0; i<items.length; i++){
out.println("<tr>");
s1 = String.valueOf(items[i].getChartId());
s2 = String.valueOf(items[i].getDate());
s3 = items[i].getNameOfInstitution();
s4 = items[i].getStaffLastNameKanji();
s5 = items[i].getStaffFirstNameKanji();
s6 = items[i].getNameOfDisease();
out.println("<td><p
align=\"center\"><a
}
out.println("<td><p align=\"center\">"
out.println("<td><p align=\"center\">"
out.println("<td><p align=\"center\">"
out.println("<td><p align=\"center\">"
out.println("<td><p align=\"center\">"
out.println("</tr>");
</table>
53
+
+
+
+
+
s2
s3
s4
s5
s6
href
+
+
+
+
+
=
\"ViewChart.jsp?keyword="
"</p></td>");
"</p></td>");
"</p></td>");
"</p></td>");
"</p></td>");
+
s1
+
%>
<%
%>
<%
%>
if(port.hasNext()){
<form action="/thesisPotal/ViewResult.jsp" method="post">
<input type="submit" id="submit" name="submit" value="次を表示">
</form>
}
else{
session.invalidate();
<p><a href="/thesisPotal/thesisPotal.html">
<font size="4"><b>検索ページへ戻る</b></font>
</p></a>
}
<hr>
<font size=1>
<i>電子カルテ共有システムの実現 ~デザインパターンと Web サービスの適用~<br>
筑波大学第三学群社会工学類
村田 洋</i><br>
</font>
</body>
</html>
[ File: ViewChart.jsp ]
<%@ page contentType="text/html; charset=Shift_JIS" pageEncoding="Shift_JIS" %>
<%@ page import='stub.*' session='true' %>
<html>
<head><title>電子カルテ共有システム カルテ画面</title></head>
<body>
<hr>
<br>
<font size=5 color="#696969">電子カルテ共有システム
<br>
<font size=1>卒業論文製作システム</font>
<br>
<br>
<%
stub.ChartSearchService port = (stub.ChartSearchService)session.getAttribute("PORT");
stub.ItemBean chartObjects = null;
if(port == null){
port = new ChartSearchServiceServiceLocator().getUrnChartSearchService();
((UrnChartSearchServiceSoapBindingStub)port).setMaintainSession(true);
String param = request.getParameter("keyword");
int keyword = Integer.parseInt(param);
%>
<%
<b>カルテ No:
out.println(keyword);%>
の情報を表示します。</b><br><br>
<%
port.operateOpenChart(keyword);
chartObjects = port.getChartObject();
if(chartObjects==null){
session.setAttribute("KEYWORD", keyword);
%>
<jsp:forward page="./ViewDnetResult.jsp" />
<%
%>
<%
カルテ画面</font>
}
}
session.setAttribute("PORT", port);
<table id="result" width="700" border="1">
<tr>
<td><p align="center"><img src="/thesisPotal/images/patient.bmp"></p></td>
<td><p align="center">カルテ No</p></td>
<td><p align="center">患者 ID</p></td>
<td><p align="center">患者(姓)</p></td>
<td><p align="center">よみ</p></td>
<td><p align="center">患者(名)</p></td>
<td><p align="center">よみ</p></td>
<td><p align="center">生年月日</p></td>
<td><p align="center">性別</p></td>
<td><p align="center">血液型</p></td>
<td><p align="center">Rh</p></td>
</tr>
String s1, s2, s3, s4, s5, s6, s7, s8, s9, s10;
s1 = String.valueOf(chartObjects.getChartId());
s2 = String.valueOf(chartObjects.getPatientId());
s3 = chartObjects.getPatientLastNameKanji();
s4 = chartObjects.getPatientLastNameAlphabet();
s5 = chartObjects.getPatientFirstNameKanji();
s6 = chartObjects.getPatientFirstNameAlphabet();
s7 = String.valueOf(chartObjects.getBirthday());
s8 = chartObjects.getSexDescription();
s9 = chartObjects.getBloodTypeABO();
s10 = chartObjects.getBloodTypeRho();
out.println("<tr><td><p align=\"center\"><form action=\"/thesisPotal/ViewPatientInfo.jsp?keyword="+s2+"\" method=\"post\"><input
type=\"submit\" id=\"submit\" name=\"submit\" value=\"患者基本情報\"></form></p></td>");
out.println("<td><p align=\"center\">" + s1 + "</p></td>");
out.println("<td><p align=\"center\">" + s2 + "</p></td>");
54
%>
<%
%>
<%
%>
<%
<%
<%
<%
<%
%>
out.println("<td><p align=\"center\">"
out.println("<td><p align=\"center\">"
out.println("<td><p align=\"center\">"
out.println("<td><p align=\"center\">"
out.println("<td><p align=\"center\">"
out.println("<td><p align=\"center\">"
out.println("<td><p align=\"center\">"
out.println("<td><p align=\"center\">"
out.println("</tr>");
+
+
+
+
+
+
+
+
s3 + "</p></td>");
s4 + "</p></td>");
s5 + "</p></td>");
s6 + "</p></td>");
s7 + "</p></td>");
s8 + "</p></td>");
s9 + "</p></td>");
s10 + "</p></td>");
</table>
<br>カルテ作成者:
out.println(chartObjects.getQualificationDescription()+"
");
out.println(chartObjects.getDepartment()+"
");
out.println(chartObjects.getStaffLastNameKanjiInEachChart() + chartObjects.getStaffFirstNameKanjiInEachChart());
out.println("<br>カルテ作成医療機関: ");
out.println(chartObjects.getNameOfInstitutionInEachChart());
out.println("<br>カルテ確定保存日: ");
out.println(chartObjects.getDateInEachChart());
<br><br>
String s11, s12, s13, s14;
s11 = chartObjects.getSubject();
s12 = chartObjects.getObject();
s13 = chartObjects.getAssessment();
s14 = chartObjects.getPlan();
<table id="result" width="700" border="1">
<tr>
<td><p align="center">S<br>(患者主訴)</p></td>
out.println("<td><p align=\"center\">" + s11 + "</p></td>");%>
</tr>
<tr>
<td><p align="center">O<br>(所見)</p></td>
out.println("<td><p align=\"center\">" + s12 + "</p></td>");%>
</tr>
<tr>
<td><p align="center">A<br>(診断)</p></td>
out.println("<td><p align=\"center\">" + s13 + "</p></td>");%>
</tr>
<tr>
<td><p align="center">P<br>(計画)</p></td>
out.println("<td><p align=\"center\">" + s14 + "</p></td>");%>
</tr>
</table>
session.invalidate();
<br><br>
<p><a href="/thesisPotal/thesisPotal.html">
<font size="4"><b>検索ページへ戻る</b></font>
</p></a>
<hr>
<font size=1>
<i>電子カルテ共有システムの実現 ~デザインパターンと Web サービスの適用~<br>
筑波大学第三学群社会工学類
村田 洋</i><br>
</font>
</body>
</html>
[ File: ViewPatientInfo.jsp ]
<%@ page contentType="text/html; charset=Shift_JIS" pageEncoding="Shift_JIS" %>
<%@ page import='stub.*' session='true' %>
<html>
<head><title>電子カルテ共有システム 患者基本情報</title></head>
<body>
<hr>
<br>
<font size=5 color="#696969">電子カルテ共有システム
<br>
<font size=1>卒業論文製作システム</font>
<br>
<br>
<%
患者基本情報</font>
stub.ChartSearchService port = (stub.ChartSearchService)session.getAttribute("PORT");
stub.ItemBean patientObjects = null;
if(port == null){
port = new ChartSearchServiceServiceLocator().getUrnChartSearchService();
((UrnChartSearchServiceSoapBindingStub)port).setMaintainSession(true);
String param = request.getParameter("keyword");
int keyword = Integer.parseInt(param);
port.operateOpenPatientInfo(keyword);
patientObjects = port.getPatientObject();
if(patientObjects==null){
session.setAttribute("KEYWORD", keyword);
%>
<jsp:forward page="./ViewDnetResult.jsp" />
<%
}
}
session.setAttribute("PORT", port);
55
%>
<table id="result" width="350" border="1">
<tr><td align="center">患者 ID</td><td align="center"><%out.println(patientObjects.getPatientId());%></td></tr>
<tr><td
align="center">
姓
</td><td
align="center"><%out.println(patientObjects.getPatientLastNameKanji());%></td></tr>
<tr><td
align="center">
よ
み
</td><td
align="center"><%out.println(patientObjects.getPatientLastNameAlphabet());%></td></tr>
<tr><td
align="center">
名
</td><td
align="center"><%out.println(patientObjects.getPatientFirstNameKanji());%></td></tr>
<tr><td
align="center">
よ
み
</td><td
align="center"><%out.println(patientObjects.getPatientFirstNameAlphabet());%></td></tr>
<tr><td align="center">生年月日</td><td align="center"><%out.println(patientObjects.getBirthday());%></td></tr>
<tr><td align="center">性別</td><td align="center"><%out.println(patientObjects.getSexDescription());%></td></tr>
<tr><td align="center">血液型</td><td align="center"><%out.println(patientObjects.getBloodTypeABO());%></td></tr>
<tr><td align="center">Rh</td><td align="center"><%out.println(patientObjects.getBloodTypeRho());%></td></tr>
<tr><td
align="center">
電
話
番
号
</td><td
align="center"><%out.println(patientObjects.getTelephoneNum());%></td></tr>
<tr><td align="center">住所</td><td align="center"><%out.println(patientObjects.getAddress());%></td></tr>
<tr><td
align="center">
婚
姻
状
態
</td><td
align="center"><%out.println(patientObjects.getMaritalStatus());%></td></tr>
</table>
<%
%>
session.invalidate();
<br><br>
<p><a href="/thesisPotal/thesisPotal.html">
<font size="4"><b>検索ページへ戻る</b></font>
</p></a>
<hr>
<font size=1>
<i>電子カルテ共有システムの実現 ~デザインパターンと Web サービスの適用~<br>
筑波大学第三学群社会工学類
村田 洋</i><br>
</font>
</body>
</html>
[ File: ViewDnetResult.jsp ]
<%@ page contentType="text/html; charset=Shift_JIS" pageEncoding="Shift_JIS" %>
<%@ page import='stub.*' session='true' %>
<html>
<head><title>電子カルテ共有システム 検索結果</title></head>
<body>
<hr>
<br>
<font size=5 color="#696969">電子カルテ共有システム</font>
<br>
<font size=1>卒業論文製作システム</font>
<br>
<hr>
<h2><b>Error</b></h2>
<br>
<br>
<p><a href="/thesisPotal/thesisPotal.html">
<font size="4"><b>検索ページへ戻る</b></font>
</p></a>
</body>
</html>
56
C) その他のファイル
[ File: deploy.wsdd ]
<deployment name="test" xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="urn:ChartSearchService" provider="java:RPC">
<parameter name="className" value="medical_service.ChartSearchService" />
<parameter name="allowedMethods" value="*" />
<parameter name="scope" value="session"/>
<beanMapping qname="ns:ItemBean" xmlns:ns="urn:medical_service"
languageSpecificType="java:medical_service.ItemBean"/>
</service>
</deployment>
[ File: undeploy.wsdd ]
<undeployment name="test" xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="urn:ChartSearchService"/>
</undeployment>
57
Fly UP