2022年03月18日(金)
DAOと表の関係
1つのDAOに複数のテーブルが含まれています
他のテーブルのデータはクエリーできますが.
データを照会できても、登録、変更、削除はできません
他のDAOが担当するテーブルを登録、変更、または削除します.
1つのDAOには1つ以上のテーブルがあります
1つのテーブルを複数のDAOに登録、変更、削除することはできません.
クエリーは可能です.
メンテナンスが難しくなる.
1つのテーブルの合計数は1つのDAOです
承認CRUD
データの登録、変更、削除は、1つのDAOが担当する必要があります.
明日サービスオブジェクトを作成します
サービス・オブジェクトが実行する作業:ビジネス処理、トランザクション制御(commit、rollback)
MemberService
BoardService
ApplyService
1つのサービス・オブジェクトは、1つ以上のDAOを使用してビジネスを処理できます.
コントローラオブジェクトコントローラオブジェクト:クライアントリクエストの処理(リクエストの応答を担当)クライアントリクエストの処理
MemberController:MemberServiceを使用してクライアント要求を処理する
BoardController
ApplyController
コントローラはDAOを使用しません
コントローラオブジェクト→サービスオブジェクト→DAO→テーブル
メンテナンスが容易な方法かメンテナンスが困難な方法か
複数のDAOアクセス用テーブル
残りのDAOはクエリーのみです.
取引
通常電話番号は複数格納
電話番号タイプ表
電話番号
携帯電話
ファクシミリ
•勤務先電話
•業務ファックス
連絡先テーブル
電話番号表
電話番号タイプ表
/Users/nana/git/bitcamp-20211108/mylist-boot/app-11.1/README.md
-- 연락처
drop table ml_contact;
create table ml_contact(
contact_no int not null,
name varchar(50) not null,
email varchar(20) not null,
company varchar(50)
);
alter table ml_contact
add constraint primary key (contact_no),
modify column contact_no int not null auto_increment;
-- 전화번호 유형
create table ml_tel_type(
tt_no int not null,
title varchar(20) not null
);
alter table ml_tel_type
add constraint primary key (tt_no),
modify column tt_no int not null auto_increment;
-- 연락처 전화번호
create table ml_cont_tel(
ct_no int not null, -- 전화번호 PK
contact_no int not null,
tt_no int not null,
tel varchar(20) not null
);
alter table ml_cont_tel
add constraint primary key (ct_no),
modify column ct_no int not null auto_increment;
alter table ml_cont_tel
add constraint ml_cont_tel_fk1
foreign key (contact_no) references ml_contact(contact_no),
add constraint ml_cont_tel_fk2
foreign key (tt_no) references ml_tel_type(tt_no);
連絡先テーブルにサンプルデータを挿入連絡先データを扱うDAOの作成
ContactDao
ContactTelDao
TelTypeDao
電話番号タイプ情報を処理するDAOを作成できます.
しなくてもいい
実際の操作では、「電話番号タイプ」テーブルのように
テーブルの作成時にデータを挿入します.
DAOを単独で作成しない
管理機能に含まれている場合は、
テーブルごとにDAOを作成することもできます.
他のテーブルに関連付けられている場合:
連絡先テーブルの変更によるドメインクラスの変更
連絡先テーブルとドメインクラス
Contact <------------------> 연락처
ContactTel <------------------> 전화번호
전화유형
電話タイプデータを直接処理する必要がない場合は、ドメインクラスを作成する必要はありません.包含関係(組合せ)
このオブジェクトに含める
オブジェクトが消えると、オブジェクトも消えます.
注意!
オブジェクト(クラス)とオブジェクトの関係は一方向でなければなりません.
Aクラス-->Bクラス
class A {
B obj;
...
}
class B { // No!!!!!!
A obj;
...
}
双方参照しないjoinが複雑な場合はHashMapを使用します
連絡先テーブルの変更によるDAOクラスの変更
管理機能(タイプの削除または追加)に含まれている場合は、
<select id="findByContactNo" parameterType="int">
select
ct_no,
contact_no,
tt_no,
tel
from
ml_cont_tel
where
contact_no=#{no}
</select>
<select id="findByContactNo" parameterType="int" resultMap="contactTelMap">
select
ct_no,
contact_no,
tt_no,
tel
from
ml_cont_tel
where
contact_no=#{no}
</select>
ContactDaoの使用
ContactController ------> ContactDao
連絡先テーブルの変更によるページコントローラクラスの変更
http://localhost:8080/contact/add?name=aaa&[email protected]&tel=010-0000-0001&tel=02-0000-0002&tel=02-0000-0003
Spring Boot
new Contact()←Contactオブジェクトの作成
nameフィールド、emailフィールド、companyフィールド
各フィールドにクエリー・パラメータ値を追加
telは複数受信可能
String[]配列でtelを受信できます
new String[]
クエリパラメータ値がString[]配列の
第0項、第1項、第2項
Spring Boot呼び出しContactControllerページコントローラ
値を受信するには変数が必要です
add(Contact contact, String[] tel) {...}
名前が一致するのでtelsではなくtelを使います.http://localhost:8080/contact/list
System.out.println(contact);
for (String t : tel) {
System.out.println(t + ", ");
}
System.out.println();
http://localhost:8080/contact/add?name=bbb&[email protected]&tel=010-0000-0001&tel=02-0000-0002&tel=02-0000-0003
複数のデータが同じ名前で入力された場合、順番に受信します.
add(Contact contact, String[] tel) {...}
同じ名前のパラメータ値が複数を超える場合は、配列として受信できます.
add(Contact contact, String[] tel) {...}
パラメータ値はオブジェクトとして受信できます.ただし、パラメータ名に一致するpropertyが必要です.
/contact/add?name=OOO
要求パラメータと呼びます.
要求パラメータ名と値
/contact/add?name=OOO&email=OOO&tel=OOO
疑問符から終了までをクエリー文字列と呼びます
要求パラメータと同じproperty名があると仮定します.
ContactTelジェネレータの作成
オブジェクトの作成時に電話番号を直接入力
public ContactTel() {}
public ContactTel(String tel) {
this.tel = tel;
}
良いジェネレータコードを作るのも減ります↓ @RequestMapping("/contact/add")
public Object add(Contact contact, String[] tel) throws Exception {
System.out.println(contact);
for (String t : tel) {
contactDao.insertTel(new ContactTel(t));
}
return 1;
}
忘れるタイプ...に質問
電話番号のタイプにパラメータはありません
/contact/add?name=OOO&email=OOO&company=OOO
new Contact()で受信
今まで私たちが学んだ解決策を使っています.
/contact/add?name=OOO&email=OOO&company=OOO&tel=1,010-1111-2222&tel=2,02-1111-2222&tel=3,010-1111-3333
new Stringで受信
0はtel=1、1はtel=2、2はtel=3
add(Contact contact, String[] tel) {...}
新しいContactTel(タイプ、電話番号)
split()でカットして入れます
public ContactTel(int telTypeNo, String tel) {
this.telTypeNo = telTypeNo;
this.tel = tel;
}
http://localhost:8080/contact/add?name=x1&[email protected]&tel=1,02-0000-0001&tel=2,02-0000-0002&tel=3,010-0000-0003 @RequestMapping("/contact/add")
public Object add(Contact contact, String[] tel) throws Exception {
contactDao.insert(contact);
for (int i = 0; i < tel.length; i++) {
String[] value = tel[i].split(",");
contactDao.insertTel(new ContactTel(Integer.parseInt(value[0]), value[1]));
}
return 1;
}
ビルダーの変更
public ContactTel(int contactNo, int telTypeNo, String tel) {
this.contactNo = contactNo;
this.telTypeNo = telTypeNo;
this.tel = tel;
}
PK値を知るにはinsertが必要ですPK値で挿入します.
以前JDBCを習った時の方法
com.eomcs.jdbc.ex4.Exam0110.java
挿入後に自動的に増加するPK列の値を決定する方法
サブテーブルにデータを同時に入力するときに発生する問題
親投稿番号を知る必要があります
うん.前に入力した投稿番号は何ですか?
問題は、上に入力した投稿PK値が自動的に生成されることです.
解決策
com.eomcs.jdbc.ex4.Exam0111.java
<!-- 자동 증가된 PK 값을 받고 싶을 때! -->
<insert id="insert" parameterType="contact" keyProperty="no" keyColumn="contact_no" useGeneratedKeys="true">
insert into ml_contact(name,email,company)
values(#{name},#{email},#{company})
</insert>
@RequestMapping("/contact/add")
public Object add(Contact contact, String[] tel) throws Exception {
contactDao.insert(contact);
for (int i = 0; i < tel.length; i++) {
String[] value = tel[i].split(",");
contactDao.insertTel(new ContactTel(contact.getNo(), Integer.parseInt(value[0]), value[1]));
}
return 1;
}
http://localhost:8080/contact/add?name=x3&[email protected]&company=bitcamp&tel=1,02-0000-0001&tel=2,02-0000-0002&tel=3,010-0000-0003 http://localhost:8080/contact/add?name=x4&[email protected]&company=bitcamp&tel=1,02-0000-0001&tel=2,02-0000-0002&tel=3,010-0000-0003
データをテーブルに分散保存
http://localhost:8080/contact/index.html
「連絡先の入力」画面
電話タイプ選択ボックスの追加
var xName = document.querySelector("#x-name");
var xEmail = document.querySelector("#x-email");
var xCompany = document.querySelector("#x-company");
document.querySelector("#x-add-btn").onclick = function() {
if (xName.value == "" || xEmail.value == "" /* || xTel.value == "" */) {
window.alert("필수 입력 항목이 비어 있습니다.");
return;
}
console.log(xName.value);
console.log(xEmail.value);
console.log(xCompany.value);
var xName = document.querySelector("#x-name");
var xEmail = document.querySelector("#x-email");
var xCompany = document.querySelector("#x-company");
var xTelDivList = document.querySelectorAll(".x-tel-div")
for (var xTelDiv of xTelDivList) {
console.log(xTelDiv);
}
for (var xTelDiv of xTelDivList) {
var xTelType = xTelDiv.querySelector("select");
var xTel = xTelDiv.querySelector("input");
}
http://localhost:8080/contact/list
get()メソッドの変更
連絡先詳細表示画面を処理します.
@RequestMapping("/contact/get")
public Object get(int no) {
Contact contact = contactDao.findByNo(no);
if (contact == null) {
return "";
}
contact.setTels(contactDao.findTelByContactNo(no));
return contact;
}
// 4) 연락처 상세 정보를 화면에 출력한다.
xName.value = contact.name;
xEmail.value = contact.email;
xCompany.value = contact.company;
for (var tel of contact.tels) {
console.log(tel);
}
// 4) 연락처 상세 정보를 화면에 출력한다.
xName.value = contact.name;
xEmail.value = contact.email;
xCompany.value = contact.company;
for (var i = 0; i < contact.tels.length; i++) {
var xTelType = xTelDivList[i].querySelector("select");
var xTel = xTelDivList[i].querySelector("input");
console.log()
xTelType.value = contact.tels[i].telTypeNo;
xTel.value = contact.tels[i].tel;
}
詳細ページに入ると、選択ボックスに相当するタイプが表示されます.update
document.querySelector("#x-update-btn").onclick = function() {
var firstTel = xTelDivList[0].querySelector("input"); // 첫번째 전화번호
if (xName.value == "" || xEmail.value == "" || firstTel.value == "") {
window.alert("필수 입력 항목이 비어 있습니다.");
return;
}
電話番号の更新既存の電話番号を押す
新しい挿入をする
int deleteTelByContactNo(int contactNo);
連絡先のすべての連絡先を削除 @RequestMapping("/contact/update")
public Object update(Contact contact, String[] tel) throws Exception {
int count = contactDao.update(contact);
if (count > 0) {
contactDao.deleteTelByContactNo(contact.getNo());
for (int i = 0; i < tel.length; i++) {
String[] value = tel[i].split(",");
if (value[1].length() == 0) {
continue;
}
contactDao.insertTel(new ContactTel(contact.getNo(), Integer.parseInt(value[0]), value[1]));
}
}
return count;
}
deleteサブテーブルデータを削除する必要があります
@RequestMapping("/contact/delete")
public Object delete(int no) throws Exception {
contactDao.deleteTelByContactNo(no);
return contactDao.delete(no);
}
電話入力画面の動的追加
<button type="button" onclick="deleteDiv(event)">삭제</button>
行内合成としてeではなくイベントを使用するEventTarget.dispatchEvent()
https://developer.mozilla.org/ko/docs/Web/API/EventTarget/dispatchEvent
表のチェックイン後、↓コードを必要とせずに一度にインポートできます.
resultMapがcollectionラベルを使用するのは来週の月曜日です...
関連タグ
Reference
この問題について(2022年03月18日(金)), 我々は、より多くの情報をここで見つけました https://velog.io/@banana/2022-03-18금テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol