Spring JdbcTemplate中關(guān)于RowMapper的使用實(shí)例

在上一節(jié)的《Spring JdbcTemplate使用實(shí)例》中,我們?cè)诓樵?xún)返回對(duì)象的時(shí)候,使用了匿名類(lèi)來(lái)創(chuàng)建對(duì)象,看上去非常地不友好,代碼顯得很是冗長(zhǎng)難懂。那么本文就來(lái)先解釋下什么是Row Mapper,我們?cè)撊绾握_地使用。

    @Override
    public Student getStudentByName(String name) {
        String sql = "select name, gender from test_student where name = ?";
        Student student = this.jdbcTemplate.queryForObject(sql, new Object[]{name}, new RowMapper<Student>() {
            @Override
            public Student mapRow(ResultSet rs, int i) throws SQLException {
                Student s = new Student();
                s.setName(rs.getString("name"));
                s.setGender(rs.getString("gender"));
                return s;
            }
        });
        return student;
    }
    @Override
    public List<Student> getStudentsByName(String name) {
        String sql = "select name, gender from test_student where name = ?";
        List<Student> students = this.jdbcTemplate.query(sql, new Object[]{name}, new RowMapper<Student>() {
            @Override
            public Student mapRow(ResultSet rs, int i) throws SQLException {
                Student s = new Student();
                s.setName(rs.getString("name"));
                s.setGender(rs.getString("gender"));
                return s;
            }
        });
        return students;
    }

一、RowMapper的基本使用

使用過(guò)原生JDBC的朋友應(yīng)該知道,從數(shù)據(jù)庫(kù)查詢(xún)出來(lái)的記錄全都被保存在ResultSet結(jié)果集中,我們需要將結(jié)果集中的數(shù)據(jù)一條條地獲取并設(shè)置到具體的實(shí)體類(lèi)上,如此,該實(shí)體類(lèi)才能在接下來(lái)的程序中使用。然而問(wèn)題是,每次都要這么操作實(shí)在是太麻煩了,Spring就不應(yīng)該提供什么功能來(lái)替我們做這些事情嗎?答案當(dāng)然是有的,那就是本文的主角——RowMapper。

Spring JDBC中目前有兩個(gè)主要的RowMapper實(shí)現(xiàn),使用它們應(yīng)該能解決大部分的場(chǎng)景了。

1.1 SingleColumnRowMapper

通過(guò)名字我們就能大概了解,在查詢(xún)返回單列數(shù)據(jù)的時(shí)候,就該使用這個(gè)RowMapper,下面我們來(lái)看看具體的代碼:

    @Override
    public String getStudentNameById(String id) {
        String sql = "select name from test_student where id = ?";
        return this.jdbcTemplate.queryForObject(sql, new Object[]{id},
                new SingleColumnRowMapper<>(String.class));
    }

    @Override
    public List<String> getStudentNamesByGrade(Integer grade) {
        String sql = "select name from test_student where grade = ?";
        return this.jdbcTemplate.query(sql, new Object[]{grade},
                new SingleColumnRowMapper<>(String.class));
    }
    @Test
    public void getStudentNameById(){
        String name = studentService.getStudentNameById("3");
        assertEquals("李清照", name);
    }

    @Test
    public void getStudentNamesByGrade(){
        List<String> names = studentService.getStudentNamesByGrade(1);
        assertTrue(2 == names.size());
    }

1.2 BeanPropertyRowMapper

當(dāng)查詢(xún)數(shù)據(jù)庫(kù)返回的是多列數(shù)據(jù),且你需要將這些多列數(shù)據(jù)映射到某個(gè)具體的實(shí)體類(lèi)上,那么就該使用這個(gè)Row Mapper,下面是具體的使用代碼:

    @Override
    public Student getStudentByName2(String name) {
        String sql = "select name, gender from test_student where name = ?";
        return this.jdbcTemplate.queryForObject(sql, new Object[]{name},
                new BeanPropertyRowMapper<>(Student.class));
    }

    @Override
    public List<Student> getStudentsByName2(String name) {
        String sql = "select name, gender from test_student where name = ?";
        return this.jdbcTemplate.query(sql, new Object[]{name},
                new BeanPropertyRowMapper<>(Student.class));
    }
    @Test
    public void getStudentByName2(){
        Student student = studentService.getStudentByName2("杜甫");
        assertEquals("杜甫",student.getName());
        assertEquals("男",student.getGender());
    }

    @Test
    public void getStudentsByName2(){
        List<Student> studentList = studentService.getStudentsByName("Jack");
        assertTrue(2 == studentList.size());
    }

這種使用方式有一個(gè)前提,那就是數(shù)據(jù)庫(kù)SQL查出來(lái)的數(shù)據(jù)其列名與實(shí)體類(lèi)中的屬性名是一致的,當(dāng)然個(gè)數(shù)和順序可以不一致。比如數(shù)據(jù)庫(kù)SQL查出來(lái)的姓名列叫name,那么對(duì)應(yīng)的實(shí)體類(lèi)中的姓名也必須叫name,而不能叫studentName或者其它。

二、定義自己的RowMapper

當(dāng)然,如果你SQL查詢(xún)出來(lái)的數(shù)據(jù)列名就是和實(shí)體類(lèi)的屬性名不一樣,或者想按照自己的規(guī)則來(lái)裝配實(shí)體類(lèi),那么就可以定義并使用自己的Row Mapper。

public class StudentRowMapper implements RowMapper<Student> {

    @Override
    public Student mapRow(ResultSet rs, int i) throws SQLException {
        Student student = new Student();
        student.setName(rs.getString("name"));
        student.setGender(rs.getString("gender"));
        student.setEmail(rs.getString("email"));
        return student;
    }
}
    @Override
    public Student getStudentByName3(String name) {
        String sql = "select name, gender, email from test_student where name = ?";
        return this.jdbcTemplate.queryForObject(sql, new Object[]{name}, new StudentRowMapper());
    }

    @Override
    public List<Student> getStudentsByName3(String name) {
        String sql = "select name, gender, email from test_student where name = ?";
        return this.jdbcTemplate.query(sql, new Object[]{name}, new StudentRowMapper());
    }
    @Test
    public void getStudentByName3(){
        Student student = studentService.getStudentByName3("杜甫");
        assertEquals("杜甫",student.getName());
        assertEquals("男",student.getGender());
        assertEquals("dufu@tang", student.getEmail());
    }

    @Test
    public void getStudentsByName3(){
        List<Student> studentList = studentService.getStudentsByName3("李白");
        assertTrue(2 == studentList.size());
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容