FHIR(PDQm)
IHE

ITI

– IHE Tutorial – 2023-06-29

1

– IHE Tutorial – 2023-06-29

– IHE Tutorial – 2023-06-29

3

v2.4.0 Trial Implementation– IHE Tutorial – 2023-06-29

4

Patientリソースの検索(search)Patientリソースの取得(read)

https://profiles.ihe.net/ITI/PDQm/ITI-78.htmlより引用– IHE Tutorial – 2023-06-29

5検索パラメータ

データタイプ内容

検索パラメータの例_id

String

リソースID_id=1234

familygiven

String

患者氏名の姓 family=田中
given:exact=実と名

identifier

Token

患者ID

完全一致

identifier=urn:oid:2.16.840.1.113883.4.1|
123456789telecom

Token

電話番号

telecom=03-1234-5678

割り当て権限者のチェック

birthdate

Date

生年月日

birthdate=eq1995-01-01
birthdate=ge2000-12-31

範囲指定等のPrefix

address

String住所

address=東京都中央区日本橋

genderToken

性別

gender=male– IHE Tutorial – 2023-06-29

6

No.

R/O※ 内容

備考

120

O

「family=金田」の検索

130

O「family=金田」および「given=満子」の検索

140

O「family=金」（前方一致）の検索

150

O「identifier=1234567890」（割り当て権限者を含む）の検索

160

O「birthdate=1982-02-02」の検索

170

O「family=栄田」（exactパラメータを使用）および「gender=female」の検索を実行

180

O「family=福岡」および「birthdate=1990-10-10」の検索

250R

それまでの検索（search）の応答メッセージの１つから、Patientリソースを取得（read）取得

300

R

Supplierに一致するものがないクエリ

割り当て権限者のチェック

完全一致
複数の検索パラメータの組み合わせ※R=必須, O=オプション– IHE Tutorial – 2023-06-29

7

– IHE Tutorial – 2023-06-29

8

HAPI FHIRはJava言語のリファレンス実装

Java以外の開発言語のライブラリも公開されている– IHE Tutorial – 2023-06-29

9

– IHE Tutorial – 2023-06-29

10

※建物正面の装飾を指す建築用語
その場で変換クライアントサーバー（ファサード型）

クライアントサーバー（リポジトリ型）

電子カルテDB

変換/登録
ツール

電子カルテDB

あらかじめ変換して保存
リポジトリ– IHE Tutorial – 2023-06-29

11

エラーになった「Meta」にカーソルを置くとインポートすべきオブジェクトモデルの候補が表示される– IHE Tutorial – 2023-06-29

12

「meta.」と入力すると関数名の候補とその説明が表示される– IHE Tutorial – 2023-06-29

13

フォーマットを選択できるタイトルのロゴや説明はカスタマイズできるサーバーが対応しているリソースが一覧表示される複数の検索パラメータを指定して検索できる
対応している検索パラ
メータから選択できる– IHE Tutorial – 2023-06-29

14

HAPI FHIRでクライアントを実装した場合のコードサンプルが表示される
リクエストの内容やヘッダーが表示されるレスポンスのコードやヘッダーが表示される
Bundle内のリソースの件数や一覧が表示されるリソースの取得（read）が行える
レスポンスの内容が表示される– IHE Tutorial – 2023-06-29

15

オブジェクト
モデル関係

クライアント関係
ファサード型サーバー関係
コード例もあり理解しやすい– IHE Tutorial – 2023-06-29

16

Patient?identifier=1234567890

SELECT * FROM MY_PATIENT
WHERE PT_ID='1234567890'

PDS（ファサード型）

