Spring-JdbcTemplate的使用

1. JdbcTemplate介紹

它是 spring 框架中提供的一個對象,是對原始 Jdbc API 對象的簡單封裝。
持久層總圖

2. 環境搭建

添加依賴

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.1.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.15</version>
        </dependency>

3. 使用JdbcTemplate完成CRUD操作

首先要創建一個JdbcTemplate對象,構造方法有兩種選擇,空參構造和傳入DataSource構造。空參構造需要在創建對象後使用JdbcTemplate的setDataSource方法設置數據源後纔可以使用。

    public JdbcTemplate() {
    }

    public JdbcTemplate(DataSource dataSource) {
        this.setDataSource(dataSource);
        this.afterPropertiesSet();
    }

數據源可以選用spring自帶的org.springframework.jdbc.datasource.DriverManagerDataSource
(1)查詢所有用戶
public List query(String sql,@NotNull RowMapper rowMapper,Object…args)
實現方式一: 自己實現RowMapper接口,在mapRow方法中定義數據庫中的每一行數據封裝到實體類中的邏輯。
應用場景:實體類屬性名與數據庫字段名不相同。

    public List<User> findAll() {
        return jt.query("select * from user", new RowMapper<User>() {
            public User mapRow(ResultSet resultSet, int i) throws SQLException {
                User user = new User();
                user.setId(resultSet.getInt("id"));
                user.setSex(resultSet.getString("sex"));
                user.setBirthday(resultSet.getDate("birthday"));
                user.setUsername(resultSet.getString("username"));
                return user;
            }
        });
    }

實現方式二: 使用spring爲我們提供的實現類BeanPropertyRowMapper
應用場景:實體類屬性名與數據庫字段名相同

    public List<User> findAll() {
        return jt.query("select * from user", new BeanPropertyRowMapper<User>(User.class));
    }

(2)查詢單個用戶
使用 查詢所有用戶 的實現方式二

    public User findOne(Integer id) {
      List<User> users= 
      jt.query("select * from user where id = ?",new BeanPropertyRowMapper<User>(User.class),id);
        return users.isEmpty() ? null : users.get(0);
    }

(3)保存,更新,刪除用戶
public int update(String sql,@Nullable Object… args)

   public void saveUser(User user) {
        jt.update("insert into user(username,sex,birthday) values(?,?,?)",
                user.getUsername(),
                user.getSex(),
                user.getBirthday());
    }

    public void updateUser(User user) {
        jt.update("update user set username = ?,sex = ?,birthday = ? where id = ?",
                user.getUsername(),
                user.getSex(),
                user.getBirthday(),
                user.getId());
    }

    public void deleteUser(Integer id) {
        jt.update("delete from user where id = ?", id);
    }

(4)查詢總記錄數
public T queryForObject(String sql,Class requiredType,@Nullable Object… args)

    public int findTotal() {
        return jt.queryForObject("select count(*) from user", Integer.class);
    }

4. 使用spring的ioc完成對UserDao中JdbcTemplate對象的注入

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--配置userDao-->
    <bean id="userDao" class="cn.itcast.dao.impl.UserDaoImpl">
        <property name="jt" ref="jdbcTemplate"></property>
    </bean>
    <!--配置JdbcTemplate-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" scope="prototype">
        <constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
    </bean>
    <!--配置數據源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/dbtest?serverTimezone=UTC"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
</beans>

4. JdbcDaoSupport的使用

userDao中的JdbcTemplate對象是採用set方法注入的,所以需要寫setter方法。
如果有多個dao實現類,那麼類中都要定義一個JdbcTemplate對象以及編寫其setter方法。這種重複性的工作spring早已想到辦法幫我們解決了。只要每個dao實現類都繼承JdbcDaoSupport,然後再爲每個dao實現類注入一個數據源,就可以直接獲取JdbcTemplate對象並使用了。

public class UserDaoImpl extends JdbcDaoSupport implements UserDao {

    public List<User> findAll() {
        return super.getJdbcTemplate().query("select * from user", 
                new BeanPropertyRowMapper<User>(User.class));
    }

}

spring-config.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--配置userDao-->
    <bean id="userDao" class="cn.itcast.dao.impl.UserDaoImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--配置數據源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/dbtest?serverTimezone=UTC"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
</beans>

JdbcDaoSupport是如何實現簡化我們書寫的?

public abstract class JdbcDaoSupport extends DaoSupport {
    @Nullable
    private JdbcTemplate jdbcTemplate;

    public final void setDataSource(DataSource dataSource) {
        if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) {
            this.jdbcTemplate = this.createJdbcTemplate(dataSource);
            this.initTemplateConfig();
        }

    }
    protected JdbcTemplate createJdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
    @Nullable
    public final JdbcTemplate getJdbcTemplate() {
        return this.jdbcTemplate;
    }

可以看到只要爲JdbcDaoSupport注入一個數據源,它就會判斷當前對象是否有jdbcTemplate對象或者數據源是否更換,如果沒有jdbcTemplate對象或者數據源更換,它就會創建一個新的jdbcTemplate對象。那麼dao實現類繼承它,自然可以使用getJdbcTemplate方法來獲取jdbcTemplate對象並使用。

5. 什麼時候選擇JdbcDaoSupport?

基於註解的配置的時候,會使用@Repository註解把dao實現類對象加入到IOC容器中,這樣我們就無法通過配置xml的方式爲dao實現類對象注入數據源了。沒有數據源就無法使用jdbcTemplate對象,此時繼承JdbcDaoSupport就沒意義了。
總結: spring基於註解開發時不要繼承JdbcDaoSupport,基於xml開發時可以讓dao實現類繼承JdbcDaoSupport來簡化我們的開發。

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Autowired
    private jdbcTemplate jt;

    public List<User> findAll() {
        return jt.query("select * from user", 
                new BeanPropertyRowMapper<User>(User.class));
    }

}
發佈了46 篇原創文章 · 獲贊 1 · 訪問量 2518
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章