지시자
만 남기고 전부 지울것이다. 또한 코드를 작성할 때 EL, JSTL식으로 적었는데 이는 디자이너들과의 협업을 위함이다. 또 EL, JSTL은 Spring을 시작할 때 자동으로 설치되기에 선언만 하면 된다.
EL : ${이름} : 요러게 적으면 request
객체 안에 있는 이름을 그대로 가져올 수 있다.
JSTL : java 코드를 태그형식으로 만들어놓은 커스텀 태그 라이브러리이다.
Spring Project에서 DB을 연결하기위해서는 총 5개의 파일이 필요하고 이것들을 모두 받아주었다.
1. Spring-jdbc : 이것은 현재 spring version과 반드시 일치해야 error가 발생하지 않는다.
2. mybatis : jsp, servlet을 안 쓰려고 사용함.
3. mybatis-spring : 그냥 mybatis로는 하자가 있어서 더 편하게 쓰려고 사용
4. hikaricp : cp를 관리하기위해 사용하는 프레임 워크
5. mysql : sql을 사용하기 위해서
자 이제 DAO(Mapper), mybatis를 만들었다. 하지만 DAO는 Object로써 완전함을 뜻하지만 이건 interface로 불완전 하기에 Mapper라는 단어를 사용한다.
원래 DAO가 했던 일을 Mapper가 한다.
또 다른 특징으로는 ;
은 문장 끝에 작성하지 않으며 sql문만 따로 빼서 작성하는 곳이 바로 mybatis이다.
또한 저기 namespace에서 interface와 이름을 일치시켜줌으로써 @Mapper
로 연결 시켜준다.
<select id="method의 이름" resultType="객체가 담겨있는 fullpath">
query 문
</select>
boardList();
함수가 알아서 잘 보내줄 것이다. 왜? mybatis가 알아서 해주기 때문이다.@Mapper
public interface BoardMapper {
public List<Board> boardList();
}
가장 위에는 이 파일이 구현해야할 Mapper Interface임을 명시해줘야 한다.
원래는 일반적인 class 파일 밑에 있는 메서드였는데 이게 메서드가 추상화가 되고 이 메서드들이 여러개 생기니까 일일이 implement하는게 귀찮아서 그냥 interface로 만들어버렸다. 다만 이것을 쓸 때 Spring이 알아서 구현해준다.
우리가 기존에 JDBC를 쓰면 어떤 문제점이 생기냐면 매번 Conn을 생성했다가 삭제하게되는데 이는 server에 매우 과부하를 주고 회사는 관리비가 매우 많이 나온다. 또한 사용자가 몰렸을 때 서버에 문제가 생길 수 있다. 이를 방지하기 위해 나온 개념이 DBCP
이다.
이는 DataBase Connection Pool의 약자로 미리 Conn을 생성 후 대여와 반납을 반복한다.
이제 아까 다운로드한 5개의 framework를 setting 해주자 root-context.xml을 봐보자 이게 무엇이냐면 bean
은 자바 객체이고 여기에 적어놓으면 spring이 알아서 만들어준다고 앞서 포스팅 했었다.
우선 bean의 구조를 알아보자
<bean id="" class="">
<property name="" value=""><property/>
</bean>
id 영역은 Board board와 같고 new Board(); 부분은 class 영역과 같은 효과를 가진다.
또한 property는 객체의 필드와 같고 이를 채워주어야 한다. name은 field의 이름 value는 setter method라고 이해하면 편하다.
자, 이제 DB와 연결해주기위해 Conn을 만들어보자
DB와 Spring을 연결해주기위한 4가지가 있다. 위에서 언급한 4가지이고 DB를 효율적으로 연결해주기위해 Hikari가 존재한다. 하지만 이도 그저 객채라 bean태그 안에 생서해주어야한다.
<bean id="config" class="com.zaxxer.hikari.HikariConfig">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mysql"></property>
<property name="username" value="root"></property>
<property name="password" value="12345"></property>
</bean>
원래 DataSource 생성 코드가 HikariDataSource dataSource = new HikariDataSource(config);
이렇게 매개변수로써 들어가야 한다. 그렇다면 내부 태그가 property가 아닌 constructor-arg가 되어야한다.
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<constructor-arg ref="config"></constructor-arg>
</bean>
바로 이 친구가 DAO 객체를 뚝딱뚝딱 자동으로 만들어줄꺼고 저장까지 해주는 친구이다.
얘는 재로가 필요한데 바로 dataSource이다.
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
</bean>
근데 이 bean들이 어디있는 줄 알고 만드나 그래서 나온 것이 scan이다.
scan 방법은 앞서 배웠든 annotaion, @Mapper
을 기반으로 scan을 실시한다.
<mybatis:scan base-package="com.gjai.mapper" />
그런데 그냥 default로 실시하면 빨간줄이 뜨는 것을 확인할 수 있다. 이를 해결하기 위해서 이제 위를 봐보자 XML은 저장하기위해 schema라는 개념이 등장한다.
지금까지 코드를 쳐보면 이상한 점이 들었다. 위에 property나 bean 태그들과 그 안에 속성은 어떻게 자동완성이 되는가? 바로 위에 사진에서 다 명시가 되어있는데 문제는 mybatis:scan이 없기 때문에 error가 뜨는 것이다.
그럼 이제 최신화를 해주자.
구글에 mybatis-spring을 검색하고 들어가면 왼쪽 tab에 mapper 주입이 있는데 여기들어가서 위의 조건을 최신화해주면 된다.
이것이 바로 Spring framework가 가진 특징중 하나인데 바로 제어역전이라 한다.
이제 장단점이 있는데 개발자가 개발하기 편하긴 하다.
.class
가 따라오기 때문에 이는 삭제해 주어야 한다. 왜? 어차피 src값의 이름이 class라고 되어있으니까Con의 역할을 한다. 즉, Mapper에서 나온 결과값을 토대로 url을 안내해주는 역할이라 봐도 될 듯 하다.
@Controller
public class BoardController{
@Autowired
private BoardMapper mapper;
@RequestMapping("/boardList.do")
public String boardList( Model model ){
List<Board> list = mapper.boardList();
model.addAttribute("list", list);
return "boardList";
}
}
@Controller
는 POJO임을 알려주는 annotation이다.
@Autowired
는 메모리에 있는 객체(bean)을 가져다 집어넣어주는 annotation이다. 왜 이렇게 생성하냐면 interface이기 때문에 일반적으로 위와같이 생성이 불가능 하다.
@RequestMapping
은 괄호 안의 요청이 들어오면 실행한다는 뜻이며 반드시/
를 앞에 붙여줘야 한다.
List<Board> list = mapper.boardList();
은 mapper안에 있는 method를 사용하여 DB에 접근하여 결과값을 가져오는 method이다.
그리고 결과값을 가져왔으면 이 결과값을 request
객체에 담아 forward 방식으로 보냈었는데
이젠 return 값에 view 이름만 넣어주어도 된다. 왜냐면 ViewResolver가 완전한 경로로 만들어주기 때문이다.
객체 바인딩
은 스코프 영역에 데이터를 잠시 저장해두는 것.
즉, model.addAttribute("list", list);
를 사용하여 request 객체에 저장해준다.
코드 작성을 진행하다보면 계속 이렇게 error 코드가 나타나는데 이건 그냥 android 설정과 달라서 나는 충돌이니 무시해도 된다.