Spring Project 설정 / 개발 순서

SangWoo·2022년 5월 12일
1

pom.xml 추가/설정 및 수정

<properties>
		<java-version>11</java-version>
		<org.springframework-version>5.0.7.RELEASE</org.springframework-version>
		<org.aspectj-version>1.6.10</org.aspectj-version>
		<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.5.9</version>
</dependency>
<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>2.0.7</version>
</dependency>
<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${org.springframework-version}</version>
</dependency>
<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.28</version>
</dependency>

<!-- Servlet -->
<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>4.0.1</version>
			<scope>provided</scope>
</dependency>

<!-- Test -->
<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${org.springframework-version}</version>
			<scope>test</scope>
</dependency>
<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
</dependency>

DataSource 작성

// root-context.xml
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
		<property name="url" value="jdbc:mysql://localhost:3306/스키마_이름"></property>
		<property name="username" value="커넥션_ID"></property>
		<property name="password" value="커넥션_PWD"></property>
	</bean>

※ DataSource를 작성한 후에는 테스트코드를 이용해서 테스트를 진행합니다.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= {"file:src/main/webapp/WEB-INF/spring/root-context.xml"})
public class DataSourceTest {
	@Autowired
	private DataSource ds;
	
	@Test
	public void test() throws Exception {
		
		try(Connection con = ds.getConnection()) {
			System.out.println("con = " + con);
		} catch (Exception e) {
			// TODO: handle exception
		}
		
	}

}
// 실행결과
con = com.mysql.cj.jdbc.ConnectionImpl@77c7ed8e
  • Connection 객체가 만들어지는 것을 확인합니다.

SQL

  • SQL 테이블 설계 및 작성합니다.

DTO

  • SQL 테이블과 관련된 개체 설계 및 작성합니다.
public class UserDto {
	private String id;
	private String pwd;
	private String name;
	private String email;
	private Date birth;
	private String sns;
	private Date reg_date;
    
    // 생성자 생략..
    // Getter/Setter 생략..
    // toString 생략..
    // hash/equals 생략..
}

Mapper

  • Resources 폴더 내에 *Mapper.xml를 작성합니다.
	<delete id="deleteUser" parameterType="String">
		delete from user_info
		where id = #{id}
	</delete>
	
	<select id="selectUser" parameterType="String" resultType="UserDto">
		select * from user_info
		where id = #{id}
	</select>
// insert, update 생략...

Alias

// mybatis-config.xml
<configuration>
	<typeAliases>
		<typeAlias alias="BoardDto" type="com.fastcampus.ch4.domain.BoardDto"/>
		<typeAlias alias="UserDto" type="com.fastcampus.ch4.domain.UserDto"/>
	</typeAliases>
</configuration>
// Mapper.xml                                             **alias**
<select id="selectUser" parameterType="String" resultType="UserDto"> 
		select * from user_info
		where id = #{id}
</select>
  • XML Mapper를 이용하는데 있어서 parameterType, resultType을 패키지까지 포함된 클래스명을 작성하는 일이 번거롭다면 typeAlias를 작성합니다.

SessionFactory, SqlSessionTemplate 작성

// root-context.xml
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource"/>
		<property name="configLocation"  value="classpath:mybatis-config.xml"/>
		<property name="mapperLocations" value="classpath:mapper/*Mapper.xml"/>
	</bean>

	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg ref="sqlSessionFactory"/>
	</bean>
  • SessionFactory는 데이터베이스와의 연결과 SQL의 실행에 중요한 객체로 DataSource를 참조하여 MyBatis와 Mysql 서버를 연동시켜줍니다.
  • SqlSessionTemplate은 Mybatis 쿼리문을 수행해주는 역할을 합니다.
    DAO클래스에 직접 SqlSession 객체를 선언하고 쿼리문을 수행합니다.

DAO

  • 단일 데이터 접근/갱신을 처리하는 클래스로 Service에 의해 호출되어 DB CRUD를 담당합니다.
public class UserDaoImpl implements UserDao {
	@Autowired
	SqlSession session;
	String namespace = "인터페이스_전체_경로.";
	
	@Override
	public int deleteUser(String id) throws Exception {
		return session.delete(namespace+"deleteUser", id);
	}
	
	@Override
	public UserDto selectUser(String id) throws Exception {
		return session.selectOne(namespace+"selectUser", id);
	}
    // insert, update 생략..
}

※ DAO를 작성한 후에는 테스트코드를 이용해서 테스트를 진행합니다.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/root-context.xml"})
public class UserDaoImplTest {
	@Autowired
	UserDao userDao;
	
	@Test
	public void test() throws Exception {
		// 데이터 전체 삭제
        userDao.deleteAll(); 
		// 데이터 count 확인
        assertTrue(userDao.count()==0); 
        
        // DTO 데이터 작성
		UserDto userDto = new UserDto("asdf", "1234", "aaa", "aaa@aaa.com", new Date(), "facebook");
		// insert
        assertTrue(userDao.insertUser(userDto)==1); 
		// 데이터 count 확인
        assertTrue(userDao.count()==1);
		
        // DTO 데이터 변경
        userDto.setPwd("1111");
		userDto.setName("bbb");
        // update 및 성공 여부 확인
		assertTrue(userDao.updateUser(userDto)==1);
	}
}
  • 테스트는 다양하고 세밀하게 하는것이 좋습니다.

Service

@Service
public class UserServiceImpl implements UserService {
	@Autowired
	UserDao userDao;
	
	@Override
	public int removeUser(String id) throws Exception {
		return userDao.deleteUser(id);
	}
	
	@Override
	public UserDto getUser(String id) throws Exception {
		return userDao.selectUser(id);
	}
    // ...
}
  • business 영역은 일반적으로 서비스(Service)라는 이름을 칭합니다.
  • business 영역에 만들어지는 클래스나 인터페이스는 반드시 클라이언트의 요구사항과 일치하도록 설계돼야 합니다.
  • business 영역은 Controller와 DAO 사이에서 트랜잭션의 처리나 예외처리 등 Controller가 처리해야 하는 일을 분업하게 만들어 줍니다.

Controller

@Controller
@RequestMapping("/login/")
public class UserController {
	@Autowired
	UserService userService;
	
	@GetMapping("login")
	public String loginForm() {
		return "loginForm";
	}
    @PostMapping("login")
	public String login(String id, String pwd, boolean rememberId, String toURL,
			HttpServletResponse response, HttpServletRequest request) {
		if(loginChk(id, pwd)) {
			if(rememberId) {
				Cookie cookie = new Cookie("id", id);
				response.addCookie(cookie);
			} else {
				Cookie cookie = new Cookie("id", id);
				cookie.setMaxAge(0);
				response.addCookie(cookie);
			}
		} else {
			String msg = URLEncoder.encode("ID 또는 PWD가 일치하지 않습니다.");
			return "redirect:/login/login?msg="+msg;
		}
		HttpSession session = request.getSession();
		session.setAttribute("id", id);
		toURL = toURL == null || toURL.equals("") ? "/" : toURL;
		return "redirect:"+toURL;
	}
    // ...
}
  • 다른 사람에게 보낼수 있게 하려면 GET 방식으로 처리합니다.
  • 외부에 노출이 되지 않아야되는 경우에 POST 방식으로 처리합니다.

View(jsp, css, js)


0개의 댓글