Spring JDBC

brave_chicken·2024년 4월 28일

잇(IT)생 챌린지

목록 보기
38/90

[DB연동]
JDBC -> Spring JDBC -> MyBatis -> JPA

		-----------
		JdbcTemplate

https://docs.spring.io/spring-framework/docs/5.2.25.RELEASE/javadoc-api/

1. SQL Mapper

  • JdbcTemplate
  • MyBatis
  • 개발자가 직접 SQL을 생성

1) JdbcTemplate

(1) JDBC를 사용하기 위해서 반복적으로 정의했던 내용을 대신 처리해준다.

	- 커넥션생성
	- Statement 객체생성
	- SQL실행
	- try~catch~finally로 처리
	- select인 경우 ResultSet에 대한 결과처리
	- 자원반납
	

(2) 개발자가 sql문과 ?에 대한 값만 설정(나머지는 스프링 내부에서 모두 처리한다.)

(3) Connection을 관리하는 객체와 JdbcTemplate을 이용해서 작업

JdbcTemplate => CLRUD관련 모두 처리할 수 있게 메소드제공 해줌

2. JdbcTemplate

1) JdbcTemplate을 사용하기 위한 작업순서

(1) 라이브러리를 pom.xml(내부에서 사용하는 의존모듈(new해서 쓰고있는 것들) 정의하는 설정파일)에 등록

=> Spring Jdbc, 오라클드라이버

(2) 커넥션을 관리하는 객체 생성

  • 커넥션풀을 사용할 것이나 DriverManager방식(요청이 들어오면 커넥션 객체를 하나씩 만들어서 리턴)으로 커넥션 객체를 관리하는 방식을 사용
  • DriverManagerDataSource
  • spring 기능을 사용하기 위해서 필요한 객체로 객체를 생성하고 관리하는 작업을 IoC컨테이너가 작업
  • IoC컨테이너가 커넥션을 관리하는 기능을 갖고있는 DriverManagerDataSource객체를 생성할 수 있도록 설정정보를 xml(드라이버, url, 계정, 계정패스워드)에 정의

(3) SQL을 실행할 수 있는 객체를 생성

  • JdbcTemplate
  • IoC컨테이너에서 생성
  • JdbcTemplate 내부에서 SQL문을 처리하기 위해 커넥션객체가 필요
  • 커넥션객체는 DriverManagerDataSource객체로부터 얻을 것(DBUtil에서 getConnect메소드를 호출해서 커넥션을 얻는 작업) => 관계를 IoC컨테이너가 매핑

[실습]
scott/tiger계정으로 접속해서 member테이블의 레코드 수를 조회하는 작업을 해보세요

  • member.xml로 작업
  • MemberDAO작업
  • MemberDAOTest작업
    조회된 레코드수 : ___개

2) JdbcTemplate메소드

(1) update - insert, delete, update를 처리하기 위한 jdbcTemplate의 메소드

실습

first

hr.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
	<context:component-scan base-package="first"/>
	<!-- 커넥션을 DriverManager방식으로 관리하는 객체 생성 (IoC컨테이너가 빈을 만들 수 있도록 명세를 정의)-->
	<!-- Driver Manager로 커넥션 생성하는 것과 동일,  DBUtil에서 처리하던 것 -->
	<!-- dice에 해당 실습.. -->
	<bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><!-- 커넥션객체만 관리 / DBUtil에서 하던일-->
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
		<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:xe"/>
		<property name="username" value="hr"/>
		<property name="password" value="hr"/>
	</bean>
	
	<!-- player에 해당 -->
	<!-- SQL문 실행할 수 있도록 기능을 제공하는 클래스 -->
	<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
		<constructor-arg ref="ds"/>
	</bean>
	
</beans>

HrDAO

@Repository
public class HrDAO {
	//Spring에서 제공하는 JdbcTemplate의 기능을 이용해서 DB연동
	private JdbcTemplate template;

	//스프링컨테이너가 매개변수있는 생성자를 호출하면서 객체를 생성
	//=> 객체 생성할때 매개변수에 해당하는 빈이 있는지 타입을 검사해서 있으면 주입해서 생성한다.
	@Autowired
	public HrDAO(JdbcTemplate template) {
		super();
		this.template = template;
	}
	
	//hr게정의 jobs테이블의 레코드 수를 리턴하는 메소드를 정의
	//select count(*) from jobs
	public int count() {
		return template.queryForObject("select count(*) from jobs", Integer.class);//캐스팅하는거임
		//queryForObject-> 오브젝트하나로 매핑될때
	}
}

