레이블이 Springjdbc인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Springjdbc인 게시물을 표시합니다. 모든 게시물 표시

2022년 1월 8일 토요일

스프링부트, Spring JDBC, MySQL, 모델, Persistence Layer, Service Layer, 자바학원, JAVA학원, 스프링학원, Spring학원

 

스프링부트, Spring JDBC, MySQL, 모델,  Persistence Layer, Service Layer, 자바학원, JAVA학원, 스프링학원, Spring학원


https://www.youtube.com/watch?v=K5R8FOYo34I&list=PLxU-iZCqT52Bihgf3v1bg5xEYeCwFQ_Zz&index=9 


https://www.youtube.com/watch?v=jDhjfRRbB9M&list=PLxU-iZCqT52Bihgf3v1bg5xEYeCwFQ_Zz&index=10 

http://ojc.asia/bbs/board.php?bo_table=LecSpring&wr_id=901 


스프링부트, Spring JDBC, MySQL, 모델, Persistence Layer, Service Layer

스프링부트, Spring JDBC, MySQL, 모델, Persistence Layer, Service Layer1.2.2. Spring JDBC현대의 대부분의 비즈니스 프로그램은 데이터베이스와 대화해야 합니다. 따라서 데이터베이스 처리 로직은 애플리케이

ojc.asia


1.2.2. Spring JDBC 

현대의 대부분의 비즈니스 프로그램은 데이터베이스와 대화해야 합니다. 따라서 데이터베이스 처리 로직은 애플리케이션의 핵심기능이라 할 수 있습니다.
먼저 데이터베이스 처리기술로 Spring JDBC를 살펴보겠습니다.
Spring JDBC는 자바표준 데이터베이스 처리기술인 JDBC를 개발자가 직접 사용할 경우 처리해야 하는 반복적인 작업을 스프링이 대신 처리해 주는 기술로 개발자를 지루함의 어둠으로부터 꺼내주는 유용한 기술입니다.


직원정보를 갖고 있는 테이블에 질의해서 데이터를 구한 다음 그 결과를 브라우저에게 전달하는 기능을 추가하겠습니다.


     새 프로젝트 생성

File > New > Spring Starter Project >

프로젝트 명: chapter1-2 > Next >

디펜던시 선택: Web, JDBC, MySQL > Finish



디펜던시
용도
Web
웹 서비스를 구축하기 위해 사용한다. 
스프링 핵심 모듈이 대부분 포함되어 있다.
JDBC
Spring JDBC 기술을 사용하기 위해 필요하다.
MySQL
MySQL 계열에 MariaDB와 연동하기 위한 연결 드라이버이다.


    프로젝트 환경설정

데이터베이스 연결정보를 환경설정 파일에 추가합니다.

application.properties

# DATASOURCE

spring.datasource.platform=mariadb

spring.datasource.sqlScriptEncoding=UTF-8

spring.datasource.url=jdbc:mysql://localhost:3306/testdb?createDatabaseIfNotExist=true

spring.datasource.username=root

spring.datasource.password=1111

spring.datasource.driver-class-name=com.mysql.jdbc.Driver


spring.datasource.platform 설정은 필수는 아니지만 스프링 부트에서 SQL의 DDL과 DML을 자동생성 하기위한schema-${platform}.sql, data-${platform}.sql 파일들을 사용할 수 있도록 해주기 때문에 여러 데이터베이스를 사용하는 개발 환경인 경우 설정해 놓으면 편리합니다.



     테스트 DB 생성

Maria DB를 설치하면 자동으로 test라는 DB는 존재하지만 testdb라는 DB는 없습니다. 테스트 DB는 "부록 3. HeidiSQL"을 참고하여 데이터베이스에 직접 접속하여 미리 생성해 놓아도 되고, 설정에서 "createDatabaseIfNotExist=true"라고 추가해 놓고 연결시도 시 생성하면서 사용하는 것도 가능합니다.


테스트 테이블 및 테스트 데이터를 입력해 놓기 위해서 application.properties 파일이 위치해 있는 src/main/resources 폴더에 다음 파일들을 생성합니다.


"부록 7.3.4"를 참조하여 파일 내용을 작성합니다.


schema.sql

data.sql


스프링 부트는 기동 시 위 파일들을 발견하면 schema.sql 파일의 DDL쿼리를 실행하고 다음으로 data.sql의 DML쿼리를 수행합니다.

스캐폴딩

