본문 바로가기
Android Studio

[중고마켓]안드로이드 앱 살리기-2

by devebucks 2020. 3. 22.
728x90

안녕하세요.

 

이번 글에서는 앱을 어떻게 살릴 지 생각해볼거에요.

 

일단 서버는 Heroku를 사용하기로 결정했는데, heroku에 옛날에 개발해 논 php를 올리려고 하니까 안되는거에요.

그래서 이럴바에야 기존꺼 버리고, Spring boot로 was서버를 개발하는게 낫겠다고 생각했어요.

 

일단 데이터베이스는 heroku-cleardb를 사용할 거라 db는 만들어 놨어요.

 

그리고, 일단 몸풀기로 가볍게, spring boot로 데이터베이스에서 값을 가져오는 로직을 짜보고, 이걸 안드로이드 스튜디오로 요청해서 결과값을 불러오는 걸 오늘 해보려고 해요.

 

 

Android Studio로 옛날 프로젝트를 import해오는데는 성공했지만,, 서버를 살려야 해요.

 

 

1. spring boot 모델 정하기

햇갈리게 하는 요소들이 있어요.

DAO는 실제 DB와의 연결해서 쿼리문을 실행하게 하는 모듈이고,

VO는 파라미터들이지요.

 

Controller.java-Service.java->ServiceImpl.java-> DAO.java -> DB

Controller.java-> Service.java -> VO.java -> DB

 


MVC 패턴에서 Service Model 의 역할
MVC 패턴의 핵심은 View는 자신이 요청할 Controller만 알고있으면 되고, Controller는 화면에서 넘어오는 매개변수들을 이용해 Service 객체를 호출하는 역할을 한다. Service 는 불필요하게 Http 통신을 위한 HttpServlet을 상속 받을 필요도 없는 순수한 자바 객체로 구성된다(그렇기에 Service 에 request나 response와 같은 객체를 매개변수로 받아선 안된다. 그걸 사용해야하는 작업은 컨트롤러에서 해야한다.). 그렇기에 자신을 어떤 컨트롤러가 호출하든 상관없이 필요한 매개변수만 준다면 자신의 비즈니스로직을 처리하게된다. 즉 모듈화를 통해 어디서든 재사용이 가능한 클래스파일이라는 뜻이다. 단순 Web 기반이 아니라 추후 native app 으로 view단이 변경되더라도 Service는 view에 종속적인 코드가 없기때문에 그대로 재사용 할 수 있어야 한다. 그리고 추가적인 요청사항이 들어오면 기존 소스를 수정하는게 아니라 기존 service 인터페이스를 구현한 다른 클래스를 구현해 그 객체를 사용하게끔 하는것이다.
 
출처: 
https://multifrontgarden.tistory.com/97
 [우리집앞마당]

 spring에서는 객체를 bean으로 생성하고 각 객체에 의존성을 주입해서 사용하는 것으로 알고 있습니다. 그래서 service라는 뼈대를 만들어 놓고 다형성을 구현하기 위해 serviceimpl을 만들어 특정한 기능을 부여할 수 있게 사용한다고 생각합니다. 뼈대만 만들어놓고 안에 있는 내용만 바꿀 수 있다면 유지 보수 차원에서 굉장히 용이하기 때문입니다. 예를들어 식당이라는 객체에 접시1과 접시2라는 주입되어 있을 때 접시 1과 접시 2의 생김새만 만들어 놓으면 음식을 자유자재로 바꿀 수 있는거죠. 만약 interface로 뼈대를 만들어 놓지 않는다면 기능이 바뀔 때마다 새로운 메소드를 만들게 되서 연관된 파일을 전부 수정해야하는 불상사가 발생합니다.

 

1. cleardb dbtool 연결

테이블 생성 

 

 

 

2. pom.xml에 MySQL 연결 dependency를 추가합니다.

작성할 위치 : 프로젝트에서 가장 하단에 pom.xml

1
2
3
4
5
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

 

 

 

3. application.properties에 DB정보 입력하기

