템플릿이란 코드에서 변경이 거의 일어나지 않으며 일정한 패턴으로 유지되는 특성을 가진 부분을 자유롭게 변경되는 성질을 가진 부분으로 부터 독립시켜서 효과적으로 활용할 수 있도록 하는 방법이다.  쉽게 생각해서 코드에서 변하는 부분과 변하지 않는 부분을 분리시키자라는 의미이다.

아래 코드를 한번보자.  deleteAll() 함수와 add함수에서 함수별로 반복적으로 나타나는 부분(변화되지 않는 부분) 과 함수별로 다른 부분을 찾을수 있다.

두함수의 변하는 부분을 템플릿 메소트 패턴을 이용하여  따로 빼보자.

하지만 여기서도 문제가 존재한다. 새로운 DAO logic이 추가될때 마다 상속을 통해 새로운 클래스를 만들어한다는 것이다.

 

그래서 이번에는 전략패턴을 적용해 보도록 하자.  전략패을 적용하기 전에 용 변하는 부분을 인페이스로 만들어 보자.

시작전에  Context는 변하지 않는 부분, 전략은 바뀌는 부분  <- 이것을 머리에 넣어두고 아래글을 보면 더 이해가 쉽다.

deleteAll() 컨텍스트를 정리해보면 다음과 같다.

  • DB커넥션 가져오기
  • PreparedStatement를 만들어줄 외부기능 호출하기
  • 전달받은 PreparedStatement 실행하기
  • 예외가 발생하면 이를 다시 메소드 밖으로 던지기
  • 모든 경우에 만들어진 PreparedStatement와 Connection을 적절히 닫아주기

여기서 두번째 PreparedStatement를 만들어줄 외부기능 <- 이부분이 전략패턴에서 전략이라고 볼수 있다.  전략패턴의 구조를 따라 이부분을 인터페이스로 만들어 인터페이스메소드를 통해 PreparedStatement를 생성하는 전략을 호출해주면 된다. 이때 PreparedStatement를 생성할때 Context에서 만든 DB커넥션을 전달해줘야 한다.

전략 interface를 다음과 같이 만들어보자.

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public interface StatementStrategy {
	public PreparedStatement makeStatement(Connection c) throws SQLException; 
}

전략  interface를 상속받아 실제 전략 클래스를 만들면 다음과 같다.

public class DeleteAllStatement implements StatementStrategy {

	@Override
	public PreparedStatement makeStatement(Connection c) throws SQLException {
		// TODO Auto-generated method stub
		PreparedStatement ps=c.prepareStatement("delete from users");
		return ps;
	}
}

이제 delete전략 클래스를 실제 deleteAll메소드에 적용해 보도록 하자.

public void deleteAll() throws SQLException {
		Connection c = null;
		PreparedStatement ps = null;
		StatementStrategy strategy= new DeleteAllStatement();
		try {
			c = dataSource.getConnection();	
			ps=strategy.makeStatement(c);
			
			ps.executeUpdate();
		}catch(SQLException e) {
			throw e;
		}finally {
			if(ps != null) {
				try {
					ps.close();
				}catch(SQLException e) {
					
				}
			}
			if(c != null) {
				try {
					c.close();
				}catch(SQLException e) {
					
				}
			}
		}
	}	

그런데 컨텍스트 안에 이미 구체적인 적략 클래스인 DeleteAllStatement를 사용하도록 고정되어 있다면 뭔가 이상하다. 컨텍스트 특정 구현 클래스인 DeleteAllStatement를 직접 알고 있다는건, 전략패턴에도 OCP(Open Closed Principle)에도 맞지 않다.

DI 적용을 위한 클라이언트/컨텍스트 분리

전략패턴에 따르면 컨텍스트가 어떤 전략을 사용할지는 클라인트가 결정하는게 일반적이다. 클라이언트가 구체적인 전략 하나를 오브젝트로 만들어 컨텍스트에 전달해준다. 그러면 컨텍스트는 전달받은 오브젝트를 사용하게된다. 이를 표현 한것이 아래 그림이다.