HrDAOTest

public class HrDAOTest {
	public static void main(String[] args) {
		ApplicationContext factory = new ClassPathXmlApplicationContext("config/hr.xml");
		HrDAO dao = factory.getBean("hrDAO", HrDAO.class);
		System.out.println("조회된 레코드 수 : "+dao.count());
	}
}

member

member.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
	
	<context:component-scan base-package="member"/>
	<bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
		<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:xe"/>
		<property name="username" value="scott"/>
		<property name="password" value="tiger"/>
	</bean>
	
	<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
		<constructor-arg ref="ds"/>
	</bean>
</beans>

interface AbstractMenu

public interface AbstractMenu {
	void insertMenu();
	void updateMenu();
	 void deleteMenu();
	 void findByAddrMenu();
	 void loginMenu();
	 void selectMenu();
	 void myPageMenu();
	 void countMenu();
}

interface MemberDAO / member테이블 엑세스

public interface MemberDAO {
	//회원가입
	int insert(MemberDTO user);
	//회원정보수정
	int update(MemberDTO updateUserInfo);
	//회원탈퇴
	int delete(String id);
	//로그인
	MemberDTO login(String id, String pass);
	//전체회원목록조회
	List<MemberDTO> select();
	//회원정보조회
	MemberDTO findById(String id);
	//주소로검색
	List<MemberDTO> findByAddr(String addr);
	//전체인원수조회
	int count();
}

MemberDTO / member테이블의 레코드를 객체로 정의

