Spring学习:JdbcTemplate

一、JDBC

        传统的JDBC代码如下所示:

    public static void main( String[] args )
    {
        Connection con = null; // 定义一个MYSQL链接对象
        PreparedStatement ps = null; // 语句对象
        ResultSet rs = null;
        String sql = "SELECT * FROM country where id = ?;"; //sql语句,?为参数
        try{
            //加载Mysql驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获取数据库连接对象
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useSSL=false", "root", ""); // 链接本地MYSQL
            //实例化PreparedStatement
            ps = con.prepareCall(sql);
            //设置参数
            ps.setInt(1,1);
            //执行sql
            rs = ps.executeQuery();
            //获取结果
            if(rs.next()){
                System.out.println(rs.getString(2));
            }
 
        }catch (ClassNotFoundException | SQLException e){
            e.printStackTrace();
        }finally {
            //释放资源
            try {
                if (ps != null) ps.close();
                if (con != null) con.close();
                if (rs != null) rs.close();
            } catch (SQLException ignored) {
 
            }
        }
    }

        操作数据库的传统方式是通过JDBC实现,如上述代码,我们实现一个查询数据库的操作。上述代码核心的其实只有一句:ps = con.prepareCall(sql); 其他的语句如加载数据库驱动、连接数据库、执行查询以及释放资源等操作都是模板代码,编写这些完全相同的代码,是对时间的浪费。

二、Spring中的JDBC

        上述使用传统JDBC操作数据库时,包含了大量与业务无关但又必须的代码。 Spring JDBC 通过模板和回调机制大大降低了使用JDBC 的复杂度,借由JdbcTemplate 的帮助,仅需要编写那些"必不可少"的代码就可以进行数据库操作。

        一般情况下都是在DAO类中使用JdbcTemplate JdbcTemplate 在XML配置文件中配置好后,直接在DAO 中注入即可

2.1 示例:

1)创建与数据库表Country对应的类对象:

public class Country {
    private int id;
    private String countryName;
    private String countryCode;

    public int getId() {
        return id;
    }

    public String getCountryName() {
        return countryName;
    }

    public String getCountryCode() {
        return countryCode;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setCountryName(String countryName) {
        this.countryName = countryName;
    }

    public void setCountryCode(String countryCode) {
        this.countryCode = countryCode;
    }
}

2)创建CountryDao接口,该接口规定了对数据库的操作

public interface CountryDao {
    /**
     * 新增一条用户
     *
     * @param country
     * @return
     */
    int addUer(Country country);

    /**
     * 更新指定的用户信息
     *
     * @param country
     * @return
     */
    int update(Country country);

    /**
     * 删除指定的信息
     *
     * @param country
     * @return
     */
    int delete(Country country);

    /**
     * 统计用户个数
     *
     * @param country
     * @return
     */
    int count(Country country);

    /**
     * 查询用户列表
     *
     * @param 
     * @return
     */
    List<Country> getList();

    /**
     * 查询单个用户信息
     *
     * @param country
     * @return
     */
    Country getUser(Country country);

    /**
     * 批量增加
     *
     * @param batchArgs
     */
    void batchAddCountry(List<Object[]> batchArgs);
}

3)创建CountryDao接口的实现类CountryDaoImpl:

public class CountryDaoImpl implements CountryDao{

    private JdbcTemplate jdbcTemplate; //属性,由Spring注入

    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public int addUer(Country country) {
        String sql = "INSERT INTO `country`(countryname,countrycode) VALUES(?,?);";
        int update = jdbcTemplate.update(sql,country.getCountryName(),country.getCountryCode());
        return update;
    }

    @Override
    public int update(Country country) {
        String sql = "UPDATE country SET countryname = ?,countrycode=?\n" +
                "WHERE id = ?;";
        int update = jdbcTemplate.update(sql,country.getCountryName(),country.getCountryCode(),country.getId());
        return update;
    }

    @Override
    public int delete(Country country) {
        String sql = "DELETE from country WHERE id = ?;";
        int update = jdbcTemplate.update(sql,country.getId());
        return update;
    }

    @Override
    public int count(Country country) {
        String sql ="SELECT COUNT(*) FROM country;";
        int count = jdbcTemplate.queryForObject(sql,Integer.class);
        return count;
    }


    @Override
    public List<Country> getList() {
        String sql = "SELECT * FROM country;";
        List<Country> countryList = jdbcTemplate.query(sql,new BeanPropertyRowMapper<Country>(Country.class));
        return countryList;
    }

    @Override
    public Country getUser(Country country) {
        String sql = "SELECT * FROM country WHERE id = ?;";
        Country country1 = jdbcTemplate.queryForObject(sql, new RowMapper<Country>() {
            @Override
            public Country mapRow(ResultSet resultSet, int i) throws SQLException {
                Country country2 = new Country();
                country2.setId(resultSet.getInt("id"));
                country2.setCountryName(resultSet.getString("countryname"));
                country2.setCountryCode(resultSet.getString("countrycode"));
                return country2;
            }
        }, country.getId());
        return country1;
    }

    @Override
    public void batchAddCountry(List<Object[]> batchArgs) {
    }
}

        我们可以看到,在创建的DAO类中,包含一个JdbcTemplate属性,所有数据库的增、删、查、改及存储过程等操作, 都是通过JdbcTemplate 提供的众多方法实现的。        

        Spring框架中,我们可以通过XML配置文件配置好JdbcTemplate ,然后直接在DAO 中注入即可。

4)配置文件配置JdbcTemplate:

DriverManagerDataSource数据源配置:

<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 配置数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!-- 属性注入 -->
        <!-- 数据库驱动 -->
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <!-- 连接数据库url -->
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false"></property>
        <!-- 数据库名称 -->
        <property name="username" value="root"></property>
        <!-- 数据库密码 -->
        <property name="password" value="root"></property>
    </bean>

    <!-- 配置jdbc模板 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!-- 配置数据源属性 -->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <bean id="countryDao" class="com.wyf.springjdbc.CountryDaoImpl">
        <!-- 注入属性 -->
        <property name="jdbcTemplate" ref="jdbcTemplate"></property>
    </bean>

</beans>

C3P0数据源配置:

<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 配置数据源 -->
<!--    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">-->
<!--        &lt;!&ndash; 属性注入 &ndash;&gt;-->
<!--        &lt;!&ndash; 数据库驱动 &ndash;&gt;-->
<!--        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>-->
<!--        &lt;!&ndash; 连接数据库url &ndash;&gt;-->
<!--        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false"></property>-->
<!--        &lt;!&ndash; 数据库名称 &ndash;&gt;-->
<!--        <property name="username" value="root"></property>-->
<!--        &lt;!&ndash; 数据库密码 &ndash;&gt;-->
<!--        <property name="password" value="wyfroot"></property>-->
<!--    </bean>-->

    <!-- 配置数据源(C3P0) -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <!-- 属性注入 -->
        <property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false"></property>
        <property name="user" value="root"></property>
        <property name="password" value="wyfroot"></property>

        <!-- C3P0其他属性设置 -->
        <!--连接池中保留的最小连接数。 -->
        <property name="minPoolSize" value="10" />
        <!--连接池中保留的最大连接数。Default: 15 -->
        <property name="maxPoolSize" value="100" />
        <!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
        <property name="maxIdleTime" value="1800" />
        <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
        <property name="acquireIncrement" value="3" />
        <property name="maxStatements" value="1000" />
        <property name="initialPoolSize" value="10" />
        <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
        <property name="idleConnectionTestPeriod" value="60" />
        <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
        <property name="acquireRetryAttempts" value="30" />
        <property name="breakAfterAcquireFailure" value="true" />
        <property name="testConnectionOnCheckout" value="false" />
    </bean>

    <!-- 配置jdbc模板 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!-- 配置数据源属性 -->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <bean id="countryDao" class="com.wyf.springjdbc.CountryDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"></property>
    </bean>
</beans>

5)测试代码

    @Test
    public void JdbcTemplateTest2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("Bean.xml");
        CountryDaoImpl countryDao = (CountryDaoImpl)context.getBean("countryDao");

        Country country = new Country();
        country.setId(17);
        country.setCountryName("CUBA");
        country.setCountryCode("CU");

        System.out.println("查询数量:"+countryDao.count(country));
        System.out.println("插入一条数据:"+countryDao.addUer(country));
        country.setCountryCode("FJ");
        country.setCountryName("Fiji");
        System.out.println("更改数据:"+countryDao.update(country));
        Country country_t = countryDao.getUser(country);
        System.out.println("获取到的对象名称:"+country_t.getCountryName());

        List<Country> countryList = countryDao.getList();
        System.out.println("获取到的对象数量:"+countryList.size());
    }

2.2 RowMapper

        使用JDBC从数据库查询数据时,查询出来的结果都被记录在ResultSet结果集中,而在Java程序中,我们需要获取结果集中一条条数据,并对应到具体的JavaBean上(ORM思想)。然而,数据库表中的字段和JavaBean类中的属性应该如何对应呢?RowMapper接口可以为我们解决这个问题。

如下所示,将ResultSet查询到的数据和JavaBean对应起来:

    @Override
    public Country getUser(Country country) {
        String sql = "SELECT * FROM country WHERE id = ?;";
        Country country1 = jdbcTemplate.queryForObject(sql, new RowMapper<Country>() {
            @Override
            public Country mapRow(ResultSet resultSet, int i) throws SQLException {
                Country country2 = new Country();
                country2.setId(resultSet.getInt("id"));
                country2.setCountryName(resultSet.getString("countryname"));
                country2.setCountryCode(resultSet.getString("countrycode"));
                return country2;
            }
        }, country.getId());
        return country1;
    }

BeanPropertyRowMapper类:

        BeanPropertyRowMapper类是RowMapper的一个实现类,它可以自动将一行数据映射到指定类的实例中,它首先将这个类实例化,然后通过名称匹配的方式,映射到属性中去,如果某个属性不匹配则返回属性值为Null。

        这种自动绑定的方式,需要列名称和Java实体类中属性名称一致。所以,如果在使用时,Java类名称要想和数据库字段名称匹配上,必须要把数据库字段名称设计成以下两种中的一种:

  • 数据库字段名设计成全小写的形式,如myname;
  • 数据库字段名设计成下划线分割的形式,如my_name;

        同时,Java属性名称应该尽量遵循Java编码风格,使用camelCase风格,如myName。如果数据中列名和属性名不一致,在sql语句中需要用as重新取一个别名。

示例代码如下:

    public List<Country> getList() {
        String sql = "SELECT * FROM country;";
        List<Country> countryList = jdbcTemplate.query(sql,new BeanPropertyRowMapper<Country>(Country.class));
        return countryList;
    }
    public Country getUser(Country country) {
        String sql = "SELECT * FROM country WHERE id = ?;";
//        Country country1 = jdbcTemplate.queryForObject(sql, new RowMapper<Country>() {
//            @Override
//            public Country mapRow(ResultSet resultSet, int i) throws SQLException {
//                Country country2 = new Country();
//                country2.setId(resultSet.getInt("id"));
//                country2.setCountryName(resultSet.getString("countryname"));
//                country2.setCountryCode(resultSet.getString("countrycode"));
//                return country2;
//            }
//        }, country.getId());
        Country country1 = jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<Country>(Country.class),country.getId());
        return country1;
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值