결국 이구조에서 전략 오브젝트를 생성하고 컨텍스트로 전달 하는 것은 Object Factoty(client)이며, 이것이 바로 의존관계 주입(DI)에 해당된다. 이제 이패턴을 적용시켜보자. 아래 코드를 다시 살펴보면 try/catch/finally 부분이 context에 해당되며 StatementStrategy strategy= new DeleteAllStatement();  이부분이 전략에 해당된다.

public void deleteAll() throws SQLException {
		Connection c = null;
		PreparedStatement ps = null;
		StatementStrategy strategy= new DeleteAllStatement();
		try {
			c = dataSource.getConnection();	
			ps=strategy.makeStatement(c);
			
			ps.executeUpdate();
		}catch(SQLException e) {
			throw e;
		}finally {
			if(ps != null) {
				try {
					ps.close();
				}catch(SQLException e) {
					
				}
			}
			if(c != null) {
				try {
					c.close();
				}catch(SQLException e) {
					
				}
			}
		}
	}	

 

이제 context를 함수로 분리해보자. context은 전략을 전달 받아야 하니, 메소드 작성시  파라미터로 전략을 넣어주자.

public void jdbcContextWithStatementStrategy(StatementStrategy strategy) throws SQLException{
		Connection c = null;
		PreparedStatement ps = null;
		try {
			c = dataSource.getConnection();	
			ps=strategy.makeStatement(c);
			ps.executeUpdate();
			
		}catch(SQLException e) {
			throw e;
		}finally {
			if(ps != null) {
				try {
					ps.close();
				}catch(SQLException e) {
					
				}
			}
			if(c != null) {
				try {
					c.close();
				}catch(SQLException e) {
					
				}
			}
		}
	}

이제 클라이언트에 해당하는 deleteAll()부분도 수정해보자.  여기서 보면, 전략 객체 strategy를 만들어 Context에 넘겨 주고 있음을 확인할 수 있다. ( 이것이 바로 DI 이다)

public void deleteAll() throws SQLException {		
		StatementStrategy strategy= new DeleteAllStatement(); //1.선택한 전략 클래스의 오브젝트를 생성  
		jdbcContextWithStatementStrategy(strategy);           //2. 선택한 전략을 context에 넣어준다. 		
}	

이번에는 add()함수에서 사용할 AddStatement를 만들어보자.  

전략 Interface StatementStartegy 상속받은 AddStatement 클래스를 하나 만들었다.  그런데 여기서 DeleteAllStatement전략 클래스와 다른점이 있다. 바로 Usesr정보이다. 클라이언트에서 User정보를 넘겨주어야 한다. 그래서 생성자로 User정보를 넘겨받도록 수정하였다. 

public class AddStatement implements StatementStrategy {
	User user;
	public AddStatement(User user) {
		super();
		this.user = user;
	}
	@Override
	public PreparedStatement makeStatement(Connection c) throws SQLException {
		// TODO Auto-generated method stub
		PreparedStatement ps = c.prepareStatement(
				"insert into users(id, name, password) values(?,?,?)");
			ps.setString(1, user.getId());
			ps.setString(2, user.getName());
			ps.setString(3, user.getPassword());
		return ps;
	}
}

 이제 AddStatement 전략 클래스를 Context로 넘겨주도록 add() 함수를 수정 하면 아래와 같다. 전략 AddStatement 의 객체 생성시 user정보를 넘겨주었다. 그리고 strategy를 넘겨주어 PreparedStatement를 받고 있음을 확인할 수 있다.

public void add(User user) throws SQLException {
    // 1.선택한 전략 클래스의 오브젝트를 생성  , user정보 넘겨줌
	StatementStrategy strategy = new AddStatement(user);  
    //2. 선택한 전략을 context에 넣어준다. 
	jdbcContextWithStatementStrategy(strategy);
	
}