public class MemberDTO {
	private String id;
	private String pass;
	private String name;
	private String addr;
	private Date regDate;
	private int point;
	private String info;
	public MemberDTO() {
		
	}
	//select용
	public MemberDTO(String id, String pass, String name, String addr, Date regDate, int point, String info) {
		this(id, pass, name, addr, info);
		this.regDate = regDate;
		this.point = point;
		
	}
	//update용
	public MemberDTO(String id, String addr, String info) {
		super();
		this.id = id;
		this.addr = addr;
		this.info = info;
	}
	//insert용
	public MemberDTO(String id, String pass, String name, String addr, String info) {
		super();
		this.id = id;
		this.pass = pass;
		this.name = name;
		this.addr = addr;
		this.info = info;
	}
	
	
	@Override
	public String toString() {
		return "MemberDTO [id=" + id + ", pass=" + pass + ", name=" + name + ", addr=" + addr + ", regDate=" + regDate
				+ ", point=" + point + ", info=" + info + "]";
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPass() {
		return pass;
	}
	public void setPass(String pass) {
		this.pass = pass;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddr() {
		return addr;
	}
	public void setAddr(String addr) {
		this.addr = addr;
	}
	public Date getRegDate() {
		return regDate;
	}
	public void setRegDate(Date regDate) {
		this.regDate = regDate;
	}
	public int getPoint() {
		return point;
	}
	public void setPoint(int point) {
		this.point = point;
	}
	public String getInfo() {
		return info;
	}
	public void setInfo(String info) {
		this.info = info;
	}
	
}

MemberDAOImpl

//DAOTest -> MenuUI -> MemberDAO -> JdbcTemplate -> DateSource,JdbcAPI
@Repository
public class MemberDAOImpl implements MemberDAO {
	private JdbcTemplate template;
	
	@Autowired
	public MemberDAOImpl(JdbcTemplate template) {
		super();
		this.template = template;
	}
	
	@Override	
	public int count() {
		return template.queryForObject("select count (*) from member", Integer.class);
	}

	@Override
	public int insert(MemberDTO user) {
		String sql = "insert into member values(?,?,?,?,sysdate,10000,?)";
		//JdbcTemplate의 update메소드를 호출해서 db에 insert하는 작업을 수행
		//sql문과 ?에 대한 값을 매개변수로 전달
		//sql문을 정의하고 ?에 셋팅할 값을 순서대로 지정
		//id,pass,name,addr,,,info
		return template.update(sql, user.getId(), user.getPass(), user.getName(), user.getAddr(), user.getInfo());
	}

	@Override
	public int update(MemberDTO updateUserInfo) {
		// id가 만족하는 데이터의 주소와 정보를 수정할 수 있도록 처리
		String sql = "update member set addr=?,info=? where id=? ";
		return template.update(sql, updateUserInfo.getAddr(), updateUserInfo.getInfo(), updateUserInfo.getId());
	}

	@Override
	public int delete(String id) {
		// 입력받은 아이디에 해당하는 레코드를 삭제
		String sql = "delete from member where id=?";
		return template.update(sql, id);
	}

	@Override
	public MemberDTO login(String id, String pass) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<MemberDTO> select() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public MemberDTO findById(String id) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<MemberDTO> findByAddr(String addr) {
		// TODO Auto-generated method stub
		return null;
	}
	
}
@Service("menu")
public class MenuUI implements AbstractMenu {
	Scanner key = new Scanner(System.in);
	MemberDAOImpl dao;
	
	@Autowired
	public MenuUI(MemberDAOImpl dao) {
		super();
		this.dao = dao;
	}

	@Override
	public void countMenu() {
		System.out.println("*******사원 수 조회하기********");
		System.out.println("조회된 레코드 수:"+dao.count());
		
	}
	
	public void insertMenu(){
		System.out.println("*******사원등록********");
		System.out.print("아이디:");
		String id = key.next();
		System.out.print("패스워드:");
		String pass = key.next();
		System.out.print("성명:");
		String name = key.next();
		System.out.print("주소:");
		String addr = key.next();
		System.out.print("기타:");
		String info = key.next();
		//여기에서 MemberDAO의 메소드를 호출하세요
		MemberDTO user = new MemberDTO(id, pass, name, addr, info);
		int result = dao.insert(user);
		if(result>=1) {
			System.out.println("=========================");
			System.out.println("로그인해서 메인페이지 이동");
			System.out.println("=========================");
		}else {
			System.out.println("--------------------------");
			System.out.println("실패를 알려 줄 수 있는 alert실행");
			System.out.println("다시 회원가입할 수 있는 페이지로 이동");
			System.out.println("--------------------------");
		}
		//dao.insert(id, pass, name, addr, info);
	}
	public void updateMenu(){
		System.out.println("*******사원수정********");
		System.out.print("정보:");
		String info = key.next();
		System.out.print("주소:");
		String addr = key.next();
		System.out.print("아이디:");
		String id = key.next();
		//여기에서 MemberDAO의 메소드를 호출하세요
		//dao.update(info, addr, id);
		MemberDTO updateUser = new MemberDTO(id, addr, info);
		int result = dao.update(updateUser);
		System.out.println(result+"개 수정완료");
	}
	public void deleteMenu(){
		System.out.println("*******사원삭제********");
		System.out.print("삭제할id:");
		String id = key.next();
		//여기에서 MemberDAO의 메소드를 호출하세요
		int result = dao.delete(id);
		System.out.println(result+"개 삭제완료");
	}
	public void findByAddrMenu(){
		System.out.println("*******사원검색********");
		System.out.print("주소:");
		String addr = key.next();
		//여기에서 MemberDAO의 메소드를 호출하세요
		List<MemberDTO> searchlist =  dao.findByAddr(addr);
		for(MemberDTO user:searchlist) {
			print(user);
		}
	}
	public void loginMenu() {
		System.out.println("*******로그인********");
		System.out.print("아이디:");
		String id = key.next();
		System.out.print("패스워드:");
		String pass = key.next();
		MemberDTO loginUser =  dao.login(id, pass);
		//로그인 성공하면 로그인성공!!메시지와 로그인한 사용자의 모든 정보를 출력(print호출)
		if(loginUser!=null) {
			System.out.println("로그인성공");
			print(loginUser);
		}else {
			System.out.println("로그인실패");
		}
		//로그인 실패하면 로그인실패!!메시지를 출력
	}
	public void selectMenu(){
		System.out.println("*******사원조회********");
		//여기에서MemberDAO의 메소드를 호출하세요 - 전체사원조회
		List<MemberDTO> userlist =  dao.select();
		System.out.println("조회된 레코드 갯수:"+userlist.size());
		//ArrayList에 저장된 DTO를 다양하게 출력할 수 있도록 코드를 작성
		for(MemberDTO user:userlist) {
			print(user);
		}
	}
	public void myPageMenu() {
		System.out.println("*******마이페이지********");
		System.out.print("아이디:");
		String id = key.next();
		//myPageMenu메소드에서 입력 받은 아이디로 아이디에 따른 정보를 조회할 수 있도록 코드를 완성하세요
		//   - MemberDAO, MemberDAOImpl에 메소드를 정의하고 작업하세요(리턴타입, 메소드명, 매개변수는 각자 알아서 작업하기)
		MemberDTO user=  dao.findById(id);
		if(user==null) {
			System.out.println("일치하는 사용자가 없습니다.");
		}else {
			print(user);
		}
	}
	public void print(MemberDTO user) {
		System.out.print(user.getId()+"\t");
		System.out.print(user.getPass()+"\t");
		System.out.print(user.getName()+"\t");
		System.out.print(user.getAddr()+"\t");
		System.out.print(user.getRegDate()+"\t");
		System.out.print(user.getPoint()+"\t");
		System.out.println(user.getInfo()+"\t");
	}
}

MemberDAOTest

public class MemberDAOTest {
	public static void main(String[] args) {
		Scanner key = new Scanner(System.in);
		System.out.println("******인사관리시스템********");
		System.out.println("1. 사원등록");
		System.out.println("2. 전체사원조회");
		System.out.println("3. 사원수정");
		System.out.println("4. 사원퇴사");
		System.out.println("5. 주소로 사원 검색");
		System.out.println("6. 로그인");
		System.out.println("7. 사원정보조회");
		System.out.println("8. 인원수조회");
		System.out.print("원하는 작업을 선택하세요:");
		int choice  = key.nextInt();
		show(choice);
	}
	public static void show(int choice){
		ApplicationContext factory = new ClassPathXmlApplicationContext("config/member.xml");
		AbstractMenu ui = factory.getBean("menu", AbstractMenu.class);
		switch(choice){
			case 1:
				ui.insertMenu();
				break;
			case 2:
				ui.selectMenu();
				break;
			case 3:
				ui.updateMenu();
				break;
			case 4:
				ui.deleteMenu();
				break;
			case 5:
				ui.findByAddrMenu();
				break;
			case 6:
				ui.loginMenu();
				break;
			case 7:
				ui.myPageMenu();
				break;
			case 8:
				ui.countMenu();
				break;
				
		}
	}
}

dept

dept.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
	
	<context:component-scan base-package="dept"/>
	<bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
		<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:xe"/>
		<property name="username" value="scott"/>
		<property name="password" value="tiger"/>
	</bean>
	<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
		<constructor-arg ref="ds"/>
	</bean>
	
</beans>

interface AbstractUI

public interface AbstractUI {
	//프로그램의 시작을 나타내는 메소드
	void show();
	//count와 관련된 메소드(dao의 count를 호출하는 메소드)
	void countMenu();
	//insert와 관련된 메소드(dao의 insert를 호출하는 메소드)
	void insertMenu();
	//update와 관련된 메소드(dao의 update를 호출하는 메소드)
	void updateMenu();
	//delete와 관련된 메소드(dao의 delete를 호출하는 메소드)
	void deleteMenu();
	//전체목록보기와 관련된 메소드(dao의 전체목록보기 메소드를 호출하는 메소드)
	void showAllMenu();
	//login와 관련된 메소드(dao의 login를 호출하는 메소드)
	void showDeptInfo();
	//검색과 관련된 메소드(dao의 검색기능 메소드를 호출하는 메소드)
	void findByDept();
	//각 부서별 근무 직원을 검색하는 메소드
	void getMemberList();
	
}

interface DeptDAO

public interface DeptDAO {
	//부서상세보기 - 부서번호로 부서의 정보를 조회 - 필수
	//DeptDTO getDeptInfo(String deptno);
	//전체 부서의 목록 보기 - 필수
	//List<DeptDTO> getDeptList();
	//부서검색 - 필수
	//List<DeptDTO> getDeptSearch(String deptname);
	//부서등록
	int insert(DeptDTO dept);
	//부서업데이트 - 부서의 전화번호와 주소를 수정하도록
	int update(DeptDTO dept);
	
	//총부서갯수
	int count();
}

DeptDTO

public class DeptDTO {
	String deptCode;
	String deptName;
	String tel;
	String addr;
	public DeptDTO(){
		
	}
	public DeptDTO(String deptCode, String deptName, String tel, String addr) {
		super();
		this.deptCode = deptCode;
		this.deptName = deptName;
		this.tel = tel;
		this.addr = addr;
	}
	public String getDeptCode() {
		return deptCode;
	}
	public void setDeptCode(String deptCode) {
		this.deptCode = deptCode;
	}
	public String getDeptName() {
		return deptName;
	}
	public void setDeptName(String deptName) {
		this.deptName = deptName;
	}
	public String getTel() {
		return tel;
	}
	public void setTel(String tel) {
		this.tel = tel;
	}
	public String getAddr() {
		return addr;
	}
	public void setAddr(String addr) {
		this.addr = addr;
	}
	@Override
	public String toString() {
		return "DeptDTO [deptCode=" + deptCode + ", deptName=" + deptName + ", tel=" + tel + ", addr=" + addr + "]";
	}
}

DeptDAOImpl

@Repository
public class DeptDAOImpl implements DeptDAO {
	private JdbcTemplate template;
	
	@Autowired
	public DeptDAOImpl(JdbcTemplate template) {
		super();
		this.template = template;
	}

	@Override
	public int insert(DeptDTO dept) {
		//부서등록
		System.out.println("insert : "+dept);
		String sql = "insert into mydept values(?,?,?,?)";
		return template.update(sql, dept.getDeptCode(),dept.getDeptName(),dept.getTel(),dept.getAddr());
	}

	@Override
	public int update(DeptDTO dept) {
		//부서업데이트 - 부서의 전화번호와 주소를 수정하도록
		String sql = "update mydept set tel=? ,addr=? where deptcode=?";
		return template.update(sql, dept.getTel(), dept.getAddr(), dept.getDeptCode());
	}

	@Override
	public int count() {
		//총부서갯수
		return template.queryForObject("select count (*) from mydept", Integer.class);
	}

}
@Service("deptservice")
public class MenuUI implements AbstractUI {
	Scanner key = new Scanner(System.in);
	DeptDAOImpl dao;
	
	@Autowired
	public MenuUI(DeptDAOImpl dao) {
		super();
		this.dao = dao;
	}
	
	//시작을 알리는 메소드
	public void show(){
		System.out.println("**********부서관리 시스템************");
		System.out.println("1. 부서등록");
		System.out.println("2. 부서상세보기");
		System.out.println("3. 부서정보수정(부서번호)");
		System.out.println("4. 부서삭제");
		System.out.println("5. 전체 부서 목록보기");
		System.out.println("6. 부서검색(부서명)");
		System.out.println("7. 부서갯수조회");
		System.out.println("8. 각 부서별 근무직원 조회하기(부서명)");
		System.out.println("9. 종료");
		System.out.print("원하는 작업을 선택하세요:");
		int menu=key.nextInt();
		menuSelect(menu);
	}
	private void menuSelect(int menu) {
		switch(menu){
			case 1: 
				insertMenu();
				break;
			case 3: 
				updateMenu();
				break;
			case 7: 
				countMenu();
				break;
			case 9:
				System.exit(0);//프로그램 정상종료
	}
		
	}
	@Override
	public void countMenu() {
		System.out.println("-----------부서갯수조회----------");
		System.out.println("조회된 부서 수:"+dao.count());
	}
	@Override
	public void insertMenu() {
		System.out.println("-----------부서등록----------");
		System.out.print("부서코드:");
		String deptcode = key.next();
		System.out.print("부서명:");
		String deptname = key.next();
		System.out.print("부서전화번호:");
		String tel = key.next();
		System.out.print("주소:");
		String addr = key.next();
		
		DeptDTO dept = new DeptDTO(deptcode,deptname,tel,addr);
		int result = dao.insert(dept);
		System.out.println(result+"개 부서 등록완료");
	}
	@Override
	public void updateMenu() {
		System.out.println("*******부서 전화번호 및 주소 수정********");
		System.out.print("정보를 변경할 부서코드:");
		String deptcode = key.next();
		System.out.print("변경할 전화번호:");
		String tel = key.next();
		System.out.print("변경할 주소:");
		String addr = key.next();
		DeptDTO dept = new DeptDTO(deptcode,null,tel,addr);
		int result = dao.update(dept);
		System.out.println(result+"개 수정완료");
	}
	@Override
	public void deleteMenu() {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void showAllMenu() {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void showDeptInfo() {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void findByDept() {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void getMemberList() {
		// TODO Auto-generated method stub
		
	}
}

DeptSystem

public class DeptSystem {
	public static void main(String[] args) {
		ApplicationContext factory = 
			 new ClassPathXmlApplicationContext("/config/dept.xml");
		AbstractUI ui = (AbstractUI)factory.getBean("deptservice");
		while(true){
			ui.show();
		}
	}
}

본 포스팅은 멀티캠퍼스의 멀티잇 백엔드 개발(Java)의 교육을 수강하고 작성되었습니다.

0개의 댓글