스프링프레임워크 & 마이바티스
(Spring Framework, MyBatis)
4-3-1-6. jdbcTemplate의 update 메소드
 execute에 비해 NULL을 setting할때 이점이 있다.(TYPE을 읶자로 받아들임)
 주로 DML 처리용(insert, update, delete)으로 파라미터는 가변읶자나 객체배열 형태로 제공하
면 된다.
 실행시 백그라운드에서 JdbcTemplate이 PreparedStatement와 PreparedStatementSetter를 생
성 시킨다.
public int insertPerson(Person person) {
String sql = “insert into person (id, firstname, lastname) values (?,?,?)”;
Object[] params = new Object[] {
person.getId(),
person.getFirstName(),
person.getLastName()
};
int[] types = new int[] { TYPES.INTEGER, TYPES.VARCHAR, TYPES.VARCHAR };
return jdbcTemplate.update(sql, params, types);
}
4-3-1-7. jdbcTemplate의 batchUpdate 메소드
 갱신하고자 하는 레코드가 2건 이상읶 경우에 사용하며, BatchPreparedStatementSetter를 만
들어 읶자로 넣어준다.
setValues(PreparedStatemet ps, int i) throws SQLException; //파라미터 바인딩
int getBatchSize(); //실행시킬 SQL문의 수를 알려준다. setValues의 호출 수 지정.
public int[] updatePersons(final List persons) {
String sql = “insert into person (id, firstname, lastname) values (?,?,?)”;
BatchPreparedStatementSetter setter = null;
setter = new BatchPreparedStatementSetter() { //Anonymous Class(익명클래스)
public int getBatchSize() {
return persons.size();
}
public void setValues(PreparedStatement ps, int index)
throws SQLException {
Person person = (Person)persons.get(index);
int parameterIndex = 1;
ps.setString(parameterIndex++, person.getId());
ps.setString(parameterIndex++, person.getFirstName());
ps.setString(parameterIndex, person.getLastName());
}
};
return this.jdbcTemplate.batchUpdate(sql, setter); //질의문 실행
}//:
4-3-1-8. jdbcTemplate의 query 메소드와 RowMapper 인터페이스
 RowMapper 읶터페이스