그런데 지금까지 해온 방법에는 두가지 문제가 있다.

  1. DAO 메소드마다 새로운 StaementStrategy 구현 클래스를 만들어야 하는점
  2. User와 같이 부가적인 정보가 있을때 전략클래스에 오브젝트를 전달 받는 생성자와 이를 저장할 인스턴스 변수를 생성해야 한다는 점

지금부터 이 두가지 문제를 해결해 보도록 하자.

첫번째 문제의 해결법은 간단하다. 아래와 같이 로컬 클래스를 사용하면 된다. 그러면 매번 전략 클래스을 따로 만들 필요가 없다.  다음 해결법을 시작하기전에 아래 add()함수를 한번 더보자. Addstatement 클래스 안에 user정보를 받는 생성자가 없다. 로컬 클래스를 사용하면 자신이 선언된 곳의 변수를 직접 사용할수 있기 때문이다.단, 로컬클래스에서 외부 변수를 사용할때는 final로 선언해줘야 한다. 그래서 add()함수의 파라미터 앞에 final을 선언했다. (user은 외부변수다.) 

public void deleteAll() throws SQLException {		
	class DeleteAllStatement implements StatementStrategy {
		@Override
		public PreparedStatement makeStatement(Connection c) throws SQLException {
			PreparedStatement ps=c.prepareStatement("delete from users");
			return ps;
		}
	}
	StatementStrategy strategy= new DeleteAllStatement(); // 이부분을 로컬 클래스로 변경
	jdbcContextWithStatementStrategy(strategy);		
}	
public void add(final User user) throws SQLException {
	class AddStatement implements StatementStrategy {
		@Override
		public PreparedStatement makeStatement(Connection c) throws SQLException {
			PreparedStatement ps = c.prepareStatement(
					"insert into users(id, name, password) values(?,?,?)");
			ps.setString(1, user.getId());
			ps.setString(2, user.getName());
			ps.setString(3, user.getPassword());
			return ps;
	    }
	}
	StatementStrategy strategy = new AddStatement();  
	jdbcContextWithStatementStrategy(strategy); 
}

여기서 좀더 간단하게 고쳐보자. AddStatement와 DeleteAllStatement 클래스는 해당 메소드에서만 사용되는 클래스이이므로 간결하게 클래스 이름도 제거해보자. 익명 클래스를 이용하면 가능하다. 

익명 내부 클래스는  이름을 갖지 않는 클래스이다. 클래스 선언과 오브젝트 생성이 결합된 형태로 만들어지며, 상속할 클래스나 구현할 인터페이스를 생성자 대신 사용해서 다음과 같은 형태로 만들어 사용한다. 클래스를 재사용할 필요가 없고, 구현한 인터페이스 타입으로만 사용할 경우에 유용하다.
 
new 인터페이스 이름( ) { 클래스 본문 }

아래는 익명 클래스로 수정한 코드다. 코드가 한결 간결해졌다.

public void deleteAll() throws SQLException {		
	jdbcContextWithStatementStrategy(
		new StatementStrategy() {
			public PreparedStatement makeStatement(Connection c) throws SQLException {
				PreparedStatement ps=c.prepareStatement("delete from users");
				return ps;
			}
		}				
	);		
}	
public void add(final User user) throws SQLException {	
	jdbcContextWithStatementStrategy(
		 new StatementStrategy() {
			 public PreparedStatement makeStatement(Connection c) throws SQLException {
					PreparedStatement ps = c.prepareStatement(
							"insert into users(id, name, password) values(?,?,?)");
						ps.setString(1, user.getId());
						ps.setString(2, user.getName());
						ps.setString(3, user.getPassword());
					return ps;
				}
		 }				
	);
}

 

JDBC Context의 분리 