프로젝트의 구조를 스캐폴딩(Scaffolding)이라고 부릅니다. 다음 그림을 보고 패키지 및 폴더를 생성합니다. com.example.employee 패키지 밑으로 하부 패키지 및 클래스를 생성하세요.



     모델 클래스

Value Object 역할을 수행할 모델 클래스를 작성합니다.

Emp.java

package com.example.employee.model;


public class Emp {

private int empno;

private String ename;

private String job;


public Emp() {}

public Emp(int empno, String ename, String job) {

this.empno = empno;

this.ename = ename;

this.job = job;

}

// getter, setter 생략

}


모델 클래스는 데이터베이스의 테이블과 1:1 대응되는 관계입니다. 테이블 내 한 줄의 데이터들을 객체에서 취급하기 위한 일종의 Value Object입니다. 때때로 취급하는 데이터의 개수가 다른 경우 별도의 DTO 클래스를 추가로 사용하기도 합니다. 


자바빈 규약에 따라 클래스의 필드변수는 private 접근제어자를 두고 getter, setter 메소드를 제공하는 형태로 작성합니다. 이러한 클래스를 계속 만들다 보면 단순하고 반복적인 작업을 계속하고 있다고 생각하게 됩니다. 이 부분에서 Lombok이 제공하는 기술을 사용하면 개발자는 필드변수만 선언하고 생성자, getter, setter 메소드를 만드는 작업은 롬복이 대신 처리하게 할 수 있습니다. 자세한 사용법은 "부록 4. Lombok"을 참고하세요.



     Persistence Layer

데이터베이스와 대화하는 로직을 취급하는 클래스를 작성합니다.

EmpDao.java

package com.example.employee.repository;


import java.util.List;

import com.example.employee.model.Emp;


public interface EmpDao {

public List<Emp> select();

}


경험으로 데이터베이스 처리 로직은 자주 변경된다는 것을 알고 있기에 일반적으로 DAO 구현 클래스를 만들기 전에 인터페이스를 작성합니다.


EmpDaoImpl.java

package com.example.employee.repository;


import java.util.List;

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.stereotype.Repository;

import com.example.employee.model.Emp;


@Repository

public class EmpDaoImpl implements EmpDao {

private JdbcTemplate jdbcTemplate;


@Autowired

public void setDataSource(DataSource dataSource){

jdbcTemplate = new JdbcTemplate(dataSource);

}


private RowMapper<Emp> rowMapper = (rs, idx)->{

Emp e = new Emp();

e.setEmpno(rs.getInt("empno"));

e.setEname(rs.getString("ename"));

e.setJob(rs.getString("job"));

return e;

};


@Override

public List<Emp> select() {

String sql = "select empno, ename, job from emp order by empno asc";

return jdbcTemplate.query(sql, rowMapper);

}

}


Spring JDBC 기술의 핵심은 반복적이고 뻔한 작업은 스프링이 대신 처리해 준다는 것입니다. 따라서 개발자는 상황에 따라 변하는 부분인 SQL쿼리 작성과 질의결과 처리 부분만 작업합니다. 


프로젝트 자바 버전이 1.8이므로 테이블 한 행의 데이터를 모델 객체에 옮겨 담는 바인딩로직을 정의하는 RowMapper 객체는 람다표현식을 사용하여 코드를 줄일 수 있습니다.



     Service Layer

EmpService.java

package com.example.employee.service;


import java.util.List;

import com.example.employee.model.Emp;


public interface EmpService {

public List<Emp> select();

}


여기서는 간단하게 하나의 메소드만 만들어 보겠습니다. 다른 메소드들은 하나씩 추가해 가시면서 살펴보시기 바랍니다.

EmpServiceImpl.java

package com.example.employee.service;


import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.example.employee.model.Emp;

import com.example.employee.repository.EmpDao;


@Service

public class EmpServiceImpl implements EmpService {

@Autowired

private EmpDao empDao;


@Override

public List<Emp> select() {

return empDao.select();

}

}


서비스 레이어의 존재 이유를 현재까지 작성한 코드만을 보고 생각해 내기 어렵지만 실제로 서비스를 구축하게 되면 자연스럽게 여러 비즈니스 로직이 필요하게 되고 그에 따라 서비스 레이어에 여러 로직이 추가됩니다. 전자정부 표준프레임워크에서도 퍼시스턴스 레이어와 서비스 레이어에는 항상 인터페이스를 두고 개발하기를 권고하고 있습니다. 이는 많은 개발자들이 수많은 프로젝트를 수행하면서 인터페이스를 두고 개발하는 것이 좋다는 결론에 동의한 결과라고 볼 수 있습니다.


