'DATABASE' 태그의 글 목록 :: 잡다한 프로그래밍
반응형

1. 문법의 차이

#1) #을 이용한 경우

<select id="select" resultType="String" parameterType="Map">
    SELECT name FROM user WHERE id = #{id}
</select>

다음과 같은 SELECT문을 작성하였을경우 아래와 같이 ?에 파라미터가 바인딩 되어 수행된다 이렇게 파싱된 쿼리문은 재활용(캐싱)되므로 효율적이다.

SELECT name FROM user WHERE id = ?

 또한 변수에 작은 따옴표(')가 붙어 쿼리가 수행되므로 '#{id}'라고 쿼리문을 작성할 필요가 없다. 대신 다음과 같이 사용할 수 없다. 아래와 같이 사용할 경우 user_'tableName'이 되어버리므로 에러가 발생한다.

<select id="select" resultType="String" parameterType="Map">
    SELECT name FROM user_#{tableName} WHERE id = #{id}
</select>

 

#2) $를 이용한 경우

반면 $를 이용하게 되면 파라미터값이 바뀔 때마다 새로운 쿼리문의 파싱을 진행해야해서 성능상 단점이 존재한다.

또한 쿼리문에 #{}과 다르게 작은 따옴표(')가 붙지 않아서 테이블 이름이나 컬럼이름을 동적으로 결정할때 사용할 수 있다.

<select id="select" resultType="String" parameterType="Map">
    SELECT name FROM user_${tableName} WHERE id = #{id}
</select>

2. SQL Injection 차이

보안적으로 #과 $에는 차이가 존재한다. #은 $보다 보안에 안전하다 다음과 같은 예시를 보자

<select id="select" parameterType="Map" resultType="...">
    SELECT * FROM user WHERE id = '${id}' AND password = '${password}'
</select>

만약 이때 사용자가 id 값에 root' --를 입력했다고 가정하면 다음과 같은 결과를 초래한다.

SELECT * FROM user WHERE id = 'root' -- 'AND password = ''

사용자는 비밀번호를 입력하지 않았지만 뒷부분이 주석처리되어 로그인에 성공하게되어버린다 따라서 $는 #보다 SQL Injection에 취약하다

반응형
반응형

1. 사전 준비

- pom.xml 수정

다음과 같은 내용을 pom.xml에 추가합니다 1. mybatis (버전은 스프링 버전에 맞게 선택 가능) 2. mybatis-spring

3.dbcp2, 4. mysql-connector 5. spring-jdbc

		<!-- MySQL -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.5.3</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>2.0.3</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-dbcp2</artifactId>
			<version>2.7.0</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.47</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>

 

- jdbc.properties생성

WEB-INF에 properties폴더 생성 > 다음과 같은 jdbc.properties 파일 생성

jdbc.username = user_id
jdbc.password = password
jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://URL/DB_NAME?serverTimezone=Asia/Seoul&useSSL=false

 

- mysql 연동

다음과 같이 root-context.xml에 추가한다 

	<!-- MySQL dataSource -->
	<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>
    
	<!-- jdbc.properties를 찾게 해주는 placeholder -->    
 	<context:property-placeholder location="/WEB-INF/properties/jdbc.properties" />

2. mybatis 연동 및 사용

- TestModel 생성

DB로부터 받아온 데이터를 담을 Model 클래스를 생성한다

@Getter
@Setter
public class Test_Model {

	private String date;

	private int count;

}

 

- mybatis-config.xml 생성

main/resources에 다음과 같은 mybatis-config.xml을 생성한다. 등록된 모델을 test라는 별칭으로 사용할 수 있다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration 
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<typeAliases>
		<typeAlias type="test.main.model.Test_Model" alias="test" />
	</typeAliases>

</configuration>

 

- rmcMapper.xml 생성

main/resource에 mappers라는 패키지를 만들고 패키지 내에 다음과 같은 testMapper.xml을 생성한다.

resultType를 config.xml에 지정한 test타입으로 반환하고 사용할 쿼리의 id를 getData로 지정한다.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="test.main.mapper.testMapper">
	<select id="getData" resultType="test">
		select * FROM test_db
	</select>
</mapper>

 

- root-config.xml 수정

다음과 같이 root-config.xml에 mybatis를 설정하기 위한 위한 코드를 추가한다. mybatis-config.xml과 Mapper.xml을 bean으로 등록하고 sqlsession을 bean으로 등록한다.

<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:mappers/**/*Mapper.xml"></property>
	</bean>
	
	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate" destroy-method="clearCache">
		<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
	</bean>
	

3. Controller, Service, DAO 만들기

- Controller 생성

다음과 같은 Controller를 작성한다. 간단하게 getData를 해오는 코드이다.

@Controller
@RequestMapping(value = "/brokenSVC")
public class testController {
	@Autowired
	private BrokenService testService;
	
	@GetMapping(value = "test")
	public String home(Model model) {
		System.out.println(testService.getdata().get(0).getDate());
		return "testpage";
	}
}

 

- Service 생성

다음과 같은 Service를 작성한다.

@Service
public class BrokenService {

	@Autowired
	private testDAO testdao;

	public List<Test_Model> getData() {
		return testdao.getData();
	}
}

 

- DAO 생성

다음과 같은 DAO를 작성한다.

@Repository
public class BrokenDAO {
	
	@Autowired private SqlSession sqlSession;
	private static final String Namespace = "test.main.mapper.rmcMapper"; //rmcMapper가 있는 위치
	
	public List<Test_Model> getData() {
		return sqlSession.selectList(Namespace+".getData");
	}
}

4. 결론

mybatis를 사용할 경우 기존 방법은 DAO에 쿼리문이 섞여있다는 단점이 있었는데 쿼리를 완벽하게 분리하여 사용할 수 있다는 장점이 있다.

반응형
반응형

지난 #8 강의에 이어 MYSQL과 연동하여 Update, delete, insert 하는 방법을 설명하도록 한다.

 

1. INSERT

먼저 지난번 query와 달리 update메소드를 사용하며 다음과 같이 사용한다 update메서드 내부에는 insert sql문, new Object로 name, email, text를? 에 넣어주는 방식으로 사용하며 이때 반환하는 값이 1이면 true를 리턴한다.

	public boolean insert(Offer offer) {
		String sqlStatement = "insert into offers (name, email, text) values (?,?,?)";
		String name = offer.getName();
		String email = offer.getEmail();
		String text = offer.getText();
		
		return (jdbcTemplateObject.update(sqlStatement, new Object[]{name, email, text}) == 1);
	}

2. UPDATE

insert와 같이 update메소드를 사용하며 사용방법은 다음과 같다.

	public boolean update(Offer offer) {
		String sqlStatement = "update offers set name=?, email=?, text=? where id=?";
		String name = offer.getName();
		String email = offer.getEmail();
		String text = offer.getText();
		int id = offer.getId();
		
		return (jdbcTemplateObject.update(sqlStatement, new Object[]{name, email, text, id}) == 1);
	}

3. DELETE

마찬가지로 update 메소드를 사용하며 사용방법은 다음과 같다.

	public boolean delete(int id) {
		String sqlStatement = "delete from offers where id = ?";
		
		return (jdbcTemplateObject.update(sqlStatement, new Object[]{id}) == 1);
	}
반응형

+ Recent posts