우리가 지금까지 UserDao클래스 내부에서 사용했던 jdbcContextWithStatementStrategy() 메소드는 JDBC의 일반적인 작업 흐름을 담고 있기때문에 다른 DAO에서도 사용할 가능성이 크다. UserDao클래스 밖으로 독립시켜서 모든 DAO가 사용가능 하도록 분리해보자. JdbcContext 클래스를 만들고  jdbcContextWithStatementStrategy() 메소드를workWithStatementStrategy() 메소드로 이름만 변경했다.

public class JdbcContext {
	private DataSource dataSource;
	
	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}
	public void workWithStatementStrategy(StatementStrategy strategy) throws SQLException{
		Connection c = null;
		PreparedStatement ps = null;
		try {
			c = dataSource.getConnection();	
			ps=strategy.makeStatement(c); // <-- 이부분이 바뀌는 부분이다.. "전략" 적용하는 부분 
			ps.executeUpdate();
			
		}catch(SQLException e) {
			throw e;
		}finally {
			if(ps != null) {
				try {
					ps.close();
				}catch(SQLException e) {
					
				}
			}
			if(c != null) {
				try {
					c.close();
				}catch(SQLException e) {
					
				}
			}
		}
	}	
}

 그리고 deleteAll()메소드와 add()메소드에서 DI가 일어나는 부분의 함수 호출 부분을 아래와 같이 변경되었다.  

public class UserDao{
	JdbcContext jdbcContext;	
	public void setDataSource(DataSource dataSource) {		
		this.jdbcContext = new JdbcContext();	 
		this.jdbcContext.setDataSource(dataSource);
		this.dataSource = dataSource;
	}
	public void deleteAll() throws SQLException {		
		this.jdbcContext.workWithStatementStrategy(
			new StatementStrategy() {
				public PreparedStatement makeStatement(Connection c) throws SQLException {
					PreparedStatement ps=c.prepareStatement("delete from users");
					return ps;
				}
			}				
		);	
	}	
	public void add(final User user) throws SQLException {	
		this.jdbcContext.workWithStatementStrategy(
			 new StatementStrategy() {
				 public PreparedStatement makeStatement(Connection c) throws SQLException {
						PreparedStatement ps = c.prepareStatement(
								"insert into users(id, name, password) values(?,?,?)");
							ps.setString(1, user.getId());
							ps.setString(2, user.getName());
							ps.setString(3, user.getPassword());
						return ps;
					}
			 }				
		);
	}
}

스프링의 DI는 기본적으로 인터페이스를 사이에 두고 의존 클래스를 바꿔서 사용하도록 하는게 목적이다. 하지만 JdbcContext는 구현방법이 바뀔 가능성이 없다. 따라서 인터페이스로 구현하지 않았다. 그리고 한가지 재미 있는 점은 UserDAO에서 JdbcContext 에 직접 dataSource를 DI 해주고 있다는 점이다. 이 방법은 스프링에서 종종 사용되는 기법이다.

여러행의 특정 컬럼 값을 한줄로 나타내 주고 싶을때가 있다. 

이럴때 이용할수 있는 방법이 있어 정리해둔다. 

학년,반,점수 컬럼을 가지는 임의의 테이블을 하나 만들었다. 

WITH TABLE_A( 학년, 반,점수) AS (
    SELECT '1학년','1반',100 UNION ALL
    SELECT '2학년','1반',200 UNION ALL
    SELECT '3학년','1반',300 
)
SELECT * FROM TABLE_A

 

나는 아래와 같이 1학년,2학년,3학년 이렇게 한줄로 보고 싶었다.

그럴땐 FOR XML PATH 을 이용하면 된다.  

 

그런데 1학년 앞에 , 도 없애고 싶다. 이럴때 STUFF함수를 사용하면 된다. 

STUFF사용 방법은 아래와 같다. start 부터 크기까지 지정한 치환문자로 바꿔준다. 