일반적으로 트랜잭션은 서비스 클래스에 어노테이션으로 설정합니다. 그래야 비즈니스 로직에 따른 여러 쿼리들을 하나의 단위로 처리할 수 있기 때문입니다. 스프링 부트로 프로젝트를 만들고 디펜던시로 JDBC나 JPA를 추가하면 트랜잭션 객체가 빈으로 등록되어 있어서 @Transactional 어노테이션을 서비스 클래스에 추가하기만 하면 클래스 내 모든 메소드에 트랜잭션이 적용됩니다. 



     Presentation Layer

프리젠테이션 레이어의 임무는 받은 데이터를 예쁘게 만들어 클라이언트에게 전달하는 것입니다.

EmpController.java

package com.example.employee.controller;


import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;

import com.example.employee.service.EmpService;


@RestController

public class EmpRestController {

@Autowired

private EmpService empService;


@GetMapping("/emps")

public Object getEmps(){

return empService.select();

}

}


@GetMapping 어노테이션은 @RequestMapping(method={GET}) 어노테이션과 같은 의미를 갖는 편의성 어노테이션입니다. empService.select 메소드의 호출결과는 List<Emp> 객체입니다. 스프링은 RestController 클래스안에 메소드가 객체를 리턴하면 Jackson 라이브러리를 사용하여 JSON 문자열로 변경하고 그 결과를 클라이언트에게 전달합니다.


spring-boot-starter-web 디펜던시를 설정하면 jackson 라이브러리가 추가됩니다.



    테스트

http://localhost:8080/emps 주소로 서버에 접속합니다. 총 14건의 Emp 객체가 JSON 포맷의 문자열로 표시됩니다. 참고로 사용하고 있는 테스트 데이터는 오라클 데이터베이스를 설치하면 자동으로 추가되는 SCOTT 계정의 테스트 데이터를 사용하고 있습니다. 


다음 그림은 지면을 아끼기 위해서 상위 2건만 표시하고 있습니다.



     정리

서비스 레이어인 EmpService.java, EmpServiceImpl.java는 비즈니스 로직이 없고 미래에도 없을 거라고 판단된다면 작성하지 않아도 됩니다. 그렇게 본다면 Spring JDBC 기술을 사용할 때 개발자가 처리해야 하는 업무와 순서는 다음과 같습니다.


  • pom.xml

프로젝트에서 사용하는 디펜던시를 설정한다.

  • application.properties

데이터베이스 연결정보를 설정한다.

  • Emp.java 

테이블의 1 Row를 자바 객체의 1 Object로 취급하는 용도의 모델 클래스를 만든다.

  • EmpDao.java, EmpDaoImpl.java

데이터베이스 처리로직을 갖고 있는 DAO 클래스를 작성한다.

  • EmpRestController.java

사용자의 URL 요청을 받아서 결과를 돌려주는 기능을 수행하는 컨트롤러 클래스를 생성한다. 필요하다면 JSP를 별도로 사용하여 최종 결과로 HTML을 클라이언트에 전달할 수 있다.


여러 개의 파일을 역할에 따라 체계적으로 만든 후 연동해서 처리합니다. 사실 대부분의 작업은 미래를 위한 일종의 투자였습니다. 로직이 추가되거나 변화될 것을 대비해서 미리 예비 작업을 수행했다고 볼 수 있습니다. 


데이터베이스와 대화하는 로직을 갖고 있는 EmpDaoImpl 클래스의 메소드를 살펴보면 코드는 두줄에 불과합니다. 이는 스프링이 반복적으로 사용되는 JDBC의 Connection. Statement, ResultSet 객체들을 대신 처리해 주기 때문에 가능합니다. 


더불어 스프링은 체크드 예외를 언체크드 예외로 전환해서 던져주기 때문에 의미없는 try 구문을 개발자가 매번 코딩할 필요도 없습니다. 하지만 데이터베이스 로직만을 개발해서 다른 개발자에게 제공하는 경우에는 사용의 오용을 방지하기 위해서 try구문이 필요할 수도 있습니다. 이런 경우 여러 데이터베이스가 제 각각 던지는 예외를 일관된 예외로 변경해서 돌려 주는 스프링의 예외전환 서비스의 혜택을 누릴 수 있습니다.


