Spring系列第8篇:Spring中的JdbcTemplate

文章目录

  • 一、JdbcTemplate的概述
    • 1.概述
    • 2.JdbcTemplate的作用
    • 3.如何创建改对象
    • 4.对象中常用的方法
    • 5.JdbcDaoSupport的使用和Dao的两种编写方式
    • 6.持久层图和数据源
  • 二、数据源
    • Java中的数据源和创建方式

一、JdbcTemplate的概述

1.概述

它是spring框架中提供的一个对象,是对原始JDBC API对象的简单封装。
spring还提供了很多的操作模板类:
操作关系型数据的:JdbcTemplate,HibernateTemplate
操作nosql数据库的:RedisTemplate
操作消息队列的:JmsTemplate

2.JdbcTemplate的作用

它就是用于和数据库交互的,实现对表的crud操作

3.如何创建改对象

依赖:

    <dependencies>
    	<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
    </dependencies>
/**
 * jdbctemplate最基本的用法
 */
public class JdbcTemplateDemo1 {
    public static void main(String[] args) {
        //准备数据源:spring内置数据源
        DriverManagerDataSource db = new DriverManagerDataSource();
        db.setDriverClassName("com.mysql.jdbc.Driver");
        db.setUrl("jdbc:mysql://localhost:3307/test");
        db.setUsername("liming");
        db.setPassword("liming");
        //1.创建jdbctemplate对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(db);
        //2.执行插入操作
        jdbcTemplate.execute("insert into account(name,money) values ('gg',100)");
    }
}
<?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">
    <!--配置账户的持久层-->
    <bean id="accountDao" class="com.ming.dao.dbcteplate.impl.AccountDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"></property>
    </bean>
    <!--配置jdbcTemplate-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--配置spring内置数据源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3307/test"></property>
        <property name="username" value="liming"></property>
        <property name="password" value="liming"></property>
    </bean>
</beans>
public class JdbcTemplateDemo2 {
    @Test
    public void jdbcTemplateTest() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("jdbcTemplate.xml");
        JdbcTemplate jt = ac.getBean("jdbcTemplate", JdbcTemplate.class);
        jt.execute(" insert into account(name,money) values('hh',500)");
    }
}

4.对象中常用的方法

JdbcTemplate的CRUD:
1.测试用

package com.ming.test.jdbctemplate;

import com.ming.model.Account;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * jdbcTemplate的CRUD
 */
public class JdbcTemplateDemo3 {
    @Test
    public void jdbcTemplateTest() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("jdbcTemplate.xml");
        JdbcTemplate jt = ac.getBean("jdbcTemplate", JdbcTemplate.class);
        //保存
        //jt.update(" insert into account(name,money) values(?,?)","lm",200f);
        //更新
        //jt.update("update account set name =?,money =? where id=? ","xl",1f,8);
        //删除
        //jt.update("delete from account  where id=? ",8);
        //查询所有
        //List accountList = jt.query("select * from account where money > ? ",new AccountRowMapeer(),10f);
//        List accountList = jt.query("select * from account where money > ? ",new BeanPropertyRowMapper<>(Account.class),10f);
//        for (Account list : accountList){
//            System.out.println(list);
//        }
        //查询一个
//        List accountList = jt.query("select * from account where id = ? ",new BeanPropertyRowMapper<>(Account.class),1);
//        System.out.println(accountList.isEmpty()?"null":accountList.get(0));
        //查询返回一行一列(使用聚合函数,但不加group by子句)
        int count = jt.queryForObject("select count(*) from account where money > ? ", Integer.class, 100f);
        System.out.println(count);
    }

    /**
     * 定义封装account
     */
    class AccountRowMapeer implements RowMapper<Account> {

        @Override
        public Account mapRow(ResultSet resultSet, int rowNum) throws SQLException {
            Account account = new Account();
            account.setId(resultSet.getInt("id"));
            account.setName(resultSet.getString("name"));
            account.setMoney(resultSet.getFloat("money"));
            return account;
        }
    }
}

2.实际开发中:
持久层接口

package com.ming.dao.dbcteplate;

import com.ming.model.Account;

/**
 * 基于jdbcTemplate的持久层
 */
public interface IAccountDao {

    /**
     * 根据id查询账户
     * @param accountId
     * @return
     */
    Account findAccountById(Integer accountId);

    /**
     * 根据账户名称查询账户
     * @param accountName
     * @return
     */
    Account findAccountByName(Integer accountName);
    /**
     * 更新账户
     * @param account
     */
    void updateAcocount(Account account);
}

