2022.01.17 TIL

서승원·2022년 1월 17일
0

TIL

목록 보기
55/68
post-thumbnail

Spring Framework 첫 사용
그동안 Spring이 포함하고 있는 함수들을 직접 만들어서 사용해보거나 하나하나 뜯어서 살펴본 뒤 직접 사용해보니 매개변수 입력이나 return에 대한 이해가 수월했다.

간단한 사용법

ApplicationContext

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
public class Test553 {
    public static void main( String[] args ) {
        AbstractApplicationContext spring = new ClassPathXmlApplicationContext("spring_01.xml");
        ApplicationContext spring2 = spring;
        
        Object obj = spring2.getBean("t");
        System.out.println( obj );
        
        Object obj2 = spring2.getBean("t");
        System.out.println( obj == obj2 );
        
        spring.close();
    }
}
 
/*
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">
    
    <bean id="t" class="kiwi.Bean01"/>
    
</beans>
*/
cs

먼저 Bean class 와 xml파일 설정, ApplicationContext를 이용한 기초적인 사용법을 알아봤다.
ApplicationContext는 대부분의 중요한 함수를 포함하고 있는 인스턴스를 생성하고 관리하는 관리자와도 같다. xml 파일에 설정한 id와 그와 연결된 Bean class를 이용해서 Spring의 함수들을 사용하는데, Bean 클래스는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
package kiwi;
 
public class Bean01 {
    
    public Bean01() { }
    
    private String name = "";
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}
 
cs
Bean class의 조건으로는
1.default 생성자를 가져야 한다.
2. 멤버변수는 property 형태로 가져야 한다.
3. 이벤트는 위임형 이벤트 모델( Deligation Model ) 을 사용한다.

Bean01.java 역시 멤버변수 name과 setter,getter를 갖췄고 생성자함수를 가지고 있다. xml 파일에서는 인스턴스에 대한 설정을 대신하여 property를 대입할 수도 있고, ref를 이용해 인스턴스에 대한 포인터를 쉽게 얻을 수도 있다. 인스턴스의 property 이하에는 list, set, map 등의 자료구조를 모두 사용할 수 있고 다양한 종류의 값을 사용할 수 있다.

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
public class Test559 {
    public static void main( String[] args ) {
        AbstractApplicationContext spring = new ClassPathXmlApplicationContext("spring_06.xml");
        ApplicationContext spring2 = spring;        
        
        Bean05 t = spring2.getBean("t", Bean05.class );
        Properties props = t.getDic();
        
        System.out.println( props.getProperty("apple") );
        System.out.println( props.getProperty("banana") );
        System.out.println( props.getProperty("mango") );
        
        spring.close();
    }
}
 
/*
<bean id="t" class="kiwi.Bean05">
    <property name="dic">
        <props>
            <prop key="apple">사과</prop>
            <prop key="banana">바나나</prop>S
            <prop key="mango">망고</prop>
        </props>
    </property>
</bean>
*/
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.List;
import java.util.Properties;
 
public class Bean05 {
    
    public Bean05() { }
    
    private Properties dic = null;
 
    public Properties getDic() {
        return dic;
    }
 
    public void setDic(Properties dic) {
        this.dic = dic;
    }
    
}
cs

위와 같이 property 역시 많이 사용하는데 Map<String, String> 과 비슷한 쓰임새다.
Bean05에서 Properties 로 dic 이라는 멤버변수를 선언하고, xml에서 key와 value를 짝지어서 설정했다.

JdbcTemplate

DAO를 개발할 시 예외처리, 인스턴스와 클래스에 대한 설정 등 jdbc 영역에서 처리해야할 전,후의 상황들이 많다. 이런 여러 고려사항들을 신경쓰지 않아도 될 만큼 처리를 한 후 class를 통해 한꺼풀 씌운 것을 JdbcTemplate 라고 볼 수 있다.

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
34
35
36
37
38
39
40
public class Test562 {
    public static void main(String[] args) {
        AbstractApplicationContext spring = new ClassPathXmlApplicationContext("spring_x1.xml");
        JdbcTemplate jdbcTemplate = spring.getBean("jtpl", JdbcTemplate.class );
        System.out.println( jdbcTemplate );
 
        int uc = jdbcTemplate.update("INSERT INTO spring_T VALUES (100,'Hello')");
        System.out.println( uc );
        
        spring.close();
    }
}
 
/*
 CREATE TABLE spring_T (
     no INT NOT NULL,
     data VARCHAR(10) NULL
 );
 * 
 * 
 * JdbcTemplate 내부 함수 구조
 public int update( String sql ) throws Exception {
        int uc = 0;
        Connection conn = null;
        PreparedStatement stmt = null;
        try {
            Class.forName("org.mariadb.jdbc.Driver");
            conn = dataSource.getConnection();
            stmt = conn.prepareStatement( sql );
            uc = stmt.executeUpdate();
        }
        catch( Exception e ) { throw e; }
        finally {
            if( stmt != null ) stmt.close();
            if( conn != null ) conn.close();
        }
        return uc;
    }
 */
cs

위와 같이 JdbcTemplate 를 이용해 Test562 를 만든 후 , update를 사용해 mariaDb에 생성한 테이블 spring_T 에 레코드를 추가해봤다. update의 기능에 맞도록 주석에 가상으로 작성한 코드다. xml 파일에 작성한 db에 대한 접근을 이용해 conn과 stmt를 선언하고, 매개변수로 입력한 sql문을 실행시키는 구조다.

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
public class Test564 {
    public static void main(String[] args) {
        AbstractApplicationContext spring = new ClassPathXmlApplicationContext("spring_x1.xml");
        JdbcTemplate jdbcTemplate = spring.getBean("jtpl", JdbcTemplate.class );
        
        RowMapper<SpringVO> rm = new RowMapper<SpringVO>() {
 
            @Override
            public SpringVO mapRow(ResultSet rs, int count) throws SQLException {
                SpringVO vo = new SpringVO();
                vo.setNo( rs.getInt("no") );
                vo.setData( rs.getString("data") );
                return vo;
            }
        };
        
        List<SpringVO> rl = jdbcTemplate.query("SELECT * FROM spring_T", rm );
        for( SpringVO t : rl ) {
            System.out.println( t.getNo() + "," + t.getData() );
        }
        spring.close();
    }
}
 
 
cs
미리 만들어본 임시적인 mapRow와 같이 사용했을 때 역시 정상적으로 작동했다. 직접 mapRow 함수를 하나하나 살펴보며 직접 작성한 후 실제로 사용해보니 왜 mapRow 함수가 저런식으로 오버라이딩 되는건지, query 함수에 RowMapper를 왜 매개변수로 사용하는건지 이해할 수 있었다.
profile
2년차 백엔드 개발자, crimy

0개의 댓글