#스프링부트, #스프링JDBC, #SpringJDBC, #스프링교육, #스프링동영상, #자바동영상, #자바교육, #스프링학원, #자바학원, ​스프링부트, 스프링JDBC, SpringJDBC, 스프링교육, 스프링동영상, 자바동영상, 자바교육, 스프링학원, 자바학원, ​



2021년 12월 5일 일요일

[스프링부트/MariaDBCRUD/자바교육/스프링교육/JAVA학원/Spring학원]스프링5 JDBC JdbcTemplate 클래스,execute, update, batchUpdate, query, RowMapper,스프링JDBC

 



[스프링부트/MariaDBCRUD/자바교육/스프링교육/JAVA학원/Spring학원]스프링5 JDBC JdbcTemplate 클래스,execute, update, batchUpdate, query, RowMapper,스프링JDBC


https://youtu.be/jDhjfRRbB9M



이미지 썸네일 삭제
[스프링부트/MariaDB기반 CRUD 실습]스프링5 JDBC JdbcTemplate 클래스,execute, update, batchUpdate, query 메소드와 RowMapper, 스프링프레임워크/스프링동영상/자바교육/스프링교육/자바학원/스프링학원

[스프링부트/MariaDB기반 CRUD 실습]스프링5 JDBC JdbcTemplate 클래스,execute, update, batchUpdate, query 메소드와 RowMapper, 스프링프레임워크/스프링동영상/자바교육/스프링교육/자바학원/스프링학원JdbcTemplate의 execute 메소드n 주로 DDL(CREATE, ALTER, DROP) 처리용으…

ojc.asia



[스프링부트/MariaDB기반 CRUD 실습]스프링5 JDBC JdbcTemplate 클래스,execute, update, batchUpdate, query 메소드와 RowMapper, 스프링프레임워크/스프링동영상/자바교육/스프링교육/자바학원/스프링학원


JdbcTemplate의 execute 메소드

 

n  주로 DDL(CREATE, ALTER, DROP) 처리용으로 사용하며 리턴값은 void 형이다.

@Autowired

JdbcTemplate jdbcTemplate;

 

@Override

public void run(String... args) throws Exception {

           jdbcTemplate.execute("DROP TABLE customers");

           jdbcTemplate.execute("CREATE TABLE customers(id number GENERATED AS IDENTITY, firstName VARCHAR(100), lastName VARCHAR2(100))");

}

 

n  SQL 문자열로 부터 PreparedStatement를 생성하고 파라미터를 바인딩 하는 작업을 많이 하므로 JdbcTemplate은 execute 메소드를 제공한다.

n  DML에서 사용하는 경우 경우 백그라운드에서 JdbcTemplate이 PreparedStatement와 PreparedStatementSetter를 생성 시킨다.

 

public void insertPerson(Person person) {

String sql = “insert into person (id, firstname, lastname) values (?,?,?)”;

 

Object[] params = new Object[] {

                                               person.getId(),

                                               person.getFirstName(),

                                               person.getLastName()

                                          };

return jdbcTemplate.execute(sql, params);

}

 

JdbcTemplate의 update 메소드

 

n  execute에 비해 NULL을 setting할때 이점이 있다.(TYPE을 인자로 받아들임)

n  주로 DML 처리용(insert, update, delete)으로 파라미터는 가변인자나 객체배열 형태로 제공하면 된다.

 int update(String sql)

 int update(String sql, Object... args)

 int update(String sql, Object[] args)

 

n  SQL문의 실행이 성공하면 추가 / 변경 / 삭제 된 행 수를 리턴한다.

n  아래 SQL문 실행시 백그라운드에서 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);

}

 

JdbcTemplate의 batchUpdate 메소드

 

n  갱신하고자 하는 레코드가 2건 이상인 경우에 사용하며, BatchPreparedStatementSetter를 만들어 인자로 넣어준다.

setValues(PreparedStatemet ps, int i) throws SQLException;  //파라미터 바인딩


int getBatchSize();  //실행시킬 SQL문의 수를 알려준다. setValues의 호출 수 지정.

 

[예문1]

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);  //질의문 실행

}//:

 

[예문2]

public void insertBatch(final List persons){

    String sql = “insert into person (id, firstname, lastname) values (?,?,?)”;

    List<Object[]> parameters = new ArrayList<Object[]>();

 

    for (Person person: persons) {

      parameters.add(new Object[] { person.getId(), person.getFirstName(), person.getLastName()} );

    }

this.jdbcTemplate.batchUpdate(sql, parameters);  //질의문 실행

}

 

