Jdbc(Java DataBase Connectivity) Template


コースの出所-金英漢講師
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8

オープンクローズの原則

  • If we wanna implement other repository, we can just replace the return type with the new repository type without any correction of existing repository file.
  • @Configuration
    public class SpringConfig {
    
        // skipped parts(D.I parts from Spring Container)
        
        @Bean
        public MemberRepository memberRepository() {
            // return new MemoryMemberRepository();
            return new JdbcTemplateMemberRepository(dataSource); // OCP(open-closed principle)
        }
    }

    Initalize JdbcTemplate

  • It should be initialized with dataSource injected from the SpringConfig.java file.
  • public class JdbcTemplateMemberRepository implements MemberRepository {
    
        private final JdbcTemplate jdbcTemplate;
    
        @Autowired // annotation may be skipped if there's only one constructor.
        public JdbcTemplateMemberRepository(DataSource dataSource) {
            jdbcTemplate = new JdbcTemplate(dataSource);
        }
        + Implementation of Interface as of here.
        .
        .
        .
    }

    SimpleJdbcInsert

  • Parameters Map's value should be Object class as a generic type.
  •  @Override
        public Member save(Member member) {
    
    	// initialize instance and set parameter.
            SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
            jdbcInsert.withTableName("member").usingGeneratedKeyColumns("id");
    
    	// Map parameters to pass in the actual execution.
            Map<String, Object> parameters = new HashMap<>(); // Object class as a generic type.
            parameters.put("name", member.getName());
    
            Number key = jdbcInsert.executeAndReturnKey(new MapSqlParameterSource(parameters));
            member.setId(key.longValue());
    
            return member;
        }

    findById(), findByName(), findAll()

    @Override
        public Optional<Member> findById(Long id) {
            List<Member> result = jdbcTemplate.query("select * from member where id = ?",
                    memberRowMapper(), id);
            return result.stream().findAny();
        }
    
        @Override
        public List<Member> findAll() {
            return jdbcTemplate.query("select * from member", memberRowMapper());
        }
    
        @Override
        public Optional<Member> findByName(String name) {
            List<Member> result = jdbcTemplate.query("select * from member where name = ?",
                    memberRowMapper(), name);
            return result.stream().findAny();
        }

    lambda of RowMapper Interface

    private RowMapper<Member> memberRowMapper() {
            return (rs, rowNum) -> {
                Member member = new Member();
                member.setId(rs.getLong("id"));
                member.setName(rs.getString("name"));
                return member;
            };
        }

    JdbcTemplateMemberRepository.java

    public class JdbcTemplateMemberRepository implements MemberRepository {
    
        private final JdbcTemplate jdbcTemplate;
    
        @Autowired // annotation may be skipped if there's only one constructor.
        public JdbcTemplateMemberRepository(DataSource dataSource) {
            jdbcTemplate = new JdbcTemplate(dataSource);
        }
    
        @Override
        public Member save(Member member) {
    
            SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
            jdbcInsert.withTableName("member").usingGeneratedKeyColumns("id");
    
            Map<String, Object> parameters = new HashMap<>(); // Object class as a generic type.
            parameters.put("name", member.getName());
    
            Number key = jdbcInsert.executeAndReturnKey(new MapSqlParameterSource(parameters));
            member.setId(key.longValue());
    
            return member;
        }
    
        @Override
        public Optional<Member> findById(Long id) {
            List<Member> result = jdbcTemplate.query("select * from member where id = ?",
                    memberRowMapper(), id);
            return result.stream().findAny();
        }
    
        @Override
        public List<Member> findAll() {
            return jdbcTemplate.query("select * from member", memberRowMapper());
        }
    
        @Override
        public Optional<Member> findByName(String name) {
            List<Member> result = jdbcTemplate.query("select * from member where name = ?",
                    memberRowMapper(), name);
            return result.stream().findAny();
        }
    
        private RowMapper<Member> memberRowMapper() {
            return (rs, rowNum) -> {
                Member member = new Member();
                member.setId(rs.getLong("id"));
                member.setName(rs.getString("name"));
                return member;
            };
        }
    }