STUFF('[문자열]','[시작위치]','[크기]','[치환문자]')

 

'MSSQL' 카테고리의 다른 글

db링크 확인 하는 법  (0) 2020.03.27
bulk insert  (0) 2020.03.26
STRING ORDER BY 가 안될때  (2) 2020.03.20
[MS SQL] 재귀쿼리 트리구조 쿼리 WITH CTE  (0) 2020.02.04
숫자+문자를 포함한 데이터 order by 가 안되는 경우  (0) 2020.02.04

익명 내부 클래스(anonymous inner class)는 이름을 갖지 않는 클래스다. 클래스 선언과 오브젝트 생성이 결합된 형태로 만들어 지며, 상속할 클래스나 구현할 인터페이스를 생성자 대신 사용해서 다음과 같은 형태로 만들어 사용한다. 클래스를 재사용할 필요가 없고, 구현한 인터페이스 타입으로만 사용할 경우에 유용하다.

  • new 인터페이스이름( ){ 클래스 본문 }

구체적인 예를 들어보자.

class DeleteAllStatement implements StatementStrategy{
       PreparedStatement makePreparedStatement(Connection c) throws SQLException{
           return c.prepareStatement("delete from users");
       }
}

StatementStrategy strategy = new TestStatementStategyDeleteAllStatement ();

strategy .makePreparedStatement(c)


위 같이 interface를 구현한 클래스를 하나 만들고  new로 인스턴스를 만들어 함수를 호출 하도록 하지만 이부분을 생략하고 아래 처럼 익명내부 클래스로 바로 사용할수도 있다. 그럼 interface를 구현한 클래스를 매번 만들 수고를 들수있다.

 

 

'JAVA' 카테고리의 다른 글

가변인자  (0) 2020.01.04

테스트는 스프링을 학습하는데 가장 효과적인 방법이다.

실제 프로젝트를 하다보면 테스트가 얼마나 중요한지 느끼게 된다. 실제 개발자들 중 테스트를 거치지 않고 서버에 소스를 commit하는 경우는 없을 것이다. 스프링에서는 개발자들이 쉽게 사용할수 있도록 테스트 기능을 제공해준다. 

지금부터, 스프링의 강력한 기능중에 하나인 test에 대해서 공부해 보자. 

테스트는 가능하면 가장 작은 단위로 쪼개어 수행해야 한다. 이렇게 작은 단위의 코드에 대해 테스트를 수행 하는 것을 단위 테스트(UNIT TEST) 라고 한다.   여기서 단위의 의미는 코딩할때  각 수행 logic별로 method를 나누어 구현 하는데, 이때, 이 method정도의 크기를 말하는 것이라 이해했다. 

자바에서는 JUnit이라는 자바 테스팅 프레임워크를 제공한다. 자바로 단위테스트를 만들때 유용하게 쓸수있다. 

JUnit 테스트는 아래의 7단계로 간략화 할수 있다.  


  1. 테스트 클래스에서 @Test가 붙은 public이고 void형이며 파라미터가 없는 테스트 메소드를 모두 찾는다.
  2. 테스트 클래스의 오브젝트를 하나 만든다.
  3. @Before가 붙은 메소드가 있으면 실행한다.
  4. @Test가 붙은 메소드를 하나 호출하고 테스트 결과를 저장해둔다. 
  5. @After가 붙은 메소드가 있으면 실행한다. 
  6. 나머지 테스트 메소드에 대해 2-5번을 반복한다. 
  7. 모든 테스트의 결과를 종합해서 돌려준다. 

여기서 한가지 주의할점은 @Test가 붙은 메소드를 실행할때 마다 매번 새로운 오브젝트를 만든다는 것이다. 

즉, 하나의 테스트 클래스안에 @Test가 붙은 메소드가 2개 라면 2개의 오브젝트가 만들어진다는 것이다.  이로써, 각 테스트가 서로 영향을 주지않고 독립적으로 실행됨을 보장 받을수 있다. 

