sql문을 동적으로 제어하기
와.... 주말에 진짜 오라클 다시 공부해야겠다.....
기억이 안나니 게시판 만드는 로직처럼 접근 해 보자
index.jsp에 먼저 등록하고 indexController에다가도 추가!
원래 로직작성은 서비스에서 하지만
이건 게시판도 아니고 하니
조직작성을 그냥 컨트롤러에 몰아넣음
원래는 떼어놓는게 맞다 !!
+++ 이거도 sql로 제어할 거라서
메퍼파일 만들거
마이바티스랑 연결 되어야 하기 때문에
src/main.resoures >onememo.mybatis.configuration.xml에다가
<mapper resource="onememo/mybatis/mapper/dynamicsql.xml"/>
추가함!!
1. 뷰
DynamicSql.jsp
뭘 할 것인지 먼저 봐
if태그 / choose~when~otherwise태그 / where태그 / trim태그 / set태그 foreach태그
<h1>마이바티스 동적 SQL</h1>
<p>${message}</p>
</div>
<h3>if 태그</h3>
<ul class="list-unstyled">
<li><a href="<c:url value="/Mybatis/If1.do?title=자바"/>">WHERE절
일부에 사용 첫번째</a></li>
<li><a
href="<c:url value="/Mybatis/If2.do?title=자바&name=김길동&content=안드로이드"/>">WHERE절
일부에 사용 두번째</a></li>
</ul>
<h3>choose~when~otherwise 태그</h3>
<a
href="<c:url value="/Mybatis/choose.do?title=자바&name=김길동&content=안드로이드"/>">WHERE절
일부에 사용</a>
<h3>where 태그</h3>
<a
href="<c:url value="/Mybatis/where.do?title=자바&name=김길동&content=안드로이드"/>">where태그로
where절 구성</a>
<h3>trim 태그</h3>
<ul class="list-unstyled">
<li><a
href="<c:url value="/Mybatis/trim1.do?title=자바&name=김길동&content=안드로이드"/>">검색문</a></li>
<li><a
href="<c:url value="/Mybatis/trim2.do?no=12&title=자바&content=안드로이드"/>">수정문</a></li>
</ul>
<!-- update 하고자 하는 칼럼을 동적으로 포함시키기 위해 사용 -->
<h3>set 태그</h3>
<a href="<c:url value="/Mybatis/set.do?no=21&title=안녕&content=인사"/>">수정문</a>
<h3>foreach 태그</h3>
<a href="<c:url value="/Mybatis/foreach.do"/>">foreach태그</a>
<h3>이메일 삭제</h3>
<form method="post" action="<c:url value="/Mybatis/foreachExam.do"/>">
<div class="form-check">
<label class="form-check-label">
<input type="checkbox" class="form-check-input" value="1" name="email">메일 1
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="checkbox" class="form-check-input" value="3" name="email">메일 3
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="checkbox" class="form-check-input" value="4" name="email">메일 4
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="checkbox" class="form-check-input" value="5" name="email">메일 5
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="checkbox" class="form-check-input" value="6" name="email">메일 6
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="checkbox" class="form-check-input" value="8" name="email">메일 8
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="checkbox" class="form-check-input" value="24" name="email">메일 24
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="checkbox" class="form-check-input" value="30" name="email">메일 30
</label>
</div>
<input type="submit" value="삭제" class="btn btn-danger"/>
</form>
[if태그]
2.컨트롤러(+서비스기능)
@Controller
@RequestMapping("/Mybatis")
public class DynamicSqlController { //여기선 서비스 생략
//생성자 인젝션으로 주입
private DynamicSqlDAO dao;
//@Autowired // 생성자가 하나일때는 생략 가능
public DynamicSqlController(DynamicSqlDAO dao) {
this.dao=dao;
}
@GetMapping("/If1.do")
public String if1(@RequestParam Map map,Model model) {
List list= dao.if1(map);
model.addAttribute("message","검색된 총 글 수 :"+list.size());
//뷰정보 반환
return "dynamicsql11/DynamicSql";
}
@GetMapping("/If2.do")
public String if2(@RequestParam Map map,Model model) {
List list= dao.if2(map);
model.addAttribute("message","검색된 총 글 수 :"+list.size());
//뷰정보 반환
return "dynamicsql11/DynamicSql";
}
3.DAO
@Repository
public class DynamicSqlDAO {
@Autowired
private SqlSessionTemplate template;
public List if1(Map map) {
return template.selectList("findWithTitleLike",map);
}
public List if2(Map map) {
return template.selectList("findWithLike",map);
}
}
+쿼리문
<select id="findWithTitleLike" parameterType="Map" resultType="memoDto">
SELECT * FROM onememo
WHERE 1=1
<if test="title !=null">
AND title LIKE '%' || #{title} || '%'
</if>
</select>
<select id="findWithLike" parameterType="Map" resultType="memoDto">
SELECT o.*,name FROM onememo o JOIN member m ON m.id=o.id
WHERE 1=1
<if test="title !=null">
AND title LIKE '%' || #{title} || '%'
</if>
<if test="name !=null">
AND name LIKE '%' || #{name} || '%'
</if>
<if test="content !=null">
AND content LIKE '%' || #{content} || '%'
</if>
</select>
[choose]
뷰는 위에
2. 컨트롤러
@GetMapping("/choose.do")
public String choose(@RequestParam Map map,Model model) {
List list= dao.choose(map);
model.addAttribute("message","검색된 총 글 수 :"+list.size());
//뷰정보 반환
return "dynamicsql11/DynamicSql";
}
3.DAO
public List choose(Map map) {
return template.selectList("findWithLikeChoose",map);
}
++쿼리문작성
<select id="findWithLikeChoose" parameterType="Map" resultType="memoDto">
SELECT o.*,name FROM onememo o JOIN member m ON m.id=o.id
WHERE 1=1
<choose>
<when test="title !=null">
AND title LIKE '%' || #{title} || '%'
</when>
<when test="name !=null">
AND name LIKE '%' || #{name} || '%'
</when>
<otherwise>
AND content LIKE '%' || #{content} || '%'
</otherwise>
</choose>
</select>
[where]
2.컨트롤러
where동적으로 추가시 where태그 권장
@GetMapping("/where.do")
public String where(@RequestParam Map map,Model model) {
List list= dao.where(map);
model.addAttribute("message","검색된 총 글 수 :"+list.size());
//뷰정보 반환
return "dynamicsql11/DynamicSql";
}
3.DAO
public List where(Map map) {
return template.selectList("findWithLikeWhere",map);
}
+쿼리문
<select id="findWithLikeWhere" parameterType="Map" resultType="memoDto">
SELECT o.*,name FROM onememo o JOIN member m ON m.id=o.id
<!-- 위 구문에서 "where 1=1"을 "where"로 변경 시 조건에 따라 에러 발생 -->
<!-- 아래 where 엘리먼트는 JSTL에 의해 컨텐츠가 리턴되면 단순히 "WHERE"만을 추가한다.
게다가 컨텐츠가 "AND"나 "OR"로 시작한다면 그 "AND"나 "OR"를 지워버린다. -->
<where>
<if test="title !=null">
AND title LIKE '%' || #{title} || '%'
</if>
<if test="name !=null">
AND name LIKE '%' || #{name} || '%'
</if>
<if test="content !=null">
AND content LIKE '%' || #{content} || '%'
</if>
</where>
</select>
2.[trim1,2]
2.컨트롤러
@GetMapping("/trim1.do")
public String trim1(@RequestParam Map map,Model model) {
List list= dao.trim1(map);
model.addAttribute("message","검색된 총 글 수 :"+list.size());
//뷰정보 반환
return "dynamicsql11/DynamicSql";
}
@GetMapping("/trim2.do")
public String trim2(@RequestParam Map map,Model model) {
if(!(map.get("title")==null && map.get("content")==null)) {
int affected= dao.trim2(map);
model.addAttribute("message","수정된 총 글 수 :"+affected);
}
else {
model.addAttribute("message","제목이나 내용 둘 중 하나는 전송!!");
}
//뷰정보 반환
return "dynamicsql11/DynamicSql";
}
3.DAO
public List trim1(Map map) {
return template.selectList("findWithLikeTrim",map);
}
업데이트니까 int를 반환!
public int trim2(Map map) {
return template.update("updateWithLikeTrim",map);
}
++쿼리문
prefix : <trim> 문 안에 쿼리 가장 앞에 붙는 접두어
suffix : <trim> 문 안에 쿼리 가장 뒤에 붙는 접미어
prefixOverrides : <trim> 문 안에 쿼리 가장 앞에 해당하는 문자들이 있으면 자동으로 지워준다.
suffixOverrides : <trim> 문 안에 쿼리 가장 뒤에 해당하는 문자들이 있으면 자동으로 지워준다.
<select id="findWithLikeTrim" parameterType="Map" resultType="memoDto">
SELECT o.*,name FROM onememo o JOIN member m ON m.id=o.id
<trim prefix="WHERE" suffix="ORDER BY no DESC" prefixOverrides="AND">
<if test="title !=null">
AND title LIKE '%' || #{title} || '%'
</if>
<if test="name !=null">
AND name LIKE '%' || #{name} || '%'
</if>
<if test="content !=null">
AND content LIKE '%' || #{content} || '%'
</if>
</trim>
</select>
<!-- trim문은 수정시에 쓰자 -->
<update id="updateWithLikeTrim" parameterType="Map">
UPDATE onememo
<!-- title이나 content가 전달되면 수정.단,둘 중의 하나는 전달되야 한다
자바코드에서 제어
-->
<trim prefix="SET" suffixOverrides=",">
<if test="title !=null">
title=#{title},
</if>
<if test="content !=null">
content=#{content},
</if>
</trim>
WHERE no=#{no}
</update>
묶어버리자...
잠을 자야해...
[set] & [foreach]
update 하고자 하는 칼럼을 동적으로 포함시키기 위해 사용
2.컨트롤러
@GetMapping("/set.do")
public String set(@RequestParam Map map,Model model) {
if(!(map.get("title")==null && map.get("content")==null)) {
int affected= dao.set(map);
model.addAttribute("message","수정된 총 글 수 :"+affected);
}
else {
model.addAttribute("message","제목이나 내용 둘 중 하나는 전송!!");
}
//뷰정보 반환
return "dynamicsql11/DynamicSql";
}
@GetMapping("/foreach.do")
public String foreach(Model model) {
//리스트인 경우
List list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
List result=dao.foreach(list);
//맵 인 경우
Map map = new HashMap();
map.put("acticleNos", Arrays.asList(1,2,3,4,5,6,7,8,9,10));
List result= dao.foreach(map);
model.addAttribute("message","검색된 총 글 수:"+result.size());
//뷰정보 반환
return "dynamicsql11/DynamicSql";
}
2.DAO
public int set(Map map) {
return template.update("updateWithSet",map);
}
리스트일 때
public List foreach(List list) {
return template.selectList("findForeach",list);
}
맵일때
public List foreach(Map map) {
return template.selectList("findForeach",map);
}
++쿼리문
**collection : List 혹은 배열 형태만 가능
parameterType이 List인 경우 "list" 혹은 "collection"
만약 List<DTO계열>이면 item속성에 지정한 변수명.DTO멤버 속성명 으로 꺼낸다
예]<foreach item="item" ~
#{item.id}
</foreach>
parameterType이 배열인 경우 "array"
parameterType이 Map인 경우 key값(단,value는 List혹은 배열) 지정
item :컬렉션에서 꺼내온 객체 저장 변수
open : 시작 문자열
close : 종료 문자열
separator : 반복 되는 사이에 삽입할 문자열
index : 0부터 순차적으로 증가하는 인덱스번호
수정 시는 trim대신 set태그를 쓰자
<update id="updateWithSet" parameterType="Map">
UPDATE onememo
<set>
<if test="title !=null">
title=#{title},
</if>
<if test="content !=null">
content=#{content},
</if>
</set>
WHERE no=#{no}
</update>
List인 경우
<select id="findForeach" parameterType="List" resultType="memoDto">
SELECT * FROM onememo
WHERE no IN
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</select>
Map인 경우
<select id="findForeach" parameterType="Map" resultType="memoDto">
SELECT * FROM onememo
WHERE no IN
<foreach collection="acticleNos" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</select>
[delet] +foreachExam
2.컨트롤러
@PostMapping("/foreachExam.do")
public String foreachExam(@RequestParam int[] email, Model model) {
int affected =dao.foreachExam(email);
model.addAttribute("message","삭제된 총 글 수 :"+affected);
return "dynamicsql11/DynamicSql";
}
2.DAO
delete 하는거라서 댓글 (자식)이 딸려있는 글(부모)는 삭제가 안됨
트랜젝션 처리를 해야 함
트랜젝션 처리를 위한 주입받기
@Autowired
private TransactionTemplate transactionTemplate;
public int foreachExam(int[] email) {
int deleteCount = transactionTemplate.execute(status->{
int affected=0;
try {
affected=template.delete("deleteEmail",email);
}
catch(Exception e) {
affected=-1;//삭제 시 에러난 경우 -1반환
}
return affected;
});
return deleteCount;
}
+쿼리문
<delete id="deleteEmail" parameterType="int[]">
DELETE onememo
WHERE no IN
<foreach collection="array" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</delete>
꿱
'학원 > SPRING' 카테고리의 다른 글
12/22 70-1 [Ajax] JQuery Ajax 나머지 (0) | 2022.12.22 |
---|---|
12/21 69-1 [AJAX] jQuery Ajax (3) | 2022.12.21 |
12/15 65-2 [SPRING] 페이징 (0) | 2022.12.15 |
12/15 65-1 [SPRING] 주말에 할 것 +delete/edit (1) | 2022.12.15 |
12/14 64-2 [SPRING] 게시판(댓글처리)-수정해야함 (0) | 2022.12.14 |