2023.04.21 61일차 SpringBoot
61일차 마이바티스
서버에서 요청을 받고 일하는데 DB에 SQL을 날리는 일을한다.
JDBC로 하기에 핵심로직 말고 지루한 코드들을 지워주는것이 마이바티스이다.
마이바티스가 연결설정 ResultSet으로 얻어온 값 bean에담기 등등 알아서해준다.
view에게 건네주기만 하면된다.
SELECT 하나의 행의 하나의 컬럼, 하나의 행에 여러 컬럼가져올때 BEAN사용 등을 배웟다.
29.9 여러행의 결과 얻기
여러행 결과를 얻어올때 while문으로 탐색해서 list에 담아서 사용햇엇다.
똑같이 리턴타입을 특정 아이템을 element를 가지는 list로 받으면된다.
SELECT CustomerName FROM Customers이 쿼리를 사용하고싶다.
String들이 리턴되니 List<String> list에 담아서 사용하면된다.
@Select("SELECT CustomerName FROM Customers")
List<String> sql1();@RequestMapping("link1")
public void method1() {
//String sql = "SELECT CustomerName FROM Customers";
List<String> list = mapper.sql1();
System.out.println(list);
list.forEach(System.out::println);
}연습
경로 : /sub21/link2 요청시 직원의 lastName 조회하는 메소드 작성하기
@Select("SELECT lastName FROM Employees")
List<String> sql2();@RequestMapping("link2")
public void method2() {
List<String> list = mapper.sql2();
list.forEach(System.out::println);
}29.10 여러 레코드 + 여러 컬럼
여러 레코드 + 하나의 컬럼은 했는데
여러 레코드와 여러 컬럼을 조회하는 메소드를 작성해보자.
javabean을 활용해서 만들어야한다.
조회할 컬럼들의 DTO를 만들어서 조회해야한다.
@Select("SELECT lastName, firstName FROM Employees")
List<Dto07> sql3();@Data
public class Dto07 {
private String lastName;
private String firstName;
}@RequestMapping("link3")
public void method3() {
List<Dto07> names = mapper.sql3();
names.forEach(System.out::println);
}연습
모든 상품의 이름, 가격을 조회해서 콘솔에 출력하기
@Data
public class Dto08 {
private String productName;
private double price;
}@Select("SELECT productName, price FROM Products")
List<Dto08> sql4();@RequestMapping("link4")
public void method4() {
List<Dto08> products = mapper.sql4();
products.forEach(System.out::println);
}29.11 여러 레코드 + 여러 컬럼 - 2
request파라미터로 받아서 특정카테고리의 상품 조회하기
@Select("SELECT productName FROM Products WHERE CategoryId = #{cid}")
List<String> sql5(int cid);@RequestMapping("link5")
public void method5(int cid) {
List<String> list = mapper.sql5(cid);
list.forEach(System.out::println);
}연습
/sub21/link6?country= 각 나라의 고객의 이름(customerName) 조회하기
@Select("SELECT customerName FROM Customers WHERE country = #{country}")
List<String> sql6(String country);@RequestMapping("link6")
public void method6(String country) {
List<String> list = mapper.sql6(country);
list.forEach(System.out::println);
}연습
/sub21/link7?cid 각 카테고리별 상품이름과 가격 조회하기
@Select("SELECT productName, price FROM Products WHERE categoryId = #{cid}")
List<Dto08> sql7(int cid);@RequestMapping("link7")
public void method7(int cid) {
List<Dto08> list = mapper.sql7(cid);
list.forEach(System.out::println);
}29.12 마이바티스 insert
insert쿼리를 sql에 작성하고 싶다.
마이바티스를 이용해서 insert를 실행하고 싶다면 @Insert어노테이션을 사용하면된다.
메소드 아규먼트에 맞게 파라미터를 #{}으로 넣어주면된다.
insert쿼리는 테이블 형식의 데이터를 반환하는게 아니라 영향을 미친 레코드의 개수를 리턴받는다.
그래서 마이바티스 매핑하는 메소드도 int타입을 반환받으면된다.
@Insert("INSERT INTO MyTable34(Col1, Col2) VALUES (#{val1}, #{val2})")
int sql1(int val1, String val2);@RequestMapping("link1")
public void method1() {
int cnt1 = mapper.sql1(77, "java");
int cnt2 = mapper.sql1(88, "spring");
int cnt3 = mapper.sql1(99, "css");
System.out.println(cnt1);
System.out.println(cnt2);
System.out.println(cnt3);
}연습
MyTable35 Col1 Col2에 값 두가지 삽입하는 코드 작성하기
@Insert("INSERT INTO MyTable35 VALUES(#{v1}, #{v2})")
int sql2(Double v1, String v2);@RequestMapping("link2")
public void method2() {
int cnt = mapper.sql2(99.99, "korean");
System.out.println(cnt);
}29.13 마이바티스 insert - 2
/sub22/link3?val1=98.98&val2=송태섭
request파라미터로 값을 받고 insert하기
@RequestMapping("link3")
public void method3(Double val1, String val2) {
int cnt = mapper.sql2(val1, val2);
System.out.println(cnt);
}29.14 마이바티스 insert -3
여러개의 컬럼이 있다면 하나씩 넣을 수도 있지만 너무 많다면 javabean을 사용해야한다.
#{}에 dto.property를 넣어주면된다.
첫번째 propertt가 첫번째 컬럼 두번째 property가 두번째 컬럼 세번째 property가 세번째 컬럼에 들어가게 된다.
dto가 하나라면 dto.property말고 그냥 property를 넣어줘야한다.
@Data
public class Dto09 {
private int prop1;
private String prop2;
private double prop3;
}@Insert("INSERT INTO MyTable36(Col1, Col2, Col3) VALUES(#{prop1}, #{prop2}, #{prop3})")
int sql3(Dto09 dto);@RequestMapping("link4")
public void method4() {
Dto09 dto = new Dto09();
dto.setProp1(300);
dto.setProp2("hello mybatis");
dto.setProp3(33.33);
int cnt = mapper.sql3(dto);
System.out.println(cnt);
}연습
INSERT INTO MyTable37(Age, Name, Score) VALUES (#{age}, #{name}, #{score}
sql에 맞게 테이블과 코드 작성하기
CREATE TABLE MyTable37(
Age INT,
Name VARCHAR(15),
Score DEC(5,2)
); @Insert("INSERT INTO MyTable37(Age, Name, Score) "
+ "VALUES (#{age}, #{name}, #{score})")
int sql4(Dto10 dto);@Data
public class Dto10 {
private int age;
private String name;
private double score;
}@RequestMapping("link5")
public void method5() {
Dto10 dto = new Dto10();
dto.setAge(26);
dto.setName("park");
dto.setScore(100.00);
int cnt = mapper.sql4(dto);
System.out.println(cnt + "행이 입력되었습니다.");
}29.14 마이바티스 insert -4
사용자에게 modelAttribute로 받아서 사용하기
requestparam이 modelAttribute의 프로퍼티로 알아서 매핑되고 바인딩된다.
/sub22/link6?age=77&name=park&score=88.88
@RequestMapping("link6")
public void method6(Dto10 dto) {
int cnt = mapper.sql4(dto);
System.out.println(cnt + "행이 입력되었습니다.");
}연습
modelAttribute로 MyTable36에 값 삽입하는 코드 작성하기
요청링크 : /sub22/link7?prop1=10&prop2=son&prop3=10.00
@RequestMapping("link7")
public void method7(Dto09 dto) {
int cnt = mapper.sql3(dto);
System.out.println(cnt + "행이 입력되었습니다.");
}29.15 마이바티스 insert -5
여러개의 Dto로 파라미터를 받을 수 있다.
dto9가 가진것은 prop1 prop2 prop3 / dto10이가진것은 age name score이다.
dto10 age에 dto9의 prop1을 넣는다고 해보자.
파라미터가 여러개라면 파라미터명.프로퍼티명으로 넣어야한다.
@Insert("INSERT INTO MyTable37(Age, Name, Score) "
+ "VALUES (#{dto9.prop1},#{dto10.name},#{dto10.score})")
int sql5(Dto09 dto9, Dto10 dto10);@RequestMapping("link8")
public void method8(Dto09 dto9, Dto10 dto10) {
int cnt = mapper.sql5(dto9, dto10);
System.out.println(cnt + "행이 입력되었습니다.");
}@RequestMapping("link8")
public void method8() {
Dto09 dto9 = new Dto09();
Dto10 dto10 = new Dto10();
dto9.setProp1(10);
dto10.setName("son");
dto10.setScore(10.00);
int cnt = mapper.sql5(dto9, dto10);
System.out.println(cnt + "행이 입력되었습니다.");
}연습
다음테이블에 Dto09 Dto10을 사용해서 값을 넣어보자.
dto1.prop1 -> Col1 dto2.age -> Col2 dto1.prop2 -> Col3
dto2.name -> Col4 dto1.prop3 -> Col5 dto2.score -> Col6
CREATE TABLE MyTable38(
Col1 INT,
Col2 INT,
Col3 VARCHAR(200),
Col4 VARCHAR(200),
Col5 DEC(10,3),
Col6 DEC(10,3)
); @Insert("INSERT INTO MyTable38(Col1, Col2, Col3, Col4, Col5, Col6) "
+ "VALUES (#{dto1.prop1},#{dto2.age},#{dto1.prop2},#{dto2.name},#{dto1.prop3},#{dto2.score})")
int sql6(Dto09 dto1, Dto10 dto12);@RequestMapping("link9")
public void method9() {
Dto09 dto1 = new Dto09();
Dto10 dto2 = new Dto10();
dto1.setProp1(10);
dto1.setProp2("son");
dto1.setProp3(10.00);
dto2.setAge(20);
dto2.setName("park");
dto2.setScore(20.00);
int cnt = mapper.sql6(dto1, dto2);
System.out.println(cnt + "행이 입력되었습니다.");
}29.16 마이바티스 insert -6
여러개의 dto의 값을 request param으로 받아보자.
다음의 경로로 요청하게 되면 각 property에 맞게 매핑된다.
/sub22/link10?prop1=7&prop2=lunch&prop3=3.14&age=8&name=song&score=3.14
@RequestMapping("link10")
public void method9(Dto09 p1, Dto10 p2) {
int cnt = mapper.sql6(p1, p2);
System.out.println(cnt + "행이 입력되었습니다.");
}29.17 auto increase
default값이 있거나 자동증가하는 컬럼이 있다면 값을 넣을 필요가 없엇다.
기본키컬럼의 속성으로 값이 자동증가하는 AUTO_INCREMENT제약사항을 추가할 수 있다.
모든컬럼에 값을 넣을 수 있지만 자동증가 컬럼에는 값을 안넣어도 된다.
CREATE TABLE MyTable39 (
Col1 INT PRIMARY KEY AUTO_INCREMENT,
Col2 VARCHAR(300),
Col3 INT
);@Data
public class Dto11 {
private int prop1;
private String prop2;
private int prop3;
}@Insert("INSERT INTO MyTable39(Col2, Col3) "
+ "VALUES (#{prop2},#{prop3})")
int sql7(Dto11 dtO);// /sub22/link11?prop2=mybatis&prop3=321
@RequestMapping("link11")
public void mehtod11(Dto11 dto) {
int cnt = mapper.sql7(dto);
System.out.println(cnt + "행 입력 완료!!");
}마이바티스에서 generate key된 키를 가져오고 싶다면
@Options 어노테이션을 사용하면된다.
useGeneratedKeys value를 true로해주면 마이바티스로 증가한 키를 가져올 수 잇다.
마이바티스가 증가하는 컬럼을 알아서 찾지만 어떤 property에 세팅할 것인지는 keyProperty를 이용해서 지정해줘야한다.
@Insert("""
INSERT INTO MyTable39 (Col2, Col3)
VALUES (#{prop2}, #{prop3})
""")
@Options(useGeneratedKeys = true, keyProperty = "prop1")
int sql7(Dto11 dto);// /sub22/link11?prop2=mybatis&prop3=321
@RequestMapping("link11")
@ResponseBody
public String mehtod11(Dto11 dto) {
System.out.println("prop1:" + dto.getProp1());
int cnt = mapper.sql7(dto);
System.out.println(cnt + "행 입력 완료!!");
System.out.println("prop1:" + dto.getProp1());
return dto.getProp1() + "번째 데이터 입력완료";
}연습
sub22/link12?age=40&name=son&score=9.9
요청시 MyTable40에 데이터 추가되도록 코드 작성
컨트롤러메소드, 매퍼 메소드, 자바빈
자바빈의 id 프로퍼티에 자동증가컬럼값 받을 수 있게 만들기
@Data
public class Dto12 {
private int id;
private int age;
private String name;
private double score;
}@Insert("INSERT INTO MyTable40 (age, name, score) "
+ "VALUES (#{age}, #{name}, #{score})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int sql8(Dto12 dto);@RequestMapping("link12")
public void method12(Dto12 dto) {
int cnt = mapper.sql8(dto);
System.out.println(cnt + "개 행 입력");
System.out.println(dto.getId() + "번 데이터 입력됨");
}Clinet -> controller -> mapper -> DB
DB -> mapper -> controller -> model -> view -> Clinet
이 흐름으로 이어진다.
서버와 DB는 별개의 프로그램이다. DB에 일시키는 것을 MAPPER 에게 일시키는 것이다.
나중에는 controller와 mapper사이에 Service가 들어가게 된다.
mapper가 DAO 대신하는 역할인가??
mapper를 repositrory라고 하는 곳도잇고 dao라고 persistence라고 하는 곳도 있다.
흐름만 생각해두자.
마이바티스를 사용하면 mapper라고 하는 것 같다.
29.18 마이바티스 delete
@Delete("DELETE FROM MyTable40")
int sql1();@RequestMapping("link1")
public void method1() {
int cnt = mapper.sql1();
System.out.println(cnt + "개 행 삭제됨");
}조건을 지정하지 않으면 테이블의 모든 내용이 삭제되니 WHERE로 조건을 지정해줘야한다.
@Delete("DELETE FROM MyTable39 WHERE Col1 = #{id}")
int sql2(Integer id);@RequestMapping("link2")
public void method2(Integer id) {
int cnt = mapper.sql2(id);
System.out.println(cnt + "개 행 삭제됨");
}연습
/sub23/link3?key=7 경로로 요청시 고객삭제하기
@Delete("DELETE FROM Customers WHERE CustomerID = #{id}")
int sql3(Integer id);@RequestMapping("link3")
public void method3(Integer key) {
int cnt = mapper.sql3(key);
System.out.println(cnt + "개 삭제됨");
}29.19 마이바티스 update
@Update("UPDATE MyTable39 SET Col2 = '수정된 값', Col3 = 99999")
int sql1();@RequestMapping("link1")
public void method1( ) {
int cnt = mapper.sql1();
System.out.println(cnt + "개 행 수정됨");
}수정을 하기 위해서는 view에서 데이터를 받아서 해야한다.
@Update("UPDATE Customers SET"
+ "CustomerName = #{name}, "
+ "ContactName = #{contactName}, "
+ "Address = #{address}, "
+ "City = #{city}, "
+ "PostalCode = #{postalCode}, "
+ "Country = #{country} "
+ "WHERE CustomerId = #{id} ")
int sql4(Customer customer);@RequestMapping("link5")
public void method(Customer customer) {
int cnt = mapper.sql4(customer);
System.out.println(cnt + "개 행 수정됨");
}<h1>${customer.id }번 고객 수정</h1>
<div>
<form action="/sub24/link5" method="post">
<input type="hidden" name="id" value="${customer.id }" />
이름 <input type="text" name="name" value="${customer.name }" /> <br />
고객명 <input type="text"
name="contactName" value="${customer.contactName }" /> <br />
주소 <input type="text" name="address" value="${customer.address }"/> <br />
도시 <input type="text" name="city" value="${customer.city }"/> <br />
국가 <input type="text" name="country" value="${customer.country }" /> <br />
우편번호 <input type="text" name="postalCode" value="${customer.postalCode }" /> <br />
<input type="submit" value="수정" />
</form>
</div>2023.04.21
마이바티스도 회사마다 사용방법이 다르다 안쓸수도 잇고
큰틀에서 이해만 해야한다.
마이바티스도 버전에따라서 사용방법이 조금씩 다르다.
큰흐름에서 이해만 하자.