지금부터 JUnit사용법을 배워보자. 

JUnit 프레임 워크에서 동작 하기 위해서는 아래 두조건을 꼭 지켜야 한다.  

  •    테스트 하고자 하는 Method에 @Test 라는 Annotation을 붙여줄것
  •    public이며 void형으로 선언할것.

아래 예제를 보자.  addAndGet메소드를 테스트 하기로 했다면 해당 메소드위에 @Test Annotaion을 붙이고 

해당 메소드를 public void형으로 선언 해둬야 한다. JUnit은 public메소드만을 테스트 메소드로 허용한다. 

@Test 
public void addAndGet() throws SQLException {
ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml");
UserDao dao = context.getBean("userDao", UserDao.class);

User user = new User();
user.setId("gyumee");
user.setName("박성철");
user.setPassword("springno1");

dao.add(user);

User user2 = dao.get(user.getId());

assertThat(user2.getName(), is(user.getName()));
assertThat(user2.getPassword(), is(user.getPassword()));
}

테스트시 유용하게 사용할 수 있는 JUnit  Static method 가 있다. 

 >> assertThat :  JUnit에서 제공하는 if 문장의 기능을 하는 함수로 첫 파라미터 값을  두번째 파라미터의 조건과 일치하면 넘어가고, 다르면 테스트가 실패하도록 만들어준다. 

    assertThat(user2.getName(), is(user.getName()));  

  -> user2.getName()와 user.getName()일치하는지 체크

  -> is()는 matcher의 일종으로  equals()로 비교해주는 기능을 가짐  

자.. 그럼 테스트를 위한 Application Context관리는 어떻게 해줘야 할까?

테스트 서버와 실제 사용서버가 다르듯이 테스트 Application Context를 따로 만들어 주는 것이 좋다. 

그리고 매번 @Test가 붙은 Method을 실행할때 마다 객체를 다시 만들기 때문에 ApplicationContext를 만드는 코드를 

아래 코드와 같이 테스트 메소드 안에 직접 명시하는 것은 좋지 않다. 

@Test 
public void andAndGet() throws SQLException {

  ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml");
  UserDao dao = context.getBean("userDao", UserDao.class);

  dao.deleteAll();
  assertThat(dao.getCount(), is(0));

  User user = new User();
  user.setId("gyumee");
  user.setName("박성철");
  user.setPassword("springno1");

  dao.add(user);
  assertThat(dao.getCount(), is(1));

  User user2 = dao.get(user.getId());

  assertThat(user2.getName(), is(user.getName()));
  assertThat(user2.getPassword(), is(user.getPassword()));
}

이런경우, 아래 소스에서 처럼 @Autowired Annotation 을 써주면 된다.  @Autowired Annotation가 붙은 인스턴스 변수가 있으면 테스트 컨텍스트 프레임워크는 변수 타입과 일치하는 컨텍스 내의 빈을 찾아준다. 그리고 스프링 어플리케이션은 초기화 할때 자기 자신도 빈으로 등록해 둔다. 따라서, 해당 테스트 클래스 실행시에 스프링 어플리케이션은 @Autowired가 붙은 context에 해당 객체를 찾아서 던져주게 된다. 즉,  ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml"); 와 같은 효과를 가질수 있다. 

@RunWith(SpringJUnit4ClassRunner.class)  // 스프링의 테스트 컨텍스트 프레임워크의 JUnit확장 기능 지정 
@ContextConfiguration(locations="/applicationContextTest.xml") // 테스트 컨텍스트가 자동으로 만들어줄 어플리
public class UserDaoTest {                                                            케이션 컨텍스트의 위치 지정 
  @Autowired 
   private ApplicationContext context; 
  UserDao dao; 
  User user1,user2,user3; 