작성할 위치 : src/main/resource/application.properties

1
2
3
4
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://디비접속 호스트 URI
spring.datasource.username=디비접속 아이디
spring.datasource.password=디비접속 비밀번호

 

 

 

4. Test코드 작성

실제 JUnit이 실행되는 소스입니다. dbConnection 객체와 sqlSession객체를 생성해서 로그로 찍어 볼게요.

작성할 위치 : src/test/java

MarketApplication.java에 작성한 내용.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 
 
 
 
@RunWith(SpringRunner.class)
@SpringBootTest
class Market2ApplicationTests {
    @Autowired
    private SqlSessionFactory sqlSession;
    
    @Autowired
    private DataSource ds;
 
    @Test
    void contextLoads() throws SQLException {
        System.out.println("DataSouce 객체 : "+ds);
        Connection con = ds.getConnection();
        System.out.println("Connection 객체 : "+con);
        System.out.println("sqlSession 객체 : " + sqlSession);
        con.close();
    }
}
 
 

 

 

 

 

4. JUnit 테스트로 객체 생성 확인

 

DataSource

Connection

sqlSession 

 

 

 

이제는 db에 값을 넣는 테스트를 해 볼 거에요.

5. VO.java 생성하기 + lombok 사용

 

작성할 위치 : src/main/java

패키지 생성 : com.market.VO

VO 생성 : Member.java

lombok 설명 및 설치 

MemberVO.java 작성 내용 : 

package com.market.VO;
 
import lombok.Data;
 
@Data
public class MemberVO {
    private String nickName;
private String gender;
}
 

 

6. MemberMapper.java

실제로 crud 쿼리가 작성되는 곳. 

작성할 위치 : src/main/java

패키지 생성 : com.market.mapper

Mapper 생성 : MemberMapper.java

MemberMapper.java 작성 내용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.market.mapper;
 
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import com.market.VO.MemberVO;
 
public interface MemberMapper {
        @Insert("insert into member (nickName, gender) values (#{nickName}, #{gender})")
        public void create(MemberVO vo) throws Exception;
        
        @Delete("delete from member where no=#{no}")
        public void delete(MemberVO vo) throws Exception;
        
        @Update("update member set nickName=#{nickName}, gender=#{gender} where no=#{no}")
        public void update() throws Exception;
        
        @Select("select * from member where no=#{no}")
        public MemberVO read(String no)throws Exception;
}
 
 

 

 

7. 테스터 코드 입력

실제 JUnit이 실행되는 소스입니다.

작성할 위치 : src/test/java

MarketApplication.java에 작성한 내용.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.example.demo;
 
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import com.market.VO.MemberVO;
import com.market.mapper.MemberMapper;
 
public class crudTest extends Market2ApplicationTests{
    
    @Autowired
    MemberMapper mapper;
    
    @Test
    public void testInsert()throws Exception{
        MemberVO vo = new MemberVO();
        vo.setNickName("nickname");
        vo.setGender("M");
        mapper.create(vo);
    }
}
 
 

 

 

 

오류

 

에러 메시지 : 

Error creating bean with name 'com.example.demo.test': Unsatisfied dependency expressed through field 'mapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.market.mapper.MemberMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

at 

원인

@MapperScan()함수는 mybatis-spring에서 제공하는 애노테이션입니다. 프로젝트에 Mapper인터페이스를 인식시킵니다.

value={} 형식으로 배열로 나열할 수 있습니다.

 

"org.market.mapper"의 패키지 이름이 아니라, "com.market.mapper"였습니다. 패키지 이름을 잘못 써준 것이 문제였습니다.

그래서 

 

해결방법

패키지 이름을 정확히 적어주었습니다.

 

 

문제 해결

 

1. auto_increment가 10씩 증가하고 있음;;;

10씩 증가하는 auto_increment

해결 방법 dbTool에 다음 코드를 입력한다.

1
2
3
4
5
-- 증가값 조회
select  @@auto_increment_increment;
 
-- 증가값 변경
SET @@auto_increment_increment=1;

 

728x90

댓글