728x90
메시지 전송 기능 예제
간단한 메시지 전송 기능 구현, AOP를 통해 종단관점(메시지 전송기능), 횡단관점(로그출력, 트랜잭션)을 분리
사용자가 메시지를 발신하면 10포인트 적립하는 기능 구현
기능 수행시 입력되는 매개변수와 메서드 실행시간을 확인하는 로그를 출력하고, 메시지 발송 오류시 포인트 적립을 롤백하는 트랜잭션 작동
메시지 전송로직 구현
1. DB(Oracle) 테이블 생성 및 사용자 레코드 입력
-- 1. 사용자 테이블 생성
CREATE TABLE tbl_user(
userid VARCHAR2(50) NOT NULL,
userpw VARCHAR2(50) NOT NULL,
uname VARCHAR2(100) NOT NULL,
upoint NUMBER DEFAULT 0,
PRIMARY KEY(userid)
);
-- 2. 메시지 저장 테이블 생성
CREATE TABLE tbl_message(
mid NUMBER NOT NULL,
targetid VARCHAR2(50) NOT NULL,
sender VARCHAR2(50) NOT NULL,
message VARCHAR2(4000) NOT NULL,
opendate DATE,
senddate DATE DEFAULT SYSDATE,
PRIMARY KEY(mid)
);
-- 3. 시퀀스 생성
CREATE SEQUENCE message_seq START WITH 1 INCREMENT BY 1;
-- 3. 제약조건(FK설정)
ALTER TABLE tbl_message ADD CONSTRAINT fk_usersender
FOREIGN KEY (sender) REFERENCES tbl_user(userid);
ALTER TABLE tbl_message ADD CONSTRAINT fk_usertarget
FOREIGN KEY (targetid) REFERENCES tbl_user(userid);
-- 사용자 추가(Insert)
INSERT INTO tbl_user (userid, userpw, uname) VALUES ('user01', '1234', 'kim');
INSERT INTO tbl_user (userid, userpw, uname) VALUES ('user02', '1234', 'lee');
INSERT INTO tbl_user (userid, userpw, uname) VALUES ('user03', '1234', 'park');
INSERT INTO tbl_user (userid, userpw, uname) VALUES ('user04', '1234', 'choi');
INSERT INTO tbl_user (userid, userpw, uname) VALUES ('user05', '1234', 'yoon');
INSERT INTO tbl_user (userid, userpw, uname) VALUES ('user06', '1234', 'yang');
INSERT INTO tbl_user (userid, userpw, uname) VALUES ('user07', '1234', 'cho');
INSERT INTO tbl_user (userid, userpw, uname) VALUES ('user08', '1234', 'koo');
COMMIT;
2. 사용자, 메시지 테이블간의 관계도
메시지 테이블의 수신자(FK), 발송자(FK)가 사용자 테이블의 사용자아이디(PK)를 참조
메시지 전송 코드
1. Controller : 흐름제어
@RestController로 json으로 된 데이터를 전달
ResponseEntity로 HTTP상태코드와 데이터를 리턴
@RestController
@RequestMapping("/messages/*")
public class MessageController {
@Inject
MessageService service;
// ResponseEntity : HTTP상태코드 + 데이터 전달
// @RequestBody : 클라이언트 => 서버 (json 데이터가 입력될 때)
// @ResponsetBody : 서버 => 클라이언트 (json) RestController에서는 생략가능
@RequestMapping(value="/", method=RequestMethod.POST)
public ResponseEntity<String> addMessage(@RequestBody MessageVO vo){
ResponseEntity<String> entity = null;
try {
service.addMessage(vo);
// new ResponseEntity<자료형>(리턴값, HTTP상태코드);
entity = new ResponseEntity<String>("success", HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
entity = new ResponseEntity<String>(e.getMessage(), HttpStatus.BAD_REQUEST);
}
return entity;
}
}
2. Service : 비지니스 로직, 핵심 기능 수행
메시지를 테이블에 저장
메시지를 발송한 사용자에게 10포인트 적립
@Service
public class MessageServiceImpl implements MessageService {
@Inject
MessageDAO messageDao;
@Inject
PointDAO pointDao;
// 메시지 작성(DB저장, 포인트적립)
@Transactional // 트랜잭션처리 대상 메서드
@Override
public void addMessage(MessageVO vo) {
// 공통업무 - 로그 확인
// 핵심업무 - 메시지 저장, 회원 포인트 적립
// 메시지를 테이블에 저장
messageDao.create(vo);
// 메시지를 발송한 사용자에게 10포인트 적립
pointDao.updatePoint(vo.getSender(), 10);
}
// 메시지 열람
@Override
public MessageVO readMessage(String userid, int mid) {
return null;
}
}
3. VO : 데이터 객체, 값 전달
UserVO - 사용자 정보
public class UserVO {
private String userid; // 사용자ID
private String userpw; // 사용자PW
private String uname; // 사용자이름
private int upoint; // 사용자적립포인트
// Getter/Setter
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getUserpw() {
return userpw;
}
public void setUserpw(String userpw) {
this.userpw = userpw;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public int getUpoint() {
return upoint;
}
public void setUpoint(int upoint) {
this.upoint = upoint;
}
// toString
@Override
public String toString() {
return "UserVO [userid=" + userid + ", userpw=" + userpw + ", uname=" + uname + ", upoint=" + upoint + "]";
}
}
MessageVO - 메시지 정보
public class MessageVO {
private int mid; // 메시지 pk
private String targetid; // 수신자
private String sender; // 발신자
private String message; // 메시지 내용
private Date opendate; // 열람일자
private Date senddate; // 보낸날짜
// Getter,Setter
public int getMid() {
return mid;
}
public void setMid(int mid) {
this.mid = mid;
}
public String getTargetid() {
return targetid;
}
public void setTargetid(String targetid) {
this.targetid = targetid;
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Date getOpendate() {
return opendate;
}
public void setOpendate(Date opendate) {
this.opendate = opendate;
}
public Date getSenddate() {
return senddate;
}
public void setSenddate(Date senddate) {
this.senddate = senddate;
}
// toString
@Override
public String toString() {
return "MessageVO [mid=" + mid + ", targetid=" + targetid + ", sender=" + sender + ", message=" + message
+ ", opendate=" + opendate + ", senddate=" + senddate + "]";
}
}
4. DAO : DB연동 작업 처리
PonintDAOImpl - 사용자 테이블 연동 작업 처리
@Repository
public class PonintDAOImpl implements PointDAO {
@Inject
SqlSession sqlSession;
// 회원 포인트 갱신(메시지 발신)
@Override
public void updatePoint(String userid, int upoint) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("userid", userid);
map.put("upoint", upoint);
sqlSession.update("point.updatePoint", map);
}
}
MessageDAOImpl - 메시지 테이블 연동 작업 처리
@Repository
public class MessageDAOImpl implements MessageDAO {
@Inject
SqlSession sqlSession;
// 메시지 작성
@Override
public void create(MessageVO vo) {
sqlSession.insert("message.create", vo);
}
// 메시지 열람
@Override
public MessageVO readMessage(int mid) {
return null;
}
// 메시지 열람시간 갱신
@Override
public void updateMessage(int mid) {
}
}
5. Mapper : SQL문 수행 작업 처리
messageMappper.xml - 메시지 저장 insert
<mapper namespace="message">
<insert id="create">
INSERT INTO tbl_message (mid, targetid, sender, message)
VALUES (message_seq.NEXTVAL, #{targetid}, #{sender}, #{message})
</insert>
</mapper>
pointMapper.xml - 포인트 적립 update
<mapper namespace="point">
<update id="updatePoint">
UPDATE tbl_user SET upoint = upoint + #{upoint}
WHERE userid = #{userid}
</update>
</mapper>
6. View : 클라이언트 화면
Advanced Rest Client로 대체
기능 구현 확인
1. 메시지 전송 - Advanced Rest Client로 데이터 입력
user02사용자가 user01사용자에게 “Hello” 메시지 전송
2. DB 확인
메시지 테이블에 발송한 메시지 저장완료(insert)
사용자 테이블에 발송한 회원의 레코드에 10포인트 적립완료(update)