JdbcTemplate의 query 메소드와 RowMapper 인터페이스

 

n  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;

}//:

 

 

 

 

 

 

JdbcTemplate의 queryForObject, queryForList, 기타 query 메소드

 

n  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;

}

 

n  queryForList : 한 개 이상의 레코드 처리용, 여러건의 레코드를 List 객체로 리턴해 준다.

public List<Person> getAllPerson() {

String sql = "SELECT * FROM person ";

List<Person> persons = this.jdbcTemplate.queryForList(sql, new PersonRowMapper());

return persons;

}

 

n  기타 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);



 

[JdbcTemplate을 이용한 CRUD 예제]

 

n  Spring Boot, MariaDB를 이용해서  EMP 테이블을 만들고 JdbcTemplate을 이용하여 CRUD 기능을 구현해 보자.



STS에서



File -> New  -> Project  -> Spring Starter Project

Name : jdbc2

Package : jdbc



다음화면에서 SQL : JDBC API, MySQL Driver 선택





[pom.xml]


<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

       <modelVersion>4.0.0</modelVersion>

       <parent>

             <groupId>org.springframework.boot</groupId>

             <artifactId>spring-boot-starter-parent</artifactId>

             <version>2.3.4.RELEASE</version>

             <relativePath/> <!-- lookup parent from repository -->

       </parent>

       <groupId>com.example</groupId>

       <artifactId>jdbc2</artifactId>

       <version>0.0.1-SNAPSHOT</version>

       <name>jdbc2</name>

       <description>Demo project for Spring Boot, JdbcTemplate</description>



       <properties>

             <java.version>1.8</java.version>

       </properties>



       <dependencies>

             <dependency>

                    <groupId>org.springframework.boot</groupId>

                    <artifactId>spring-boot-starter-jdbc</artifactId>

             </dependency>



             <dependency>

                    <groupId>mysql</groupId>

                    <artifactId>mysql-connector-java</artifactId>

                    <scope>runtime</scope>

             </dependency>

             <dependency>

                    <groupId>org.springframework.boot</groupId>

                    <artifactId>spring-boot-starter-test</artifactId>

                    <scope>test</scope>

                    <exclusions>

                           <exclusion>

                                 <groupId>org.junit.vintage</groupId>

                                 <artifactId>junit-vintage-engine</artifactId>

                           </exclusion>

                    </exclusions>

             </dependency>

       </dependencies>



       <build>

             <plugins>

                    <plugin>

                           <groupId>org.springframework.boot</groupId>

                           <artifactId>spring-boot-maven-plugin</artifactId>

                    </plugin>

             </plugins>

       </build>



</project>



[src/main/resources/schema.sql]

drop table if exists emp;

create table emp

(

           empno int(4) not null auto_increment,

           ename varchar(50),      

           sal   int(15),

           primary key (empno)

) ENGINE=InnoDB;



[src/main/resources/data.sql(파일 속성에서 text encoding을 UTF-8로)]


insert into emp(ename, sal) values ('1길동', 1000000);

insert into emp(ename, sal) values ('2길동', 2000000);

insert into emp(ename, sal) values ('3길동', 3000000);



[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=mariadb

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.sql-script-encoding=UTF-8

spring.datasource.initialization-mode=always



도메인 클래스(Emp.java) – 테이블구조와 동일하다.


package jdbc;



public class Emp {

       private long empno;

       private String ename;

       private int sal;

      

       public Emp(long empno, String enameint sal) {

             super();

             this.empno = empno;

             this.ename = ename;

             this.sal = sal;

       }

      

       @Override

       public String toString() {

             return "Emp [empno=" + empno + ", ename=" + ename + ", sal=" + sal + "]";

       }

      

       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 int getSal() {

             return sal;

       }

       public void setSal(int sal) {

             this.sal = sal;

       }     

}



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;



@Component


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");

int sal = rs.getInt("sal");

                     

                      return new Emp(empno, ename, sal);

           }

}



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);

           int[] batchInsert(List<Object[]> params);

}



Repository 구현체(EmpRepositoryImpl.java) – 영속성 서비스용 구상클래스


package jdbc.repository;



import java.util.List;