PDC{"resourceType": "Patient","identifier": [ {"system":... ,"value": "1234567890"} ],...

患者マスター
MY_PATIENT"1234567890","福岡","千尋","フクオカ","チヒロ", "F",
19901010,"03-62522220",...

– IHE Tutorial – 2023-06-29

17

フィールド名

データタイプ

PKEY

NULL

内容

PT_ID

CHAR(10)

Y

N

患者ID

PT_FAMILY_IDE

CHAR(20)

N

患者漢字氏名（姓）PT_GIVEN_IDE

CHAR(20)

N

患者漢字氏名（名）PT_FAMILY_SYL

CHAR(20)

N患者カナ氏名（姓）PT_GIVEN_SYL

CHAR(20)

N患者カナ氏名（名）PT_FAMILY_ABC

CHAR(20)

N患者ローマ字氏名（姓）

PT_GIVEN_ABC

CHAR(20)

N患者ローマ字氏名（名）PT_GENDER

CHAR(1)

N

患者性別（M=男、F=女、O=その他）

PT_BIRTHDATE

DATE

N

患者生年月日PT_PHONE

CHAR(20)

N

患者電話番号

PT_ZIP

CHAR(10)

N

患者郵便番号

PT_ADDRESSCHAR(64)

N

患者住所

患者IDをリソースIDとする想定

姓と名を別のフィールドに格納– IHE Tutorial – 2023-06-29

18

– IHE Tutorial – 2023-06-29

19

– IHE Tutorial – 2023-06-29

20

– IHE Tutorial – 2023-06-29

21

– IHE Tutorial – 2023-06-29

22

①クライアントからリクエストが来る
HAPI FHIR
Plain Server

クライアント⑥JSON/XMLに変換して返す⑤検索パラメータに合致するオブジェクトのリストを返す④レコードの内容をPatientオブジェクトに変換する:アプリ側で実装する部分②対応する関数の引数に検索パラメータが渡る
Providerクラス③検索パラメータに合致するレコードを検索する

Converterクラス
HAPI FHIR
ライブラリ

MyBatisライブラリ

患者マスターテーブル– IHE Tutorial – 2023-06-29

23

– IHE Tutorial – 2023-06-29

24

※ アノテーションとは、プログラムのソースコードに注釈を加えて、コンパイラに情報を伝えること– IHE Tutorial – 2023-06-29

25

検索用であることを示す@Search()Patientオブジェクトのリストを返す

引数が対応する検索パラメータを示す
必須パラメータの場合は@RequiredParamを使用する

public List<Patient> search(@OptionalParam(name = Patient.SP_IDENTIFIER) TokenParam theIdentifier,@OptionalParam(name = Patient.SP_NAME) StringParam theName,@OptionalParam(name = Patient.SP_FAMILY) StringParam theFamily,@OptionalParam(name = Patient.SP_GIVEN) StringParam theGiven,@OptionalParam(name = Patient.SP_BIRTHDATE) DateRangeParam theBirthDate,@OptionalParam(name = Patient.SP_GENDER) TokenParam theGender,@OptionalParam(name = Patient.SP_TELECOM) TokenParam theTelecom,@OptionalParam(name = Patient.SP_ADDRESS) StringParam theAddress,@Sort SortSpec theSort) {_sortパラメータに対するクラスも定義されている

検索パラメータのタイプごとにクラスが定義されている– IHE Tutorial – 2023-06-29

26

List<Patient> list = new ArrayList<Patient>();SqlSession session = null;

Patientオブジェクトのリストを生成する

DBに接続するtry {session = Common.OpenSqlSession();

List<MyPatient> tables = selectMyPatient(session, theIdentifier, theName,theFamily, theGiven, theBirthDate, theGender, theTelecom, theAddress );for (MyPatient table : tables) {検索条件に合うMY_PATIENTのレコードを検索する

Patient resource = MyPatientConverter.CreateResource(session, table);list.add(resource);}

リストに追加するレコードの内容を順にPatientオブジェクトに変換する

sortResourceList(list, theSort);}

DBとの接続を閉じる（省略）

return list;

リストをソートする

リストを返す– IHE Tutorial – 2023-06-29

27

public List<MyPatient> selectMyPatient(SqlSession session, ...) {MyPatientMapper mapper =session.getMapper(MyPatientMapper.class);

テーブルごとのMapperクラスを取得する

MyPatientExample example = new MyPatientExample();MyPatientExample.Criteria criteria = example.createCriteria();
ExampleクラスとCriteriaクラスのオブジェクトを生成する

if (theIdentifier != null)

criteria.andPt_idEqualTo(theIdentifier.getValue());
if (theGiven != null)
criteria.andPt_given_sylEqualTo(theGiven.getValue());...
return mapper.selectByExample(example);}

検索を実行すると、テーブルオブジェクトのリストが返る指定された検索条件をANDでcriteriaに追加する→検索パラメータの組み合わせに対応できる– IHE Tutorial – 2023-06-29

28

if (theGiven != null) {検索パラメータの値を取得する（例:「実」）String given = theGiven.getValue();
if (Common.IsFullKatakana(given)) {if (theGiven.isExact()):exactが指定されているか（例:true）→:exactパラメータに対応できる

criteria.andPt_given_sylEqualTo(given);:exactが指定されていたらEQUAL検索を行う

else
criteria.andPt_given_sylLike(given + "%");}:exactが指定されていなければLIKE検索を行う

else{
if (theGiven.isExact())

criteria.andPt_given_ideEqualTo(given);else
criteria.andPt_given_ideLike(given + "%");

漢字による検索の場合}}

パラメータ例：「given:exact=実」– IHE Tutorial – 2023-06-29

29

if (theBirthDate != null) {if (theBirthDate.getLowerBound() != null) {下限値を取得する（例:2000-12-31)

Prefixを取得する（例:ge）→Prefixに対応できる

Date sdate = theBirthDate.getLowerBound().getValue();ParamPrefixEnum sprefix = theBirthDate.getLowerBound().getPrefix();
if (sprefix == ParamPrefixEnum.GREATERTHAN_OR_EQUALS)
criteria.andPt_birthdateGreaterThanOrEqualTo(sdate);
else if (sprefix == ParamPrefixEnum.GREATERTHAN)
criteria.andPt_birthdateGreaterThan(sdate);ge (以上)が指定されている場合
GreaterThanOrEqualToを使用
gt (より大きい)が指定されている場合
GreaterThanを使用

else if (sprefix == ParamPrefixEnum.EQUAL)

eq (等しい)が指定されている場合
EqualToを使用

criteria.andPt_birthdateEqualTo(sdate);}
if (theBirthDate.getUpperBound() != null) {

上限値を取得する

Date edate = theBirthDate.getUpperBound().getValue();ParamPrefixEnum eprefix = theBirthDate.getUpperBound().getPrefix();
if (eprefix == ParamPrefixEnum.LESSTHAN_OR_EQUALS)
criteria.andPt_birthdateLessThanOrEqualTo(edate);
else if (eprefix == ParamPrefixEnum.LESSTHAN)
criteria.andPt_birthdateLessThan(edate);}}le (以下)が指定されている場合
LessThanOrEqualToを使用
lt (より小さい)が指定されている場合
LessThanを使用

パラメータ例：「birthdate=ge2000-12-31」 – IHE Tutorial – 2023-06-29

30

if (theIdentifier != null) {String system = theIdentifier.getSystem();if (system != null && !system.equals(Common.GetNSPatient()))

system部分を取得して、値をチェックする→割り当て権限者に対応できる

throw new ResourceNotFoundException("Not recognized identifier system:" +system);
HTTP STATUS 404(Not Found) を返す
String value = theIdentifier.getValue();if (value != null)
criteria.andPt_idEqualTo(value);}code部分を取得してEqualToで検索する（例:123456789）

パラメータ例：「identifier=urn:oid:2.16.840.1.113883.4.1|123456789」– IHE Tutorial – 2023-06-29

31

取得用であることを示す@Read(version = false)

リソースIDが引数として渡るPatientオブジェクトを返す

public Patient readPatient(@IdParam IdType theId) {SqlSession session = null;
DBに接続するtry {session = Common.OpenSqlSession();

MyPatientMapper mapper = session.getMapper(MyPatientMapper.class);
MyPatient table = mapper.selectByPrimaryKey(theId.getIdPart());
if (table == null)
throw new ResourceNotFoundException(theId);

リソースIDを患者IDとしてMY_PATIENTを検索する

return MyPatientConverter.CreateResource(session, table);}catch(Exception e) {throw new InternalErrorException(e);取得したレコードの内容をPatientオブジェクトに変換して返す}
finally{

DBとの接続を閉じる

session.close();}– IHE Tutorial – 2023-06-29

32

– IHE Tutorial – 2023-06-29

33

static public Patient CreatePatientResource(SqlSession session, MyPatient table){
Patient resource = new Patient();// id

Patientオブジェクトを生成する

MyBatis用の患者マス
ターオブジェクト

resource.setId(table.getPt_id());// identifier
resource.addIdentifier()

患者IDをリソースIDとしてセットする.setValue(table.getPt_id()).setSystem(Common.GetNSPatient());

患者IDをセットする// name

患者漢字氏名をセットする

resource.addName(Common.CreateHumanName(table.getPt_family_ide(),table.getPt_given_ide(), "IDE"));
resource.addName(Common.CreateHumanName(table.getPt_family_syl(),table.getPt_given_syl(), "SYL"));

患者カナ氏名をセットする//telecom
resource.addTelecom().setUse(ContactPointUse.HOME).setSystem(ContactPointSystem.PHONE)

電話番号をセットする.setValue(table.getPt_phone());– IHE Tutorial – 2023-06-29

34性別をセットする（例:female）//genderswitch(table.getPt_gender()) {case "M" : resource.setGender(AdministrativeGender.MALE); break;case "F" : resource.setGender(AdministrativeGender.FEMALE); break;case "O" : resource.setGender(AdministrativeGender.OTHER); break;default: resource.setGender(AdministrativeGender.UNKNOWN); break;}//birthDate
resource.setBirthDateElement(new DateType(table.getPt_birthdate()));//address生年月日をセットする（例:1990-10-10）

resource.addAddress().setText(table.getPt_address()).setPostalCode(table.getPt_zip());
return resource;}

住所、郵便番号をセットする

生成したPatientオブ
ジェクトを返す– IHE Tutorial – 2023-06-29

35

public static HumanName CreateHumanName(String family, String given, Stringstyle) {textをセットする
HumanName humanName = new HumanName()（例:福岡 千尋）
.setText(family + " " + given).setUse(NameUse.OFFICIAL).setFamily(family).addGiven(given);// Create an extension
if (style != null) {familyをセットする（例:福岡）
givenをセットする（例:千尋）

humanName.addExtension()// "http://hl7.org/fhir/StructureDefinition/iso21090-EN-representation".setUrl(GetSDIso21090ENRepresentation()).setValue(new CodeType(style));}EN Representation
拡張を追加する（例:IDE）

return humanName;}– IHE Tutorial – 2023-06-29

36

{}, {"resourceType": "Patient","id": "1234567890","extension": [ {リソースID"meta": {"profile":[ "http://jpfhir.jp/fhir/core/StructureDefinition/JP_Patient" ]"url":"http://hl7.org/fhir/StructureDefinition/iso21090EN-representation","valueCode": "SYL"} ],},"use": "official","identifier": [ {"text": ""system":"http://terminology.sample.com/IdSystem/patient","value": "1234567890"
} ],

",

"family": "","given": [ "" ]

} ],

患者ID

"telecom": [ {"active": true,"system": "phone","name": [ {"value": "03-6252-2220","extension": [ {電話番号"use": "home""url":"http://hl7.org/fhir/StructureDefinition/iso21090EN-representation","gender": "female","birthDate": "1990-10-10","text": ""use": "official","postalCode": "105-7123",",","given": [ "" ]住所

"address": [ {} ],"family": "性別・生年月日} ],"valueCode": "IDE""text": "患者カナ氏名"country": "JP"患者漢字氏名} ]
}

",

郵便番号

– IHE Tutorial – 2023-06-29

37

– IHE Tutorial – 2023-06-29

38

IHE
– IHE Tutorial – 2023-06-29

39