持久层实现类

package com.ming.dao.dbcteplate.impl;

import com.ming.dao.dbcteplate.IAccountDao;
import com.ming.model.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

/**
 * 基于jdbcTemplate的账户持久层实现类
 */
public class AccountDaoImpl implements IAccountDao {

    private JdbcTemplate jdbcTemplate;

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

    @Override
    public Account findAccountById(Integer accountId) {
        List<Account> accountList = jdbcTemplate.query("select * from account where id = ? ",new BeanPropertyRowMapper<Account>(Account.class),accountId);
        return accountList.isEmpty()?null:accountList.get(0);
    }

    @Override
    public Account findAccountByName(Integer accountName) {
        List<Account> accountList = jdbcTemplate.query("select * from account where name = ? ",
                new BeanPropertyRowMapper<Account>(Account.class),accountName);
        if(accountList.isEmpty()){
            return null;
        }
        if(accountList.size() > 1){
             throw new RuntimeException("结果集不为1");
        }
        return  accountList.get(0);
    }

    @Override
    public void updateAcocount(Account account) {
        jdbcTemplate.update("update account set name = ? , money = ? where id = ? ",account.getName(),account.getMoney(),account.getId());
    }
}

测试

public class JdbcTemplateDemo3 {
    @Test
    public void jdbcTemplateDaoTest(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("jdbcTemplate.xml");
        IAccountDao accountDao = ac.getBean("accountDao", IAccountDao.class);
        Account account = accountDao.findAccountById(7);
        System.out.println(account);
        account.setMoney(959f);
        accountDao.updateAcocount(account);
    }
}

5.JdbcDaoSupport的使用和Dao的两种编写方式

1.JdbcDaoSupport的使用
第一种方式:抽取持久层dao,写一个类JdbcDaoSupport用于让dao的实现类继承

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">
    <!--配置账户的持久层-->
    <bean id="accountDao" class="com.ming.dao.dbcteplate.impl.AccountDaoImpl">
       <!-- <property name="jdbcTemplate" ref="jdbcTemplate"></property>-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--配置jdbcTemplate-->
<!--    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">-->
<!--        <property name="dataSource" ref="dataSource"></property>-->
<!--    </bean>-->
    <!--配置spring内置数据源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3307/test"></property>
        <property name="username" value="liming"></property>
        <property name="password" value="liming"></property>
    </bean>
</beans>
package com.ming.dao.dbcteplate.impl;

import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

/**
 * 此类用于抽取dao层中的重复代码
 */
public class JdbcDaoSupport {

    private JdbcTemplate jdbcTemplate;

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

    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }

    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        //this.dataSource = dataSource;
        if(jdbcTemplate == null){
            jdbcTemplate = createJdbcTemplate(dataSource);
        }
    }

    private JdbcTemplate createJdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

package com.ming.dao.dbcteplate.impl;

import com.ming.dao.dbcteplate.IAccountDao;
import com.ming.model.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;

import java.util.List;

/**
 * 基于jdbcTemplate的账户持久层实现类
 */
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {

    @Override
    public Account findAccountById(Integer accountId) {
        List<Account> accountList = super.getJdbcTemplate().query("select * from account where id = ? ",new BeanPropertyRowMapper<Account>(Account.class),accountId);
        return accountList.isEmpty()?null:accountList.get(0);
    }

    @Override
    public Account findAccountByName(Integer accountName) {
        List<Account> accountList = super.getJdbcTemplate().query("select * from account where name = ? ",
                new BeanPropertyRowMapper<Account>(Account.class),accountName);
        if(accountList.isEmpty()){
            return null;
        }
        if(accountList.size() > 1){
             throw new RuntimeException("结果集不为1");
        }
        return  accountList.get(0);
    }

    @Override
    public void updateAcocount(Account account) {
        super.getJdbcTemplate().update("update account set name = ? , money = ? where id = ? ",account.getName(),account.getMoney(),account.getId());
    }
}

2.Dao的两种编写方式
如果不自己写第一种方式JdbcDaoSupport用spring的只要继承就行,spring会自动导入:
import org.springframework.jdbc.core.support.JdbcDaoSupport;
继续JdbcDaoSupport的作用:去除dao的注入和定义的重复代码
区别:如果自己编写的类用@Autowired private JdbcTemplate jdbcTemplate;可以使用
但是只要继承spring的JdbcDaoSupport在jar上加上注解就比较难实现

6.持久层图和数据源

Spring系列第8篇:Spring中的JdbcTemplate_第1张图片

