relationships - JDBC -> Mybatis, JPA, Hibernate
Spring - DB와 연결해주는 역할, 템플릿툴을 제공
--DB Setting
<!-- DB Setting -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="/WEB-INF/mybatis-config.xml"/>
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/oracle"/>
<property name="resourceRef" value="true"/>
</bean>
bean객체 -> spring container에 위치
ref = 객체, value = 문자열 전달(경로)
mybatis-config.xml, DAO 없어짐 이후로
데이터액세스오브젝트(DAO) : 템플릿을 필요로 함
DAO에서 sqlSessionTemplate 사용(Dependency Injection방법으로 호출하면 container에서 객체 자동생성)
private SqlSessionTemplate sqlTemplate;
view - tiles(template)
view-module-template : layout template만 수정하면 됨 - 일관성있게 유지보수가능
web-inf - tiles2def.xml
<tiles-definitions>
<definition name="base_layout" template="/view/module/template.jsp">
<put-attribute name="logo" value="/view/module/logo.jsp"/>
<put-attribute name="header" value="/view/module/header.jsp"/>
<put-attribute name="footer" value="/view/module/footer.jsp"/>
</definition>
<definition name="insert_form" extends="base_layout">
<put-attribute name="body" value="/view/insert_form.jsp"/>
</definition>
<definition name="list" extends="base_layout">
<put-attribute name="body" value="/view/list.jsp"/>
</definition>
<definition name="detail" extends="base_layout">
<put-attribute name="body" value="/view/detail.jsp"/>
</definition>
</tiles-definitions>
모든 definition은 container가 알고있어야 한다
<!-- Tiles Setting -->
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles2def.xml</value>
</list>
</property>
</bean>
<bean id="viewResolver2" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView"/>
<property name="order" value="1"/>
</bean>
<!-- /view/hello.jsp -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/view/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="2"/>
</bean>
-->internalresuource는 null값을 return할 수 없기 때문에 하위우선순위가 됨
--파일업로드
라이브러리추가
입력폼에서 encytype=multipart추가
파일 입력 input추가
board객체에 multipartfile 추가, get, set method 추가
xml에서
<!-- File UP/Down Setting -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
</bean>
BoardController에서
private String uploadDir = "C:/Upload/File";
@RequestMapping(value="/board_insert", method=RequestMethod.POST)
public String board_insert(@ModelAttribute("boardCommand") @Valid Board board, BindingResult errors){
if(errors.hasErrors()){
System.out.println("에러발생");
return "insert_form";
}
MultipartFile multipartFile = board.getUploadFile();
if(multipartFile != null){
String filename = multipartFile.getOriginalFilename();
board.setFname(filename);
try {
multipartFile.transferTo(new File(uploadDir, filename));//파일업로드 수행
} catch (Exception e) {
e.printStackTrace();
}
}
dao.insert(board);
return "redirect:board_list";
}
board.xml
<insert id="insertBoard" parameterType="Board">
insert into board values(board_seq.nextval, #{title}, #{writer},
#{contents}, sysdate, 0, #{fname})
</insert>
--파일다운로드
--detail.jsp
<li><a href="board_download?filename=${board.fname }">${board.fname }</a></li>
--board.controller
@RequestMapping("/board_download")
public String board_download(@RequestParam("filename") String filename, Model model)throws Exception{
File file = new File(uploadDir, filename);
model.addAttribute("downloadFile", file);
return "downloadView";
}
--servlet
<bean id="downloadView" class="kosta.view.DownloadView"/>
**새로운 뷰를 만들었기 때문에 새로 생성해줘야 함.
<bean id="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="1"/>
</bean>
--json(ajax)
-client(ajax) => server(RestController-view필요없고 data만 전달)에 요청
-server(json으로 데이터 전달) -> jsp가 값을 받아서 화면에 표시
-json controller : view만들어줄 필요없이 json으로 다루기 가능
[
{"이름" : 홍길동,
"주소": 가산
},
{}
]
BoardController -> client.jsp -> JsonController
@RequestMapping("json_index")
public String json_index(){
return "client";
}
$(function(){
$.getJSON("spring_json", function(data){
//var data = responseData.list;
//alert(data);
$.each(data, function(index, member){
$('#result').append('<tr><td>' + member.name + '</td>'
+ '<td>' + member.address + '</td></tr>');
});
});
});
@RestController
public class JsonController {
@RequestMapping("/spring_json")
public List<Member> spring_json(){
List<Member> list = new ArrayList<>();
list.add(new Member("홍길동","가산"));
list.add(new Member("박길동","강남"));
return list;
}
}
**ajax요청 -> jsonController 임의의 객체 list를 return해보기
json코드를 html로 표현하기
--AOP(Aspect Oriented Programming)
-
Aspect(공통 관심사항)
-
JointPoint
-
Pointcut
-
Advice
-
Weaving
POJO Class를 이용한 AOP구현
스프링 api를 이용한 AOP구현
**Annotation을 이용한 AOP 구현
AOP는 설계단계에서부터 합의된대로 만들어야 한다.
원래 호출하고 싶은 메소드가 공통관심사 -> 중복되니까 AOP로 작성 -> 확장이 용이
--SessionAspect.java
@Aspect //공통관심사
public class SessionAspect {
@Around("execution(public * kosta.controller.*.*do(..))")
public String sessionCheck(ProceedingJoinPoint joinPoint) throws Throwable{
Object[] obj = joinPoint.getArgs();
HttpServletRequest request = (HttpServletRequest)obj[0];
HttpSession session = request.getSession();
String name = (String)session.getAttribute("name");
String view = "session/session_fail"; //실패했을때의 뷰는 항상 같기때문에 하나로 정해줌
try {
if(name == null){
throw new Exception("no Session");//예외 발생
}
view = (String)joinPoint.proceed(); //session_do() 호출, Object->string으로 형변환
} catch (Exception e) {
return view;//fail
}
return view;//success
}
}
-SessionController
@Controller
public class SessionController {
@RequestMapping("/session_req")
public String session_req(){
return "session/session_req";
}
@RequestMapping("/session_do")
public String session_do(HttpServletRequest request){
return "session/session_success";
}
@RequestMapping("/session_add")
public String session_add(){
return "session/session_add";
}
}
--TRANSACTION
**Annotation을 이용한 transaction
구현
--OrderService
@Service
public class OrderService {
private OrderDao orderDao;
private ItemDao itemDao;
@Autowired
public void setOrderDao(OrderDao orderDao) {
this.orderDao = orderDao;
}
@Autowired
public void setItemDao(ItemDao itemDao) {
this.itemDao = itemDao;
}
@Transactional(propagation=Propagation.REQUIRED, rollbackFor={Exception.class})//예외발생시 롤백진행
public void orderAction(Order order) throws Exception{
orderDao.addOrder(order);
if(itemDao.findItem(order.getNo()).getAmount()<order.getAmount()){//재고수량<주문수량
throw new Exception("재고가 부족합니다."); //재고가 없을 시 주문도 자동취소되도록 한묶음으로 트랜잭션 처리
}
itemDao.updateItem(order);
}
}
--OrderController
@Controller
public class OrderController {
private OrderService service;
@Autowired
public void setService(OrderService service) {
this.service = service;
}
@RequestMapping("/orderForm")
public String orderForm(){
return "transaction/orderForm";
}
@RequestMapping("/order")
public String order(Order order){
String view = "transaction/orderOk";
try {
service.orderAction(order);
} catch (Exception e) {
System.out.println("재고가 부족합니다");
view = "transaction/orderForm";
}
return view;
}
}
'FULLSTACK > SPRING' 카테고리의 다른 글
12/7~8 Spring Boot, JPA (0) | 2020.12.08 |
---|---|
STS기반 SPRING - 구멍가게코딩단 책과 함께합니다 (0) | 2020.11.13 |
SPRING 3차시 - DB연결, RESTful방식 (0) | 2020.11.13 |
SPRING 2차시 - AOP (0) | 2020.11.13 |
SPRING 1차시 - Dependency Injection (0) | 2020.11.13 |