여러 건의 레코드(여러 person 객체)를 얻을 수 있는 메소드가 필요하다면 RowMapper를 구현
해서 데이터를 추출할 수 있는데 RowMapper는 ResultSet의 SELECT된 레코드와 객체를 매핑 시
키는 역할을 한다.
//레코드(행, 로우)를 매핑할 PersonRowMapper를 RowMapper인터페이스를 구현해서 만든다.
public class PersonRowMapper implements RowMapper {
public Object mapRow(ResultSet rs, int index) throws SQLException {
Person person = new Person();
person.setId(new Integer(rs.getInt("id")));
person.setFirstName(rs.getString(“firstname"));
person.setLastName(rs.getString(“lastname"));
return person;
}
}
…………
public List getAllPersons() {
String sql = “select id, firstname, lastname from person”;
return jdbcTemplate.query( sql, new PersonRowMapper()); //queryForList
}
}
//아이디를 통해 person 객체를 얻어오는 메소드
public Person getPerson(Integer id) {
String sql = “select id, firstname, lastname from person where id =? “;
Person person = (Person)jdbcTemplate.query(sql, id, new PersonRowMapper());
return person;
}//:
4-3-1-9. jdbcTemplate의 queryForObject, queryForList, 기타 query
메소드
 queryForObject : 한 개의 레코드 처리용, 객체타입으로 결과를 리턴해 준다.
public Person getLastNameById(Integer id) {
String sql = "SELECT lastname FROM person WHERE id = ? ";
Object[] args = new Object[] { id }; //?에 대입되는 매개변수
String lastname=(String)this.jdbcTemplate.queryForObject(sql, args, String.class);
return lastname;
}
 queryForList : 한 개 이상의 레코드 처리용, 여러건의 레코드를 List 객체로 리턴해 준다.
public List<Person> getAllPerson() {
String sql = "" + "SELECT * FROM person ";
List<Person> persons = this.jdbcTemplate.queryForList(sql, new PersonMapper());
return persons;
}
 기타 query 메소드
//queryForInt, queryForLong은 더 이상 사용되지 않는다.
String sql = "SELECT count(*) FROM person WHERE id = ?";
int count = jdbcTemplate.queryForObject(sql, new Object[] { id }, Integer.class);
String sql = "SELECT longCol FROM person WHERE id = ?";
long col = jdbcTemplate.queryForObject(sql, new Object[] { id }, Long.class);}
// 아래 double형이나 date형은 queryForObject를 적절히 사용하면 된다.
String sql = " SELECT doubleCol FROM Table ";
Double d = (Double)this.jdbcTemplate.queryForObject(sql, Double.class);
String sql = " SELECT dateCol FROM Table ";
Date d = (Date)this.jdbcTemplate.queryForObject(sql, Date.class);
4-3-1-10. jdbcTemplate을 이용한 CRUD 예제
 Spring Boot, MariaDB를 이용해서 EMP 테이블을 만들고 JdbcTemplate을 이용하여 CRUD 기
능을 구현해 보자.
STS에서
File -> New -> Project -> Spring Starter Project
Name : jdbc2
Package : jdbc
다음화면에서 SQL : JDBC, MySQL 선택
MariaDB에서 직접 SQL을 작성하여 테이블 및 데이터를 생성할 수 있지만 스프링 부트
에서는 클래스패스 경로에 schema.sql, data.sql이 존재하면 자동실행 하므로 스키마 생성
부분과 데이터 생성부분을 파읷로 만들어두면 된다.
[src/main/resources/schema.sql]
drop database if exists jdbc2;
create database jdbc2;
use jdbc2;
create table emp
(
empno int(4) not null auto_increment,
ename varchar(50),
primary key (empno)
) ENGINE=InnoDB;
[src/main/resources/data.sql(파일 속성에서 text encoding을 UTF-8로)]
insert into emp(ename) values ('1길동');
insert into emp(ename) values ('2길동');
insert into emp(ename) values ('3길동');
[src/main/resources/application.properties]
spring.datasource.platform=mysql
spring.datasource.url=jdbc:mysql://localhost/jdbc2?createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=1111
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.sql-script-encoding=UTF-8
#커넥션풀에서 커넥션을 가져올 경우 커넥션이 유효한지 검사
도메인 클래스(Emp.java) – 테이블구조와 동일하다.
package jdbc.domain;
public class Emp {
private Long empno;
private String ename;
public Emp() { }
public Emp(String ename) { this.ename = ename; }
public Emp(Long empno, String ename) {
this.empno = empno;
this.ename = ename;
}
public Long getEmpno() { return empno; }
public void setEmpno(Long empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String toString() { return "[empno=" + empno +",ename=" + ename +
"]"; }
}
RowMapper 구현체(EmpRowMapper.java)
package jdbc.repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import jdbc.domain.Emp;
@Repository
public class EmpRowMapper implements RowMapper {
@Override
public Emp mapRow(ResultSet rs, int rowNum) throws SQLException {
Long empno = rs.getLong("empno");
String ename = rs.getString("ename");
return new Emp(empno, ename);
}
}
Repository 인터페이스(EmpRepository.java) – 영속성 서비스용 인터페이스
package jdbc.repository;
import java.util.List;
import jdbc.domain.Emp;
public interface EmpRepository {
List<Emp> findAll();
Emp findOne(Long empnno);
Emp save(Emp emp);
void delete(Long empno);
}
Repository 구현체(EmpRepositoryImpl.java) – 영속성 서비스용 구상클래스
package jdbc.repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import jdbc.domain.Emp;
@Repository
@Transactional(readOnly=true)
public class EmpRepositoryImpl implements EmpRepository {
private SimpleJdbcInsert jdbcInsert;
private JdbcTemplate jdbcTemplate;
@Autowired
RowMapper<Emp> empRowMapper;
@Autowired //스프링부트에서 DataSource를 자동 주입해 준다.
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public List<Emp> findAll() {
List<Emp> emps = jdbcTemplate.query("select empno, ename from
emp",empRowMapper);
return emps;
}
@Override
public Emp findOne(Long empno) {
return (Emp)jdbcTemplate.queryForObject("select empno, ename from
emp where empno = ?", empRowMapper, empno);
}
@Override
@Transactional(readOnly=false)
public Emp save(Emp emp) {
SqlParameterSource param = new
BeanPropertySqlParameterSource(emp);
if (emp.getEmpno() == null) {
Number key = jdbcInsert.executeAndReturnKey(param);
emp.setEmpno(key.longValue());
}
else {
this.jdbcTemplate.update(
"insert into emp (empno, ename) values (?, ?)",
emp.getEmpno(), emp.getEname()
);
}
return emp;
}
@Override
@Transactional(readOnly=false)
public void delete(Long empno) {
this.jdbcTemplate.update(
"delete from emp where empno = ?",
empno
);
}
//생성자가 실행된 후에 실행된다.
@PostConstruct
public void init() {
//INSERT SQL Auto Create
jdbcInsert = new
SimpleJdbcInsert(jdbcTemplate).withTableName("emp").usingGeneratedKeyColumns("emp
no");
}
}
스프링 부트 메인(Jdbc2Application.java)
package jdbc;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import jdbc.domain.Emp;
import jdbc.repository.EmpRepository;
@SpringBootApplication
public class Jdbc2Application implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(Jdbc2Application.class, args);
}
@Autowired
EmpRepository empRepository;
public void run(String...args) {
//전체 사원 SELECT
List<Emp> emps = empRepository.findAll();
for(Emp e : emps) { System.out.println(e); }
System.out.println("---------------------");
//2번 사원 SELECT
Emp e = empRepository.findOne(2L);
System.out.println(e);
System.out.println("---------------------");
//3번 사원 DELETE
empRepository.delete(3L);
emps = empRepository.findAll();
for(Emp e1 : emps) { System.out.println(e1); }
System.out.println("---------------------");
//4번 사원 INSERT
e = empRepository.save(new Emp(4L, "4길동"));
emps = empRepository.findAll();
for(Emp e1 : emps) { System.out.println(e1); }
System.out.println("---------------------");
//'5길동' 사원 INSERT
Emp e5 = new Emp(“5길동”);
e = empRepository.save(e5);
emps = empRepository.findAll();
for(Emp e1 : emps) { System.out.println(e1); }
}
}
[결과]
4-3-1-10. Spring Data JPA를 이용한 CRUD 예제
 이전의 예제를 Spring Data JPA를 이용한 형태로 변형하여 작성해 보자.
 간단히 Spring Data JPA 구조, 기본적읶 CRUD읶 경우 쿼리를 직접 만들지 않아도 된다는 것
만 확읶하자.
마리아DB는 아래 URL을 참조하여 설치하자.
http://ojc.asia/bbs/board.php?bo_table=LecSpring&wr_id=524
STS에서 File -> New -> Project -> Spring Starter Project
Name : springjpa, Package name : jpa
다음화면에서 SQL-> JPA, MySQL 선택
src/main/resources/data.sql(파일 속성에서 text encoding을 UTF-8로)
insert into emp(ename) values ('1길동');
insert into emp(ename) values ('2길동');
insert into emp(ename) values ('3길동');
Spring Data JPA는 테이블을 자동으로 생성하므로 이전 예제에서 작성한 schema.sql은 필요 없다.
src/main/resources/application.properties(파일 속성에서 text encoding을 UTF-8로)
spring.datasource.platform=mysql
spring.datasource.url=jdbc:mysql://localhost/emp2?createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=1111
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.sql-script-encoding=UTF-8
# 자동으로 DDL을 만들어 테이블 생성
spring.jpa.hibernate.ddl-auto=create
# 실행되는 SQL문을 로그에서 보이도록
spring.jpa.show-sql=true
도메인 클래스(Emp.java) – 테이블구조와 동일하다.
package jpa.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Emp {
@Id //PK임을 지정
@GeneratedValue //자동증분 칼럼
private Long empno;
//@Column 어노테이션이없더라도 테이블 칼럼명과 자동 매핑
private String ename;
public Emp() { }
public Emp(String ename) { this.ename = ename; }
public Emp(Long empno, String ename) { this.empno = empno; this.ename = ename; }
public Long getEmpno() { return empno; }
public void setEmpno(Long empno) { this.empno = empno; }
public String getEname() { return ename; }
public void setEname(String ename) { this.ename = ename; }
public String toString() { return "[empno=" + empno +",ename=" + ename + "]";}
}
Repository 인터페이스(EmpRepository.java) – 영속성 서비스용 인터페이스
package jpa.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import jpa.domain.Emp;
/*
* JpaRepository에는 기본적인 CRUD(findAll, findOne, save, delete, deleteAll) 메소드가
* 정의되어 있으며 이를 상속한 인터페이스를 만듦으로써 구현클래스 없이 레포지터리 구성이
가능하다. 제너릭으로 도메인 클래스와 키칼럼(ID칼럼)의 타입을 기술하면 된다.
*/
public interface EmpRepository extends JpaRepository<Emp, Long> { }
스프링 부트 메인(SpringjpaApplication.java)
package jpa;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import jpa.domain.Emp;
import jpa.repository.EmpRepository;
@SpringBootApplication
public class SpringjpaApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(SpringjpaApplication.class, args); }
@Autowired
EmpRepository empRepository;
public void run(String...args) {
//전체 사원 SELECT
List<Emp> emps = empRepository.findAll();
for(Emp e : emps) { System.out.println(e); }
System.out.println("---------------------");
//2번 사원 SELECT
Emp e = empRepository.findOne(2L);
System.out.println(e);
System.out.println("---------------------2번사원 SELECT");
//3번 사원 DELETE
empRepository.delete(3L);
emps = empRepository.findAll();
for(Emp e1 : emps) { System.out.println(e1); }
System.out.println("---------------------3번 DELETE후");
//4번 사원 INSERT
e = empRepository.save(new Emp(4L, "4길동"));
emps = empRepository.findAll();
for(Emp e1 : emps) { System.out.println(e1); }
System.out.println("---------------------4번 INSERT후");
//'5길동' 사원 INSERT
Emp e5 = new Emp(“5길동”);
e = empRepository.save(e5);
emps = empRepository.findAll();
for(Emp e1 : emps) {
System.out.println(e1);
}
System.out.println("---------------------5번 INSERT후");
//'5길동' 사원 이름 수정
e = empRepository.findOne(5L);
e.setEname("수정된5길동");
empRepository.save(e);
emps = empRepository.findAll();
for(Emp e1 : emps) {
System.out.println(e1);
}
System.out.println("---------------------5번 수정후");
}
}

#16.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/마이바티스학원추천

  • 1.
    스프링프레임워크 & 마이바티스 (SpringFramework, MyBatis) 4-3-1-6. jdbcTemplate의 update 메소드  execute에 비해 NULL을 setting할때 이점이 있다.(TYPE을 읶자로 받아들임)  주로 DML 처리용(insert, update, delete)으로 파라미터는 가변읶자나 객체배열 형태로 제공하 면 된다.  실행시 백그라운드에서 JdbcTemplate이 PreparedStatement와 PreparedStatementSetter를 생 성 시킨다. public int insertPerson(Person person) { String sql = “insert into person (id, firstname, lastname) values (?,?,?)”; Object[] params = new Object[] { person.getId(), person.getFirstName(), person.getLastName() }; int[] types = new int[] { TYPES.INTEGER, TYPES.VARCHAR, TYPES.VARCHAR }; return jdbcTemplate.update(sql, params, types); } 4-3-1-7. jdbcTemplate의 batchUpdate 메소드  갱신하고자 하는 레코드가 2건 이상읶 경우에 사용하며, BatchPreparedStatementSetter를 만 들어 읶자로 넣어준다. setValues(PreparedStatemet ps, int i) throws SQLException; //파라미터 바인딩 int getBatchSize(); //실행시킬 SQL문의 수를 알려준다. setValues의 호출 수 지정.
  • 2.
    public int[] updatePersons(finalList persons) { String sql = “insert into person (id, firstname, lastname) values (?,?,?)”; BatchPreparedStatementSetter setter = null; setter = new BatchPreparedStatementSetter() { //Anonymous Class(익명클래스) public int getBatchSize() { return persons.size(); } public void setValues(PreparedStatement ps, int index) throws SQLException { Person person = (Person)persons.get(index); int parameterIndex = 1; ps.setString(parameterIndex++, person.getId()); ps.setString(parameterIndex++, person.getFirstName()); ps.setString(parameterIndex, person.getLastName()); } }; return this.jdbcTemplate.batchUpdate(sql, setter); //질의문 실행 }//: 4-3-1-8. jdbcTemplate의 query 메소드와 RowMapper 인터페이스  RowMapper 읶터페이스 여러 건의 레코드(여러 person 객체)를 얻을 수 있는 메소드가 필요하다면 RowMapper를 구현 해서 데이터를 추출할 수 있는데 RowMapper는 ResultSet의 SELECT된 레코드와 객체를 매핑 시 키는 역할을 한다. //레코드(행, 로우)를 매핑할 PersonRowMapper를 RowMapper인터페이스를 구현해서 만든다. public class PersonRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int index) throws SQLException { Person person = new Person(); person.setId(new Integer(rs.getInt("id"))); person.setFirstName(rs.getString(“firstname")); person.setLastName(rs.getString(“lastname")); return person; } }
  • 3.
    ………… public List getAllPersons(){ String sql = “select id, firstname, lastname from person”; return jdbcTemplate.query( sql, new PersonRowMapper()); //queryForList } } //아이디를 통해 person 객체를 얻어오는 메소드 public Person getPerson(Integer id) { String sql = “select id, firstname, lastname from person where id =? “; Person person = (Person)jdbcTemplate.query(sql, id, new PersonRowMapper()); return person; }//: 4-3-1-9. jdbcTemplate의 queryForObject, queryForList, 기타 query 메소드  queryForObject : 한 개의 레코드 처리용, 객체타입으로 결과를 리턴해 준다. public Person getLastNameById(Integer id) { String sql = "SELECT lastname FROM person WHERE id = ? "; Object[] args = new Object[] { id }; //?에 대입되는 매개변수 String lastname=(String)this.jdbcTemplate.queryForObject(sql, args, String.class); return lastname; }  queryForList : 한 개 이상의 레코드 처리용, 여러건의 레코드를 List 객체로 리턴해 준다. public List<Person> getAllPerson() { String sql = "" + "SELECT * FROM person "; List<Person> persons = this.jdbcTemplate.queryForList(sql, new PersonMapper()); return persons; }  기타 query 메소드 //queryForInt, queryForLong은 더 이상 사용되지 않는다.
  • 4.
    String sql ="SELECT count(*) FROM person WHERE id = ?"; int count = jdbcTemplate.queryForObject(sql, new Object[] { id }, Integer.class); String sql = "SELECT longCol FROM person WHERE id = ?"; long col = jdbcTemplate.queryForObject(sql, new Object[] { id }, Long.class);} // 아래 double형이나 date형은 queryForObject를 적절히 사용하면 된다. String sql = " SELECT doubleCol FROM Table "; Double d = (Double)this.jdbcTemplate.queryForObject(sql, Double.class); String sql = " SELECT dateCol FROM Table "; Date d = (Date)this.jdbcTemplate.queryForObject(sql, Date.class); 4-3-1-10. jdbcTemplate을 이용한 CRUD 예제  Spring Boot, MariaDB를 이용해서 EMP 테이블을 만들고 JdbcTemplate을 이용하여 CRUD 기 능을 구현해 보자. STS에서 File -> New -> Project -> Spring Starter Project Name : jdbc2 Package : jdbc 다음화면에서 SQL : JDBC, MySQL 선택 MariaDB에서 직접 SQL을 작성하여 테이블 및 데이터를 생성할 수 있지만 스프링 부트 에서는 클래스패스 경로에 schema.sql, data.sql이 존재하면 자동실행 하므로 스키마 생성 부분과 데이터 생성부분을 파읷로 만들어두면 된다. [src/main/resources/schema.sql] drop database if exists jdbc2; create database jdbc2; use jdbc2; create table emp
  • 5.
    ( empno int(4) notnull auto_increment, ename varchar(50), primary key (empno) ) ENGINE=InnoDB; [src/main/resources/data.sql(파일 속성에서 text encoding을 UTF-8로)] insert into emp(ename) values ('1길동'); insert into emp(ename) values ('2길동'); insert into emp(ename) values ('3길동'); [src/main/resources/application.properties] spring.datasource.platform=mysql spring.datasource.url=jdbc:mysql://localhost/jdbc2?createDatabaseIfNotExist=true spring.datasource.username=root spring.datasource.password=1111 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.sql-script-encoding=UTF-8 #커넥션풀에서 커넥션을 가져올 경우 커넥션이 유효한지 검사 도메인 클래스(Emp.java) – 테이블구조와 동일하다. package jdbc.domain; public class Emp { private Long empno; private String ename; public Emp() { } public Emp(String ename) { this.ename = ename; } public Emp(Long empno, String ename) { this.empno = empno; this.ename = ename; } public Long getEmpno() { return empno; } public void setEmpno(Long empno) { this.empno = empno;
  • 6.
    } public String getEname(){ return ename; } public void setEname(String ename) { this.ename = ename; } public String toString() { return "[empno=" + empno +",ename=" + ename + "]"; } } RowMapper 구현체(EmpRowMapper.java) package jdbc.repository; import java.sql.ResultSet; import java.sql.SQLException; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; import jdbc.domain.Emp; @Repository public class EmpRowMapper implements RowMapper { @Override public Emp mapRow(ResultSet rs, int rowNum) throws SQLException { Long empno = rs.getLong("empno"); String ename = rs.getString("ename"); return new Emp(empno, ename); } } Repository 인터페이스(EmpRepository.java) – 영속성 서비스용 인터페이스 package jdbc.repository;
  • 7.
    import java.util.List; import jdbc.domain.Emp; publicinterface EmpRepository { List<Emp> findAll(); Emp findOne(Long empnno); Emp save(Emp emp); void delete(Long empno); } Repository 구현체(EmpRepositoryImpl.java) – 영속성 서비스용 구상클래스 package jdbc.repository; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import javax.annotation.PostConstruct; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.core.simple.SimpleJdbcInsert; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import jdbc.domain.Emp; @Repository @Transactional(readOnly=true) public class EmpRepositoryImpl implements EmpRepository { private SimpleJdbcInsert jdbcInsert; private JdbcTemplate jdbcTemplate;
  • 8.
    @Autowired RowMapper<Emp> empRowMapper; @Autowired //스프링부트에서DataSource를 자동 주입해 준다. public void setDataSource(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } @Override public List<Emp> findAll() { List<Emp> emps = jdbcTemplate.query("select empno, ename from emp",empRowMapper); return emps; } @Override public Emp findOne(Long empno) { return (Emp)jdbcTemplate.queryForObject("select empno, ename from emp where empno = ?", empRowMapper, empno); } @Override @Transactional(readOnly=false) public Emp save(Emp emp) { SqlParameterSource param = new BeanPropertySqlParameterSource(emp); if (emp.getEmpno() == null) { Number key = jdbcInsert.executeAndReturnKey(param); emp.setEmpno(key.longValue()); } else { this.jdbcTemplate.update(
  • 9.
    "insert into emp(empno, ename) values (?, ?)", emp.getEmpno(), emp.getEname() ); } return emp; } @Override @Transactional(readOnly=false) public void delete(Long empno) { this.jdbcTemplate.update( "delete from emp where empno = ?", empno ); } //생성자가 실행된 후에 실행된다. @PostConstruct public void init() { //INSERT SQL Auto Create jdbcInsert = new SimpleJdbcInsert(jdbcTemplate).withTableName("emp").usingGeneratedKeyColumns("emp no"); } } 스프링 부트 메인(Jdbc2Application.java) package jdbc; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
  • 10.
    import jdbc.domain.Emp; import jdbc.repository.EmpRepository; @SpringBootApplication publicclass Jdbc2Application implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(Jdbc2Application.class, args); } @Autowired EmpRepository empRepository; public void run(String...args) { //전체 사원 SELECT List<Emp> emps = empRepository.findAll(); for(Emp e : emps) { System.out.println(e); } System.out.println("---------------------"); //2번 사원 SELECT Emp e = empRepository.findOne(2L); System.out.println(e); System.out.println("---------------------"); //3번 사원 DELETE empRepository.delete(3L); emps = empRepository.findAll(); for(Emp e1 : emps) { System.out.println(e1); } System.out.println("---------------------"); //4번 사원 INSERT e = empRepository.save(new Emp(4L, "4길동")); emps = empRepository.findAll(); for(Emp e1 : emps) { System.out.println(e1); } System.out.println("---------------------"); //'5길동' 사원 INSERT Emp e5 = new Emp(“5길동”);
  • 11.
    e = empRepository.save(e5); emps= empRepository.findAll(); for(Emp e1 : emps) { System.out.println(e1); } } } [결과] 4-3-1-10. Spring Data JPA를 이용한 CRUD 예제  이전의 예제를 Spring Data JPA를 이용한 형태로 변형하여 작성해 보자.  간단히 Spring Data JPA 구조, 기본적읶 CRUD읶 경우 쿼리를 직접 만들지 않아도 된다는 것 만 확읶하자. 마리아DB는 아래 URL을 참조하여 설치하자. http://ojc.asia/bbs/board.php?bo_table=LecSpring&wr_id=524 STS에서 File -> New -> Project -> Spring Starter Project Name : springjpa, Package name : jpa 다음화면에서 SQL-> JPA, MySQL 선택 src/main/resources/data.sql(파일 속성에서 text encoding을 UTF-8로)
  • 12.
    insert into emp(ename)values ('1길동'); insert into emp(ename) values ('2길동'); insert into emp(ename) values ('3길동'); Spring Data JPA는 테이블을 자동으로 생성하므로 이전 예제에서 작성한 schema.sql은 필요 없다. src/main/resources/application.properties(파일 속성에서 text encoding을 UTF-8로) spring.datasource.platform=mysql spring.datasource.url=jdbc:mysql://localhost/emp2?createDatabaseIfNotExist=true spring.datasource.username=root spring.datasource.password=1111 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.sql-script-encoding=UTF-8 # 자동으로 DDL을 만들어 테이블 생성 spring.jpa.hibernate.ddl-auto=create # 실행되는 SQL문을 로그에서 보이도록 spring.jpa.show-sql=true 도메인 클래스(Emp.java) – 테이블구조와 동일하다. package jpa.domain; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Emp { @Id //PK임을 지정 @GeneratedValue //자동증분 칼럼 private Long empno; //@Column 어노테이션이없더라도 테이블 칼럼명과 자동 매핑 private String ename; public Emp() { } public Emp(String ename) { this.ename = ename; } public Emp(Long empno, String ename) { this.empno = empno; this.ename = ename; } public Long getEmpno() { return empno; } public void setEmpno(Long empno) { this.empno = empno; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public String toString() { return "[empno=" + empno +",ename=" + ename + "]";}
  • 13.
    } Repository 인터페이스(EmpRepository.java) –영속성 서비스용 인터페이스 package jpa.repository; import org.springframework.data.jpa.repository.JpaRepository; import jpa.domain.Emp; /* * JpaRepository에는 기본적인 CRUD(findAll, findOne, save, delete, deleteAll) 메소드가 * 정의되어 있으며 이를 상속한 인터페이스를 만듦으로써 구현클래스 없이 레포지터리 구성이 가능하다. 제너릭으로 도메인 클래스와 키칼럼(ID칼럼)의 타입을 기술하면 된다. */ public interface EmpRepository extends JpaRepository<Emp, Long> { } 스프링 부트 메인(SpringjpaApplication.java) package jpa; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import jpa.domain.Emp; import jpa.repository.EmpRepository; @SpringBootApplication public class SpringjpaApplication implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(SpringjpaApplication.class, args); } @Autowired EmpRepository empRepository; public void run(String...args) {
  • 14.
    //전체 사원 SELECT List<Emp>emps = empRepository.findAll(); for(Emp e : emps) { System.out.println(e); } System.out.println("---------------------"); //2번 사원 SELECT Emp e = empRepository.findOne(2L); System.out.println(e); System.out.println("---------------------2번사원 SELECT"); //3번 사원 DELETE empRepository.delete(3L); emps = empRepository.findAll(); for(Emp e1 : emps) { System.out.println(e1); } System.out.println("---------------------3번 DELETE후"); //4번 사원 INSERT e = empRepository.save(new Emp(4L, "4길동")); emps = empRepository.findAll(); for(Emp e1 : emps) { System.out.println(e1); } System.out.println("---------------------4번 INSERT후"); //'5길동' 사원 INSERT Emp e5 = new Emp(“5길동”); e = empRepository.save(e5); emps = empRepository.findAll(); for(Emp e1 : emps) { System.out.println(e1); } System.out.println("---------------------5번 INSERT후"); //'5길동' 사원 이름 수정 e = empRepository.findOne(5L); e.setEname("수정된5길동"); empRepository.save(e); emps = empRepository.findAll(); for(Emp e1 : emps) {
  • 15.