Tip! xml에서 먼저 쿼리문을 작성하고, 그걸 토대로 Mapper 인터페이스 작성한 후에 컨트롤러 메서드 작성하는 순서로 하면 편하다.
1. TestMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.test.mapper.TestMapper">
<!-- 인터페이스랑 연결하려면 xml과 이름 동일, namespace에 전체 경로 적어줘야함-->
<insert id="insertMember">
insert into test values(#{id},#{pw},#{age},sysdate)
</insert>
<!-- 1. test 테이블에서 전체 회원의 수를 가져오고 싶다.
resultType: 실행 결과의 컬럼 개수와 데이터 타입에 따라
숫자 하나, 컬럼 하나 가져옴. 단일 데이터, 즉 int-->
<select id="memberCount" resultType="int">
select count(*) from test
</select>
<!-- 2 -->
<select id="maxAge" resultType="int">
select max(age) from test
</select>
<!-- 3 컬럼 4개를 여러 정보를 가져오니 테스트DTO-->
<select id="selectAll" resultType="com.test.model.TestDTO">
select * from test
</select>
<!-- 4 아이디로 골라서 가져오기. 어떤 아이디를 넣어도 꺼낼 수 있게 id= #{}-->
<select id="selectOne" resultType="com.test.model.TestDTO">
select * from test where id=#{id}
</select>
<!-- 5 id를 주고 그 사람의 회원 가입 날짜 가져오기
타임스탬프 -->
<select id="getReg" resultType="java.sql.Timestamp">
select reg from test where id=#{id}
</select>
<!--6 pw, age 수정 해당 id의 사람꺼. int는 안적어도 리턴 ok -->
<update id="updateMember">
update test set pw=#{pw}, age=#{age} where id=#{id}
</update>
<!-- 7. age 파라미터가 넘어오면 해당 age의 count수를 조회
age가 안넘어오면 전체 count수를 조회. age의 카운트 수가 넘어오므로 int -->
<select id="selectIf" resultType="int">
select count(*) from test
<if test="age != null"> <!-- age값이 넘어오지 않으면 밑에 실행문은 실행 x 위에 전체 카운트 출력문만 출력됨 -->
where age=#{age}
</if>
</select>
<!-- 8. 로그인 체크 id랑 pw 받아서 db에서 일치하는지 체크/ id 존재 여부 확인도 됨
문제점: pw만 보내면 where절 스킵되서 에러발생. -->
<select id="selectIf2" resultType="int">
select count(*) from test
<if test="id != null">
where id=#{id}
</if>
<if test="pw!=null">
and pw=#{pw}
</if>
</select>
<!-- 해결 방안 #1 -->
<select id="selectIf3" resultType="int">
select count(*) from test where id=#{id}
<if test="pw!=null">
and pw=#{pw}
</if>
</select>
<!-- (구조적인) 해결방안 #2 조건에 맞으면 trim이 붙여서 실행-->
<select id="selectTrim" resultType="int">
select count(*) from test
<trim prefix="where" prefixOverrides="and|or"> <!-- and,or가 붙어서 오면 where로 덮어버리겠다-->
<if test="id!=null">
id=#{id}
</if>
<if test="pw!=null">
and pw=#{pw}
</if>
</trim>
</select>
<!-- 9. id pw (또는) age가 일치하는 레코드 수.
pw 또는 age 둘중에 하나! 둘 다 아님. 다 되고 싶으면 trim,if,if 써야함 -->
<select id="choose" resultType="int">
select count(*) from test where id= #{id}
<choose>
<when test="pw!=null">
and pw= #{pw}
</when>
<when test="age!=null">
and age = #{age}
</when>
<otherwise>
<!-- 위 조건이 안 맞을 경우 실행할 문장 -->
</otherwise>
</choose>
</select>
<!-- 10. trim 이용하여 update: 회원정보 수정.
pw만, age만, pw&age, id&pw&age 등등 경우의 수 다양-->
<update id="trimUpdate" >
update test
<trim prefix="set" suffixOverrides=','>
<if test="pw!=null">
pw=#{pw},
</if>
<if test="age!=null"> <!-- int면 !=0 Integer라서 !=null -->
age=#{age}
</if>
</trim>
where id=#{id}
</update>
<!-- 11. forEach: age가 list에 들은 값들과 일치하는 레코드 전체 컬럼 정보 얻기
ArrayList: [10,20,30]를 어레이리스트에 담아서 주겠다.-->
<select id="selectIn" resultType="com.test.model.TestDTO">
select * from test where age in
<foreach collection="list" item="item" open="(" separator="," close=")">
<!--list라는 이름으로 아이템에 담아줄 것
open: ( 이걸로 열거야 separator: 구분기호 close: ) 이걸로 닫을거야-->
#{item}
</foreach>
</select>
<!-- 12. selectKey:id,pw는 외부에서 던져주고 전체 레코드 수를 구해서
age값으로 하나의 레코드 추가-->
<insert id="insertSK">
<selectKey keyProperty="age" order="BEFORE" resultType="int">
<!-- keyProperty: 쿼리를 실행한 결과를 key라고 보면 된다.
age에 들어갈거니까 변수 이름 똑같이 적어야함. order: 먼저 실행하겠다. -->
select count(*) from test
</selectKey>
insert into test values(#{id}, #{pw},#{age},sysdate)
</insert>
<!-- 13. Like #{} 문자열일 경우에는 ''를 자동으로 붙여준다.
#{} 숫자면 ''없이 숫자만 들어간다.
<select id="selectLike" resultType="com.test.model.TestDTO">
select * from test where id like '%'||#{keyword}||'%' '%' ||'s'||'%' 으로 되서 %s% 으로 인식
</select>-->
<!-- like 응용
column 명은 ${}으로 채워준다. #{}로 채우면 문자열이라 홑따옴표가 붙는 쿼리가 되어버림-->
<select id="selectLike" resultType="com.test.model.TestDTO">
select * from test where ${column} like '%'||#{keyword}||'%'
</select>
</mapper>
2. TestMapper.java
package com.test.mapper;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.test.model.TestDTO;
public interface TestMapper {
public void insertMember(TestDTO dto); //리턴타입 잘 모르겠으면 일단 void로 쓰고 나중에 고쳐라
//쿼리문은 xml에 작성!
//리턴타입: 쿼리문 실행 레코드 수와 데이터 타입에 따라
//매개변수: 쿼리문 실행 시 외부에서 던져줄 데이터에 따라 실행
//1. test 테이블에서 전체 회원의 수를 가져오고 싶다
public int memberCount();
//데이터가 한줄(레코드가 하나) 리턴타입 int . 여러개면 List나 Integer로 받기.
//#{}등 던져주는 매개변수가 없으므로 매개변수 값 비워놓기
//2
public int maxAge();
//3 레코드가 여러 개니까 리스트로 묶어라. 한줄로 묶은 데이터의 타입이 뭔지. 타입이 여러개니까 DTO
public List<TestDTO> selectAll();
//4 한사람의 여러정보를 가져온다. 레코드 하나, 값은 여러 종류라서 리턴타입 디티오. 매개변수의 값은 아이디니까 스트링
public TestDTO selectOne(String id);
//5
public Timestamp getReg(String id);
//6
//public void updateMember(TestDTO dto);
//public void updateMember(HashMap map);
public void updateMember(@Param("id") String id, @Param("pw") String pw, @Param("age") int age);
//7
public int selectIf();
public int selectIf(Integer age); //메서드 오버로딩
//8
public int selectIf2(TestDTO dto);
//9
public int choose(TestDTO dto);
//10
public void trimUpdate(TestDTO dto);
//11
public List<TestDTO> selectIn(ArrayList list);
//12
public void insertSK(TestDTO dto);
//13
//기본
//public List<TestDTO> selectLike(String keyword);
//응용
public List<TestDTO> selectLike(HashMap map);
}
3. TestContoller6.java
package com.test.controller;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.test.mapper.TestMapper;
import com.test.mapper.TimeMapper;
import com.test.model.TestDTO;
@Controller
@RequestMapping("/day06/")
public class TestController6 {
@Autowired
private TestMapper testMapper; //테스트 매퍼 주입
//form화면 요청
@GetMapping("form")
public void form() {
System.out.println("form 요청");
}
//form에서 넘어온 데이터 처리 요청
@PostMapping("pro")
public void pro(TestDTO dto) { //TestDTO 낱개가 아닌 여러개로 받겠다
System.out.println("pro요청");
//DB저장
testMapper.insertMember(dto);
}
@GetMapping("test")
public void test() {
// int count = testMapper.memberCount();
// System.out.println("count: " + count);
// int maxAge = testMapper.maxAge();
// System.out.println("maxAge: " + maxAge);
// List<TestDTO> list= testMapper.selectAll();
// System.out.println(list);
// list.forEach(dto -> System.out.println(dto)); //스트림 한번 사용해보기
// TestDTO dto = testMapper.selectOne("go");
// System.out.println(dto);
// Timestamp reg = testMapper.getReg("go");
// System.out.println(reg); //404
//testMapper.updateMember("go","1111",40);
/*
//7. 동적쿼리
int count = testMapper.selectIf();
System.out.println(count);
//8
TestDTO dto = new TestDTO();
//id중복여부 확인
dto.setId("go");
//id,pw일치하는지 확인 (로그인)
dto.setPw("1111");
int count = testMapper.selectIf2(dto);
System.out.println("count: "+count);
/*id중복여부 확인
if(count>0) {
System.out.println(dto.getId()+"는 이미 사용 중인 ID입니다.");
}else {
System.out.println(dto.getId()+"는 사용 가능한 ID입니다.");
}
if(count > 0) {
System.out.println("로그인 성공");
}else {
System.out.println("ID 또는 PW가 일치하지 않습니다.");
}
//9. choose. choose는 둘 중에 하나! 둘 다 아님.
TestDTO dto = new TestDTO();
dto.setId("spring01");
//dto.setPw("0000");
dto.setAge(30);
int result = testMapper.choose(dto);
System.out.println(result);
//11
ArrayList list = new ArrayList();
list.add(10); //쿼리문한테 리스트 보내줌
list.add(20);
list.add(30);
list.add(40);
list.add(50);
List<TestDTO> resultList = testMapper.selectIn(list);
System.out.println(resultList);
resultList.forEach(dto-> System.out.println(dto));
//12 select key
TestDTO dto = new TestDTO();
dto.setId("java");
dto.setPw("0101");
testMapper.insertSK(dto);
System.out.println(dto);
//13 id에 s라는 문자가 포함된 정보 모두 추출
List<TestDTO> list = testMapper.selectLike("s");
System.out.println(list);
list.forEach(dto->System.out.println(dto));
//컬럼명(검색기준)과 키워드 두개를 보내서 일치하는 것 찾기
HashMap map = new HashMap();
map.put("column", "pw"); //pw에 (select 박스로 사용자가 선택한 검색 시준)
map.put("keyword", "0"); //0이 들어간 레코드 찾아줘 (검색 키워드 작성한 것)
List<TestDTO> list = testMapper.selectLike(map);
System.out.println(list);
list.forEach(dto->System.out.println(dto));*/
//10
TestDTO dto = new TestDTO();
dto.setId("spring01");
dto.setAge(41);
testMapper.trimUpdate(dto);
}
/* 유효성 검사
//테스트를 위해 localhost:8080/day06/pro?id=java06&pw=435&age=10
//@RequestMapping(value="pro", params = "id=java06") //params: 넘어오는 데이터의 제약을 걸어줄 수 있다. id는 꼭 자바06이 와야한다고 명시.
//@RequestMapping(value="pro", params= {"id=java06","pw=1234"})//id는 java06,pw는1234여야 넘어온다.파라미터의 유효성 검사 가능
//@RequestMapping(value="pro", params= {"id","pw"}) //id,pw파라미터가 넘어오면 ok. 값은 상관 안함
//@RequestMapping(value="pro", params= {"id","pw","!age"}) //age라는 이름의 파라미터는 넘어오면 안된다
@RequestMapping("pro")
//public String pro(@RequestParam(value="id", defaultValue = "hello") String id, //디폴트밸류: 값이 안넘어왔을때 초기값 지정
public String pro(@RequestParam(value="id", required = true) String id, //id 필수 값으로 지정
@RequestParam(value="pw") String pw) {
System.out.println(id +"\n"+ pw);
return "day06/pro";
}
*/
}
SQL 쿼리문
select sysdate from dual;
--resultType="String"
select id from test;
--resultTupe="int"
select age from test;
--resultType="com.test.model.TestDTO"
select * from test;
--1.test 테이블에서 전체 회원의 수를 가져오고 싶다. 숫자 하나, 컬럼 하나 가져옴.
select count(*) from test;
--2. 나이 제일 많은 사람
select max(age) from test;
--3
select * from test;
--4
select * from test where id = 'spring01';
--5
select reg from test where id='go';
--6
update test set pw='0000', age='10' where id='go';
--7 동적쿼리를 이용해 분기처리해보자
select count(*) from test;
select count(*) from test where age=10;
--8
--id, pw체크. 있으면 1 없으면 0 리턴.
select count(*) from test where id='spring01' and pw='0000';
--id 사용유무 체크
select count(*) from test where id='spring01';
--9. id pw age가 일치하는 레코드 수 (비번 찾을 때, 아이디 비번 이메일 일치하는지 입력하는 그런거..)
select count(*) from test where id='go' and pw='1111' and age='40';
--11 forEach
select * from test where id in ('spring01','go','python','java');
select * from test where age in(10,20,30);
--12
select count(*) from test;
--레코드 전체 개수를 insert의 age 값으로 넣어줘보자. 레코드가 8개면 age에 8
--insert into test values (#(id),#(pw),#(age), sysdate);
--13.Like
select * from test where id like '%s%';
+
log4j Doctype 변경
<!DOCTYPE log4j:configuration SYSTEM
"http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
이걸로 바꿔주면 빨간줄 안뜸.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM
"http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
헤더 전체적인 모양이 이렇게 되도록.