import javax.annotation.PostConstruct;



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 {

       @Autowired

       private JdbcTemplate jdbcTemplate;

      

       @Autowired

       RowMapper<Emp> empRowMapper;

      

       @Override

       public List<Emp> findAll() {

             List<Emp> emps = jdbcTemplate.query("select empno, ename, sal from emp",empRowMapper);

             return emps;

       }

      

       @Override

       public Emp findOne(Long empno) {

             return (Emp)jdbcTemplate.queryForObject("select empno, ename, sal from emp where empno = ?"empRowMapperempno);

       }



       @Override

       @Transactional(readOnly=false)

       public Emp save(Emp emp) {

             this.jdbcTemplate.update("insert into emp (empno, ename, sal) values (?, ?, ?)"

                                            ,emp.getEmpno(), emp.getEname(), emp.getSal());

             return emp;        

       }



       @Override

       @Transactional(readOnly=false)

       public void delete(Long empno) {

             this.jdbcTemplate.update("delete from emp where empno = ?",    empno);

       }



       @Override

       @Transactional(readOnly=false)

       public int[] batchInsert(List<Object[]> params) {

             return this.jdbcTemplate.batchUpdate("insert into emp (empno, ename, sal) values (?, ?, ?)",params);

       }

}



스프링 부트 메인(Jdbc2Application.java)


package jdbc;



import java.util.ArrayList;

import java.util.List;

import java.util.stream.IntStream;



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;



           @Override

           public void run(String... args) throws Exception {

                      // 전체 사원 SELECT

                      List<Emp> emps = empRepository.findAll();

                      for (Emp e : emps) {

                                 System.out.println(e);

                      }

                      System.out.println("전체사원 SELECT 후---------------------");



                      // 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길동", 4000000));

                      emps = empRepository.findAll();

                      for (Emp e1 : emps) {

                                 System.out.println(e1);

                      }

                      System.out.println("4번 사원 INSERT 후---------------------");

                     

                      //5,6번 사원 배치인서트

                      List<Object[]> params = new ArrayList<Object[]>();

                      params.add(new Object[] {5L, "5길동", 5000000});

                      params.add(new Object[] {6L, "6길동", 6000000});

                      int[] ret = empRepository.batchInsert(params);

                      System.out.println(IntStream.of(ret).sum() + "건 입력OK!");

                     

                      emps = empRepository.findAll();

                      for (Emp e1 : emps) {

                                 System.out.println(e1);

                      }

                      System.out.println("5,6번 사원 배치인서트 후---------------------");

           }

}         



[실행결과]


Emp [empno=1, ename=1길동, sal=1000000]

Emp [empno=2, ename=2길동, sal=2000000]

Emp [empno=3, ename=3길동, sal=3000000]

전체사원 SELECT 후---------------------

Emp [empno=2, ename=2길동, sal=2000000]

2번 사원 SELECT 후---------------------

Emp [empno=1, ename=1길동, sal=1000000]

Emp [empno=2, ename=2길동, sal=2000000]

3번 사원 DELETE 후 전체출력---------------------

Emp [empno=1, ename=1길동, sal=1000000]

Emp [empno=2, ename=2길동, sal=2000000]

Emp [empno=4, ename=4길동, sal=4000000]

4번 사원 INSERT 후---------------------

2건 입력OK!

Emp [empno=1, ename=1길동, sal=1000000]

Emp [empno=2, ename=2길동, sal=2000000]

Emp [empno=4, ename=4길동, sal=4000000]

Emp [empno=5, ename=5길동, sal=5000000]

Emp [empno=6, ename=6길동, sal=6000000]

5,6번 사원 배치인서트 후---------------------






 


#스프링jdbc, #JdbcTemplate, #Springjdbc, #자바스프링, #Spring동영상, #Spring강의, #스프링프레임워크, #스프링교육, #스프링학원, #스프링강좌, #스프링강의, #자바학원, #자바, #스프링동영상, #자바동영상, #스프링프레임워크교육, #스프링프레임워크강의, #스프링프레임워크학원,  스프링jdbc, JdbcTemplate, Springjdbc, 자바스프링, Spring동영상, Spring강의, 스프링프레임워크, 스프링교육, 스프링학원, 스프링강좌, 스프링강의, 자바학원, 자바, 스프링동영상, 자바동영상, 스프링프레임워크교육, 스프링프레임워크강의, 스프링프레임워크학원,   

(C#교육동영상)C# ADO.NET 실습 ODP.NET/ODAC 설치 오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원

  (C#교육동영상)C# ADO.NET 실습  ODP.NET/ODAC 설치  오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원 https://www.youtube.com/watch?v=qIPU85yAlzc&list=PLxU-i...