  @Before 
  public void setUp() { 
  dao=this.context.getBean("userDao",UserDao.class); 
  user1 = new User("gyumee", "박성철", "springno1"); 
  user2 = new User("leegw700", "이길원", "springno2"); 
  user3 = new User("bumjin", "박범진", "springno3"); 
  ..................

  ..................
}

그리고  여기서 주의 할 점은  테스트 클래스 상단에 아래 두 Annotation을 지정해 줘야 한다. 


      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(locations="/applicationContextTest.xml")


@ RunWith은 JUnit의 프레임워크의 테스트 실행방법을 확장할 때 사용하는 Annotaion이다. SpringJUnit4ClassRunner.class라는 JUnit의 확장 클래스를 지정해 주면 JUnit이 테스트를 진행하는 중에 테스트가 사용할 Application Context를 만들고 관리하는 작업을 진행해준다. 

@ContextConfiguration은 자동으로 만들어줄 Application Context의 설정파일 위치를 지정한다. 

2장 테스트는 여기서 마무리 하겠다. .......................

스프링을 시작 하기에 앞서 이클립스와 MSSQL을 설치 하도록 하자.

SQL은 자신이 편한쪽으로 선택하면 되겠다. 일단 , 나는 MS-SQL을 선택했다.

1. 아래 URL로 가서 MS SQL서버 개발자용으로 다운로드를 받아야 한다.

https://www.microsoft.com/ko-kr/sql-server/sql-server-downloads

 

SQL Server 다운로드 | Microsoft

지금 Microsoft SQL Server를 다운로드하세요. 각 데이터와 워크로드에 가장 적합한 SQL Server 체험판 또는 버전, 도구, 커넥터를 선택할 수 있습니다.

www.microsoft.com

2. 다운로드 받아 설치를 시작해보자.  설치 유형 선택(기본)을 선택 하면 된다.

 

3.  설치를 누른다.

 

4.  설치 완료된 인스턴스 이름와 폴더를 확인한다.

 

5. 위 하단에 SSMS(SQL Server Management Studio)를 설치를 눌러 SSMS를 설치 하도록 하자 

6. 설치하면 아래와 같이 SQL Server Management Studio 18이 보인다. 클릭해서 실행 해보자.

 

7. 서버이름에는 local일 경우 . 만 입력후 연결을 누르면 된다.

 

 

8. 서버 오른쪽 마우스 클릭후 속성을 선택한다. 서버인증및 로그인 감사를 보안요구 사항에 맞게 수정한다.

이제 모든 설치가 완료 되었으니 새 데이터베이스를 만든후, 테이블 생성, 조회를 해보도록 하자

1. 새로운 데이터베이의 이름을 입력해보자.

2. 테이블을 만들어 보자.

3. 컬럼과 테이블이름을 등록해보자

4. 기본키 설정은 해당 컬럼선택후 오른쪽 마우스 클릭 -> 기본 키 설정을 선택하면 된다.

5. 이제 데이트를 입력 해 보도록 하자. ( 해당 데이터 베이스선택후 새 쿼리 선택)

 

6. 데이터를 INSERT후 해당 DB에 데이터가 들어가 있음을 확인 할수 있다.

이제 DB는 사용할 준비가 끝이났다.

이제 자바를 이용하여 SPRING을 공부하기 위하여 Eclipse를 설치 하도록 하자.

Eclipse설치 방법은 다음에 다시 이어서 쓰도록 하겠다.

'Spring' 카테고리의 다른 글

3장 템플릿 II- 템플릿/ 콜백패턴  (0) 2020.01.04
3장 템플릿I - 전략패턴  (0) 2020.01.04
2장 테스트  (0) 2019.12.28
시작하기전 준비사항들 II - MSSQL 설정  (0) 2019.12.28
토비의 스프링 3.1 공부시작  (0) 2019.12.28

Eclipse에 MSSQL설정 하는 방법을 정리하도록 하겠다.

1. JDBC download - 아래 사이트에서 다운로드 받자

https://docs.microsoft.com/ko-kr/sql/connect/jdbc/download-microsoft-jdbc-driver-for-sql-server?view=sql-server-2017

다음 사이트로 부터 JDBC를 다운받을 수 있습니다.

2. 자신의 자바버전에 맞춰 다운로드 받는다.

3. 한국어로 선택후 다운로드

4.  zip파일로 선택

5. 다운로드 후 압축을 푼다. mssql-jdbc-7.4.1.jre12.jar파일을 아래 디렉토리로 파일을 옮겨 준후,

이클립스에서 configure build path를 잡아준다.

6. SQL Server 구성 관리자를 실행한다.

7.  TCP/IP 사용으로 변경한다.

8.  TCP/IP클릭후, IP 주소 탭에 IPALL에 TCP 포트를 1433으로 설정한다.

9. 해당 서버 선택후 오른쪽 마우스 클릭-> 서버 재시작 선택

 

10. SQL Server Management Studio실행

 

11.  보안 -> 로그인 오른쪽 마우스 클릭 새로그인 클릭

12. 로그인할 이름 입력후, SQL Server인증선택후 암호 입력 

주의!!! -> 하단에 기본 데이터 베이스를 master선택

13. 서버역할 선택후 모두 체크 - 주의!!

14. 해당 서버(SQL Server 14.0.1000.169-kimak) 우 클릭 속성 선택후 보안에서