二、数据源

Java中的数据源和创建方式

javax.sql.DataSource。DataSource的创建可以有不同的实现。

JNDI方式创建DataSource

以JNDI方式创建数据源首先要配置数据源的相关连接信息,也就是数据源连接池。该配置应该在Tomcat安装目录下的conf/context.xml文件中配置。其配置如下:


……

       type="javax.sql.DataSource"maxActive="100" maxIdle="30"

       maxWait="10000"username="root" password="root"

       driverClassName="com.mysql.jdbc.Driver"

       url="jdbc:mysql://localhost:3306/cheng"/>

……

然后,在程序中以JNDI的方式创建数据源,得到数据库连接已进行相应的操作。代码如下:

// 初始化JNDI上下文,创建DataSource对象

Context initContext = new InitialContext();

Context context = (Context)initContext.lookup("java:comp/env");

DataSourcedataSource =  (DataSource)context.lookup("jdbc/NutzDemo");

Apache提供的简单连接池创建数据源

以这种方式创建数据源必须先准备两个jar文件:commons-dbcp.jar 和 commons-pool.jar。

以这种方式创建的数据源就不再是javax.sql.DataSource。DataSource了,而是org.apache.commons.dbcp.BasicDataSource。而且不再需要配置任何文件就可以直接使用。代码如下:

创建BasicDataSource对象

BasicDataSource ds = new BasicDataSource();

ds.setDriverClassName("com.mysql.jdbc.Driver");

ds.setUrl("jdbc:mysql://localhost:3306/test");

ds.setUsername("root");

ds.setPassword("root");

ds.setInitialSize(50);

ds.setMaxActive(100);

ds.setMaxIdle(30);

ds.setMaxWait(10000);

// 关闭数据源连接
ds.close();

C3P0方式创建数据源

使用C3P0方式创建数据源应该首先准备一个jar文件:c3p0-0.9.1.2.jar,将其放到web/lib目录下,就可以在项目中使用C3P0创建数据源,C3P0创建的数据源对象也不是DataSource对象,而是ComboPooledDataSource,代码如下:

// 创建ComboPooledDataSource对象

ComboPooledDataSource ds = new ComboPooledDataSource();

ds.setDriverClass("com.mysql.jdbc.Driver");

ds.setJdbcUrl("jdbc:mysql://localhost:3306/test");

ds.setUser("root");

ds.setPassword("root");

ds.setInitialPoolSize(50);

ds.setMaxPoolSize(100);

ds.setMaxIdleTime(10000);

Proxool方式创建数据源

应该准备的jar文件为:proxool-01.9.0RC3.jar,之后在项目中创建ProxoolDataSource对象,其代码如下:

// 创建ProxoolDataSource对象

ProxoolDataSource ds = new ProxoolDataSource();

ds.setDriver("com.mysql.jdbc.Driver");

ds.setDriverUrl("jdbc:mysql://localhost:3306/cheng");

ds.setUser("root");

ds.setPassword("root");

BoneCP方式创建数据源

BoneCP是一个快速高效,开源免费的Java数据库接池。

创作者称,BoneCP在性能上会完全超越所有主流的Java连接池。它可以帮你管理数据连接,让你的应用程序能更快速地访问数据库。比C3P0/DBCP(DataBaseconnection pool,数据库连接池)连接池快25倍。这个数据库连接池采用Google Collection作为内部的集合类框架,而且现在的版本已经很稳定。

要使用BoneCP,必须用到的jar文件有:

· bonecp-0.6.5.jar

· google-collections-1.0.jar

· slf4j-api-1.5.11.jar

· slf4j-log4j12-1.5.11.jar

·log4j-1.2.15.jar

在程序中创建BoneCPDataSource对象,代码如下:

// 创建BoneCPDataSource对象

BoneCPDataSource ds = new BoneCPDataSource();

ds.setDriverClass("com.mysql.jdbc.Driver");

ds.setJdbcUrl("jdbc:mysql://localhost:3306/cheng");

ds.setUsername("root");

ds.setPassword("root");

ds.setAcquireIncrement(1);

ds.setAcquireRetryDelay(10000);

ds.setIdleConnectionTestPeriod(100);

ds.setMinConnectionsPerPartition(2);

ds.setMaxConnectionsPerPartition(20);

ds.setPartitionCount(2);

以上几种创建数据源的方式多以硬编码来实现,在实际应用中应该以配置文件的形式出现,以方便管理和维护。

你可能感兴趣的:(Spring,spring)