기존 memory(map class) 방식에서 데이터를 DB에 생성하고 가져오는 방식으로 변경
jdbc로 연동하던 중 팅김(애러 원인... => 초기화를 MemoryMemberRepository로 잘못 지정함...
@Controller에서 생성자 호출 시 memberService를 통해 구현해야함(C->S->R)
@Controller
public class MemberController {
private MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
1. build.gradle 설정
DB연계를 위해서는 우선 DB 접속을 위한 library를 graddle에서 implement해야함
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-jdbc' // 추가
implementation 'mysql:mysql-connector-java' // 추가
}
jdbc는 자바에서 DB에 접속하기 위한 interface이고 mysql-connector는 연동하고자 하는 DB의 구현체로 DB 별로 구현체가 다르므로 검색해서 추가해야함.
JPA 사용을 위한 추가 설정
// implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
2. application.properties 설정
C:\study\hello-spring\src\main\resources\application.properties
DB 연결을 위한 driver-class-name, datasource.url, username, password 등을 설정해야함
(여기서 설정하면 실제 class에서 사용할때 지정하지 않아도됨 :
- Connection conn; 연결을 위한 객체를 spring에서 생성해줌)
# MySQL
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# DB Source URL
spring.datasource.url=jdbc:mysql://localhost:3306/memberservice
# DB username
spring.datasource.username=kalpa
# DB password
spring.datasource.password=dongwook0#
JPA 구현을 위한 추가 설정
# true 설정시 JPA 쿼리문 확인 가능
#spring.jpa.show-sql=true
# DDL(create, alter, drop) 정의시 DB의 고유 기능을 사용할 수 있다.
#spring.jpa.hibernate.ddl-auto=update
# JPA의 구현체인 Hibernate가 동작하면서 발생한 SQL의 가독성을 높여준다.
#spring.jpa.properties.hibernate.format_sql=true
3. JPA 없이 jdbc 만을 이용해서 DB CRUD 구현하기
DB 연동 시험(잘되면 java와 db간 연동은 되는 것임)
@SpringBootApplication
public class HelloSpringApplication {
public static void main(String[] args) {
SpringApplication.run(HelloSpringApplication.class, args);
try {
// MySQL DB용 드라이로드
Class.forName("com.mysql.cj.jdbc.Driver");
// DB연결
Connection conn =
DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/db이름", "아이디", "패스워드");
System.out.println("mysql db 연결 성공");
conn.close();
System.out.println("mysql 연결해제 성공");
}
catch(ClassNotFoundException error) {
System.out.println("mysql driver 미설치 또는 드라이버 이름 오류");
}
catch(SQLException error) {
System.out.println("DB접속오류");
}
}
}
Spring을 이용해서 기존의 MemoryRepository를 JdbcRepository로 변경해서 구현함
(기존 코드는 변경없이 Spring DI 구성만 변경해서 구현)
@Configuration
public class SpringConfig {
DataSource dataSource;
@Autowired
public SpringConfig(DataSource dataSource) {
this.dataSource = dataSource;
}
@Bean
public MemberService memberService(){
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository(){
// return new MemoryMemberRepository();
return new JdbcMemberRepository(dataSource);
}
}
다소 복잡하지만 jdbc만을 이용해서 DB연계 후에 데이터 가져오는 코드....
public class JdbcMemberRepository implements MemberRepository{
private final DataSource dataSource;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
public JdbcMemberRepository(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public void save(Member member) throws ClassNotFoundException {
String sql = "insert into member(name) values(?)";
try {
conn = getConnection();// 위에서 설정한 값으로 db와 연결을 생성해줌
pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
pstmt.setString(1, member.getName());
pstmt.executeUpdate();
rs = pstmt.getGeneratedKeys();
if (rs.next()) {
member.setId(rs.getLong(1));
} else {
throw new SQLException("id 조회 실패");
}
} catch (Exception e) {
throw new IllegalStateException(e);
} finally {
close(conn, pstmt, rs);
}
}
@Override
public Optional<Member> findById(Long id) throws ClassNotFoundException {
String sql = "select * from member where id = ?";
try {
conn = getConnection();// 위에서 설정한 값으로 db와 연결을 생성해줌
pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
pstmt.setString(1, String.valueOf(id));
rs = pstmt.executeQuery();
if (rs.next()) {
Member member = new Member();
member.setId(rs.getLong("id"));//db의 실제 컬럼 이름
member.setName(rs.getString("name"));//db의 실제 컬럼 이름
member.setRegDate(rs.getTimestamp("regdate")); //db의 실제 컬럼 이름
return Optional.of(member);
} else {
return Optional.empty();
}
} catch (Exception e) {
throw new IllegalStateException(e);
}finally {
close(conn, pstmt, rs);
}
}
@Override
public Optional<Member> findByName(String name) throws ClassNotFoundException {
String sql = "select * from member where name = ?";
try {
conn = getConnection(); // 위에서 설정한 값으로 db와 연결을 생성해줌
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, name);
rs = pstmt.executeQuery();
if (rs.next()) {
Member member = new Member();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
member.setRegDate(rs.getTimestamp("regdate"));
return Optional.of(member);
} else {
return Optional.empty();
}
} catch (Exception e) {
throw new IllegalStateException(e);
} finally {
close(conn, pstmt, rs);
}
}
@Override
public List<Member> findAll() throws ClassNotFoundException {
String sql = "select * from member";
try {
conn = getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
List<Member> members = new ArrayList<>();
while (rs.next()) {
Member member = new Member();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
member.setRegDate(rs.getTimestamp("regdate"));
members.add(member);
}
return members;
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
close(conn, pstmt, rs);
}
}
private Connection getConnection(){
return DataSourceUtils.getConnection(dataSource);
}
private void close(Connection conn, PreparedStatement pstmt, ResultSet rs) {
try{
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
try{
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
private void close(Connection conn) throws SQLException{
DataSourceUtils.releaseConnection(conn, dataSource);
}
}
findbyName으로 맴버를 찾는 것.. 잘 안되다가 겨우 됨
(html form action에 링크 수정하고, Optional에 대해서 isPresent로 검토하고...되내.. 쩜 3시간 삽질)
@GetMapping("/members/member")
public String memberByIdForm(){
return "members/findOne";
}
// @PostMapping("/members/member")
// public String findOne(MemberForm form) throws ClassNotFoundException {
//
// Optional<Member> oneMember = memberService.findByName(form.getMemberName());
// System.out.println("찾은 member : "+oneMember);
// System.out.println("form name: " +form.getMemberName());
//
// Member member = oneMember.get();
//
// return "redirect:/members/oneMember";
//// return "redirect:/members/oneMember.html";
//// return "members/memberOneByName";
// }
@PostMapping("/members/oneMember")
public String list(Model model,MemberForm form) throws ClassNotFoundException {
Optional<Member> memberName = memberService.findByName(form.getMemberName());
if (memberName.isPresent()) {
Member member = memberName.get();
model.addAttribute("member", member);
} else {
return "members/findOne";
}
return "members/oneMember";
}
'Spring > spring_old' 카테고리의 다른 글
07./ Spring Web MVC-DB연계-JPA (0) | 2023.01.13 |
---|---|
07./ Spring Web MVC-DB연계-jdbc template (0) | 2023.01.13 |
06./ Spring Web MVC (0) | 2023.01.12 |
05./ Spring -Member-03-Bean 등록-Dependency Injection (0) | 2023.01.12 |
05./ Spring excersise-Member-02-service (0) | 2023.01.12 |