: 스프링이 제공하는 웹 애플리케이션 개발 전용 프레임워크
: MVC(Model-View-Controller) 패턴 사용, 이 사이 의존 관계를 스프링 컨테이너가 관리하고 스프링이 제공하는 기능 자유롭게 확장해 웹 애플리케이션 구축 가능
model : 애플리케이션 데이터가 들어 있는 객체
view : 모델 정보(데이터) 특정 형식으로 나타냄. 보통 작성 시 JSP, JSTL 사용
controller : 애플리케이션의 비즈니스 로직 포함. 애너테이션으로 표시
front controller : 애플리케이션 흐름 관리(스프링 MVC-DispatcherServlet)
: 웹 브라우저에서 서버--웹 요청--처리-->결과 되돌려 주기까지 디스패쳐 서블릿(DispatcherServlet) 도움 받음
DispatcherServlet : 웹 애플리케이션으로 들어오는 모든 웹 요청을 제어하고 모델-뷰-컨트롤러를 조합하여 웹 브라우저에 출력하는 클래스, 스프링 MVC의 대표적인 구성 요소
HandlerMapping : 클라이언트가 요청한 URL을 어떤 컨트롤러가 처리할지 결정
Controller : 요청 처리 후 결과 반환. 응답 결과에서 보여 줄 데이터를 모델에 담아 전달
ModelAndView : 컨트롤러가 처리한 결과 정보와 뷰 선택에 필요한 정보 담음
ViewResolver : 컨트롤러 처리 결과를 보여 줄 뷰 결정
View : 컨트롤러의 처리 결과 화면 생성. 주로 JSP 파일로 클라리언트에 응답 결과 전송
db : database(개념. 공유/저장/통합/운영)
: 중복, 데이터 불일치 방지 ex.공유폴더
RDB(Relational DB) : 관계형DB
dbms : database management system(DB관리시스템.오라클)
localhost : ip 주소, LAN(local area network)
xe :express edition. express(OracleXE11g.r2) => SID(sequence ID)
bean : 객체
pool(connection-객체) <=====> DB
: 데이터베이스와 연결된 커넥션을 미리 만들어서 풀(pool) 속에 저장해 두고 있다가 필요할 때에 커넥션을 풀에서 가져다 쓰고, 사용이 끝나면 다시 풀에 반환하는 기법
: 커넥션을 미리 생성해 두기 때문에 커넥션을 사용자가 DB를 사용할 때마다 매번 생성하는 것보다 더 빠른 속도를 보장
: 커넥션의 최대 생성 개수도 제어, 많은 사용자가 몰려도 과부화 방지
: 메모리 때문에 정해진 갯수만큼만 객체 생성
: multi thread -> thread pool
: 오픈 소스 => DBCP(apache), CP30
: 스프링 프레임워크에게 클래스가 웹 브라우저의 요청(request)를 받아들이는 컨트롤러임을 명시
: 스프링은 servlet-context.xml의 context:component-scan의 설정에 의해 이 클래스를 자바빈 객체로 등록(메모리에 바인딩)
@Controller
public class BookController {
.
.
/*
요청 URI : localhost/create == /create
요청방식 : get
*/
// 요청 매핑(요청값="/create", 방식 = 요청방식.GET)
@RequestMapping(value="/create", method = RequestMethod.GET)
public ModelAndView create() {
model - 데이터, view - 경로
javac -version
휴대폰 수리 중 액정 고치기
// 서비스 interface : 비즈니스 로직(기능)
public interface BookService { // 휴대폰 수리 중
// 도서 등록 -> 액정 고치기
public int createPost();
}
도서 등록
// 도서 관리 프로그램
// 서비스 호출하기 위해 의존성 주입(Dependency Injection - DI)
// IoC(Inversion of Control - 제어의 역전)
@Autowired
BookService bookService;
.
.
.
// <form action="/create" method="post">
// HTTP 파라미터(요청 파라미터)
//=> {"title":"총알탄 개똥이","category":"소설","price":10000}
//bookVO => {"bookId":"(0)","title":"총알탄 개똥이","category":"소설"
// ,"price":10000,"insertDate":"(null)"}
@RequestMapping(value = "/create", method = RequestMethod.POST)
public ModelAndView createPost(BookVO bookVO, ModelAndView mav) {
log.info("bookVO : " + bookVO);
// 도서 등록
this.bookService.createPost(bookVO); // bookVO 던져줘야 서비스에서 받음
return mav;
}
=>Service interface
// 서비스 interface : 비즈니스 로직(기능)
public interface BookService {
// 도서 등록
public int createPost(BookVO bookVO); // 던진 거 받아줌
}
=> Service implement
//서비스 클래스 : 비즈니스 로직
//스프링 MVC 구조에서 Controller와 DAO를 연결하는 역할
/*
스프링 프레임워크는 직접 클래스를 생성하는 것을 지양하고,
* 프링은 인터페이스를 좋아해. 자꾸자꾸 좋아지면 Impl은 어떡해
인터페이스를 통해 접근하는 것을 권장하고 있기 때문.(확장성)
그래서 서비스 레이어는 인터페이스(BookService)와 클래스(BookServiceImpl)를 함께 사용함
Impl : implement의 약자
*/
//"프링아 이 클래스 서비스 클래야"라고 알려주자. 프링이가 자바빈으로 등록해줌.
@Service
public class BookServiceImpl implements BookService {
// 도서 등록
@Override
public int createPost(BookVO bookVO) {
return 0;
}
}
sqlSessionTemplate(백신) -> BookDao(사람)
DAO =>
// 매퍼xml(book_SQL.xml)을 실행시키는
// DAO(Data Access Object) 클래스
// Repository 어노테이션 : 데이터에 접근하는 클래스
// 스프링이 데이터를 관리하는 클래스라고 인지하여 자바빈으로 등록하여 관리함
@Repository
public class BookDao {
//DI(Dependency Injection) : 의존성 주입
//new 키워드를 통해 직접 생성하지 않고!!!
//스프링이 미리 만들어 놓은(서버 실행 시 스프링이 미리 xml을 읽어
//객체를 인스턴스화 해놓음)
//sqlSessionTemplate 타입 객체를 BookDao 객체에 주입함
@Autowired // root-context에 bean으로 미리 저장되어 있어서 주입해서 사용 => @Autowired
SqlSessionTemplate sqlSessionTemplate;
public int createPost(BookVO bookVO) {
//book_SQL.xml 파일의 namespace가 book이고, id가 insert인
//태그를 찾아 그 안에 들어있는 sql을 실행함
//bookVO=>{"bookId":"","title":"총알탄 개똥이","category":"소설","price":10000,"insertDate":""}
//insert,update,delete는 반영된 건수가 return됨
//insert성공 : 1이상, 실패면 0
this.sqlSessionTemplate.insert();
}
}
xml =>
<!-- namespace : xml파일은 여러개일 수 있음. 이를 구별하기 위한 식별 용도로 사용 -->
<mapper namespace="book">
<!-- MyBatis에서 제공해주는 데이터 입력을 나타내는 태그
1) 드루와 : Dao 객체가 던진 데이터타입.parameterType만 씀
2) 가즈아 : Dao 객체의 메소드 쪽으로 리턴할 타입.
- resultType : vo, hashMap, String, int
- resultMap : MyBatis의 resultMap 태그를 사용
-->
<!-- bookVO(전)=>{"bookId":"","title":"총알탄 개똥이","category":"소설","price":10000,"insertDate":""} -->
<!-- bookVO(후)=>{"bookId":"1","title":"총알탄 개똥이","category":"소설","price":10000,"insertDate":""} -->
<!-- 마이바티스 쿼리 XML에 전달되면 샵{title}을 "총알탄 개똥이"로 자동 변환함 -->
<!-- insert/update/delete의 경우 resultType은 생략(명확한 int 타입이므로) -->
<insert id="createPost" parameterType="bookVO" >
INSERT INTO BOOK(BOOK_ID, TITLE, CATEGORY, PRICE, INSERT_DATE)
VALUES(1, #{title}, #{category}, #{price}, SYSDATE)
</insert>
</mapper>
dao =>
// 도서 등록
public int createPost(BookVO bookVO) {
// book_SQL.xml 파일의 namespace가 book이고, id가 createPost인 태그를 찾아 그 안에 들어있는 sql을 실행함
// bookVO=>{"bookId":"","title":"총알탄 개똥이","category":"소설","price":10000,"insertDate":""}
// insert,update,delete는 반영된 건수가 return됨
// insert성공 : 1이상, 실패면 0
return this.sqlSessionTemplate.insert("book.createPost", bookVO); // "mapper.id"
}
id 중복 방지
xml =>
<!-- insert/update/delete의 경우 resultType은 생략(명확한 int 타입이므로) -->
<insert id="createPost" parameterType="bookVO" >
<!--
order : BEFORE(쿼리를 실행하기 전에 먼저 selectKey를 실행
resultType : selectkey 쿼리를 실행한 타입
keyProperty : bookVO의 멤버변수(결과 담을 멤버변수)
-->
<selectKey resultType="int" order="BEFORE" keyProperty="bookId" >
SELECT NVL(MAX(BOOK_ID), 0) + 1 FROM BOOK
</selectKey>
INSERT INTO BOOK(BOOK_ID, TITLE, CATEGORY, PRICE, INSERT_DATE)
VALUES(#{bookId}, #{title}, #{category}, #{price}, SYSDATE)
</insert>