 서버인증: SQL Server및 Windows인증 모드 선택

 로그인 감사 : 실패한 로그인만

체크

15. 해당 서버 다시 재시작한다.( 서버 재시작 방법은 9번 참조)

16. SQL Server Management Studio에 등록한 이름으로 로그인해보자

 로컬이므로 서버이름에는 . 만 입력하면 된다.

17. 이제 자바에서 로컬에 설치한 MSSQL을 연결해보자.

Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");

// 1433(->SQL server구성관리자에서 TCP/IP설정한 PortNumber)

//databaseName=SQL Server Management Studio에서 만든 데이터베이스 이름

String url="jdbc:sqlserver://localhost:1433;databaseName=SPRING_DB;";

// kimak, 12345는 위에 설정한 SQL서버 로그인 이름와 비번입력
Connection c = DriverManager.getConnection(url,"kimak","12345");

if(c != null ) {
System.out.println("DB Connect Success");
}else {
System.out.println("DB Connect Faile");
}

c.close();

'Spring' 카테고리의 다른 글

3장 템플릿 II- 템플릿/ 콜백패턴  (0) 2020.01.04
3장 템플릿I - 전략패턴  (0) 2020.01.04
2장 테스트  (0) 2019.12.28
1장 시작하기전에 준비사항들1-MS SQL설치  (0) 2019.12.28
토비의 스프링 3.1 공부시작  (0) 2019.12.28

토비의 스프링 3.1
일주일에 한 Chapter씩 토비의 스프링을 공부하기로 했다. 자바 프로젝트를 진행하면서 Spring을 써 오긴 했지만 , 언제나 겉만 핥는 느낌 이였던 터라, 지금이라도 조금더 깊이 있게 스프링에 대해 공부해 보기로 했다. 스프링에 대해 자세히 공부 하다 보면 분명 개발시에도 도움이 많이 되리라 생각한다.
요즘은 스프링의 세부적인 설정을 자동으로 해주는 스프링 부트를 많이 쓴다고 하니, 스프링 공부 후에 스프링 부트도 정리해 볼 생각이다.
여기에 올리는 글 들은 지극히 개인적인 공부 정리 공간이므로 반말로 글을 정리하더라도 오해하지 마시길, 그리고 혹여 틀린 정보가 있다면 댓글로 알려주시면 바로 수정 하도록 하겠다.

+ Recent posts