一、jdbcTemplate
1、jdbcTemplate概述
它是spring框架中提供的一个对象,是对原始Jdbc API对象的简单封装。spring框架为我们提供了很多的操作模板类,入下图所示:
2、需要导入的jar包
二、jdbcTemplate入门
1、jdbcTemplate对象的获取以及基本用法
package cn.itcast.jdbctemplate;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
/**
* JdbcTemplate对象的获取,最基本的使用
* @author wingzhe
*
*/
public class JdbcTemplateDemo1 {
public static void main(String[] args) {
//1 定义一个数据源
DriverManagerDataSource ds = new DriverManagerDataSource();
//2 设置连接数据库的信息
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/spring_64");
ds.setUsername("root");
ds.setPassword("1234");
//3 创建Jdbc操作模板
JdbcTemplate jt = new JdbcTemplate();
//4.建立操作模板和连接池的关系
jt.setDataSource(ds);
jt.execute("insert into account(name,money)values('ddd',1000)");
}
}
2、使用配置的方式获取jdbcTemplate
(1)、jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_64
jdbc.username=root
jdbc.password=1234
(2)、bean.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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置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="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean> -->
<!-- 配置c3p0数据源
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>-->
<!-- 配置DBCP数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 引入属性文件 -->
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"/>
</bean>
</beans>
(3)、java代码
package cn.itcast.jdbctemplate;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
/**
* JdbcTemplate的配置方式
* @author wingzhe
*
*/
public class JdbcTemplateDemo2 {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
jt.execute("insert into account(name,money)values('hhh',1000)");
}
}
三、jdbcTemplate的增删改查
package cn.itcast.jdbctemplate;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import cn.itcast.domain.Account;
/**
* JdbcTemplate的CRUD
* @author wingzhe
*
*/
public class JdbcTemplateDemo3 {
public static void main(String... args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
// 保存
// jt.update("insert into account(name,money)values(?,?)","iii",5000);
// 更新
// jt.update("update account set money = money-? where id=?",500,1);
// 删除
// jt.update("delete from account where id = ? ",4);
// 查询所有
// List<Account> accounts = jt.query("select * from account where money > ?",new AccountRowMapper(),1000);
// for(Account a : accounts){
// System.out.println(a);
// }
// 查询一个
// List<Account> accounts = jt.query("select * from account where id = ?",new AccountRowMapper(),4);
// System.out.println(accounts.isEmpty()?"没有数据":accounts.get(0));
//查询返回一行一列
Integer count = jt.queryForObject("select count(*) from account where money > ? ", Integer.class,1000);
System.out.println(count);
}
}
/**
* RowMapper<T> : 行的映射 将数据库中的一行数据转换成java代码中的一个对象(javaBean)
*
*/
class AccountRowMapper implements RowMapper<Account>{
// RowMapper 行的映射 将数据库中的一行数据转换成java代码中的一个对象(javaBean)
// 有多少行记录 mapRow 方法将被执行几次 每一次执行的时候 会传入两个参数
// 参数1: 当前行的结果集 不用resultSet.next()
// 参数2: 执行到第几行的索引 遍历第几次的索引
// 返回值是Account 每一次执行完一次mapRow方法 会封装一个Account对象 自动添加到list集合中
@Override
public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
Account account = new Account();
account.setId(rs.getInt("id"));
account.setName(rs.getString("name"));
account.setMoney(rs.getFloat("money"));
return account;
}
}
使用BeanPropertyRowMapper封装所有数据到List集合中
/**
* 查询所有封装到一个对象中
* 选中类 ctrl + h
* 细节 注意点:
* 1. 数据库的一条数据 查询结果有字段的名称 与 实体(对象 javaBean) set方法 去掉set首字母小写匹配 如果匹配成功赋值
* 2. 数据库中字段多余实体的字段 不会报错 数据库有name 实体没有name
* 3. 数据库中字段少于实体的字段 不会报错 顶多是赋值不成功 实体中有name2 但数据库没有 使用数据类型的默认值
* 4. 如果实体没有无参 会报错 java实体必须要有无参构造(适用于以后 反射的过程一般都是使用无参构造)
*
* javaBean 实体对象
* 1.成员私有化
* 2.提供get/set
* 3.必须有无参构造
* 4.必须使用包装类类型 包装类有null 而普通的类型没有
* 因为int 有默认值 0 数据库数据库有null和0一说 必须区分开来两个数据
*
*/
@Test
public void queryImportant(){
String sql = " select * from tab_user ";
//BeanPropertyRowMapper javaBean对象 的属性 行 映射
//将数据库的行记录映射到实体的类中属性上
//class交由底层反射实例化对象 Class.newInstance() 泛型的user可以省略 因为class很强大 通过泛型反射可以获得类型
List<User> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<User>(User.class));
for (User user : list) {
System.out.println(user);
}
}
四、Dao中的jdbcTemplate
1、继承JdbcDaoSuppport
(1)、javaBean
package cn.itcast.domain;
import java.io.Serializable;
public class Account implements Serializable {
private Integer id;
private String name;
private Float money;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Float getMoney() {
return money;
}
public void setMoney(Float money) {
this.money = money;
}
@Override
public String toString() {
return "Account [id=" + id + ", name=" + name + ", money=" + money + "]";
}
}
(2)、spirng配置文件
<?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="accountDao" class="cn.itcast.dao.impl.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置spring内置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 引入属性文件 -->
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"/>
</bean>
</beans>
(3)、dao层接口和实现类
package cn.itcast.dao.rowmapper;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
import cn.itcast.domain.Account;
public class AccountRowMapper implements RowMapper<Account> {
@Override
public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
Account account = new Account();
account.setId(rs.getInt("id"));
account.setName(rs.getString("name"));
account.setMoney(rs.getFloat("money"));
return account;
}
}
package cn.itcast.dao;
import cn.itcast.domain.Account;
/**
* 账户的持久层接口
* @author wingzhe
*
*/
public interface IAccountDao {
/**
* 根据id查询账户信息
* @param id
* @return
*/
Account findAccountById(Integer id);
/**
* 根据名称查询账户信息
* @param name
* @return
*/
Account findAccountByName(String name);
/**
* 更新账户信息
* @param account
*/
void updateAccount(Account account);
}
package cn.itcast.dao.impl;
import java.util.List;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import cn.itcast.dao.IAccountDao;
import cn.itcast.dao.rowmapper.AccountRowMapper;
import cn.itcast.domain.Account;
/**
* 账户的持久层实现类
* @author zhy
*
*/
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {
@Override
public Account findAccountById(Integer id) {
List<Account> accounts = getJdbcTemplate().query("select * from account where id = ? ",new AccountRowMapper(),id);
return accounts.isEmpty() ? null : accounts.get(0);
}
@Override
public Account findAccountByName(String name) {
List<Account> accounts = getJdbcTemplate().query("select * from account where name = ? ",new AccountRowMapper(),name);
//没有结果
if(accounts.isEmpty()){
return null;
}
//结果集大于1了,数据有问题
if(accounts.size() > 1){
throw new RuntimeException("结果集不唯一");
}
return accounts.get(0);
}
@Override
public void updateAccount(Account account) {
getJdbcTemplate().update("update account set money = ? where id = ? ",account.getMoney(),account.getId());
}
}
(4)、测试类
package cn.itcast.ui;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.itcast.dao.IAccountDao;
import cn.itcast.domain.Account;
public class Client {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
IAccountDao accountDao = (IAccountDao) ac.getBean("accountDao");
Account account = accountDao.findAccountById(3);
System.out.println(account);
account.setMoney(3000f);
accountDao.updateAccount(account);
}
}
2、在dao中定义jdbcTemplate
(1)、配置方式
dao层
/**
* 账户的持久层实现类
* @author wingzhe
* 此版本的dao,需要给dao注入JdbcTemplate
*/
public class AccountDaoImpl implements IAccountDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public Account findAccountById(Integer id) {
List<Account> list = jdbcTemplate.query("select * from account where id = ? ",new AccountRowMapper(),id);
return list.isEmpty()?null:list.get(0);
}
@Override
public Account findAccountByName(String name) {
List<Account> list = jdbcTemplate.query("select * from account where name = ? ",new AccountRowMapper(),name);
if(list.isEmpty()){
return null;
}
if(list.size()>1){
throw new RuntimeException("结果集不唯一,不是只有一个账户对象");
}
return list.get(0);
}
@Override
public void updateAccount(Account account) {
jdbcTemplate.update("update account set money = ? where id = ? ",account.getMoney(),account.getId());
}
}
配置文件
<?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">
<!-- 配置一个dao -->
<bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
<!-- 注入jdbcTemplate -->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!-- 配置一个数据库的操作模板:JdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///spring_day04"></property>
<property name="username" value="root"></property>
<property name="password" value="1234"></property>
</bean>
</beans>
(2)、注解方式
配置类
package cn.itcast.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
/**
* spring连接数据库的配置类
* @author
*
*/
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean(name="jdbcTemplate")
public JdbcTemplate createJdbcTemplate(@Qualifier("dataSource")DataSource ds){
return new JdbcTemplate(ds);
}
@Bean(name="dataSource")
public DataSource createDataSource(){
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
}
package cn.itcast.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
@Configuration
@ComponentScan("cn.itcast")
@Import({JdbcConfig.class})
@PropertySource("classpath:jdbc.properties")
public class SpringConfiguration {
@Bean
public static PropertySourcesPlaceholderConfigurer createPropertySourcesPlaceholderConfigurer(){
return new PropertySourcesPlaceholderConfigurer();
}
}
dao层
package cn.itcast.dao.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import cn.itcast.dao.IAccountDao;
import cn.itcast.dao.rowmapper.AccountRowMapper;
import cn.itcast.domain.Account;
/**
* 账户的持久层实现类
* @author
*
*/
@Repository("accountDao")
public class AccountDaoImpl implements IAccountDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public Account findAccountById(Integer id) {
List<Account> accounts = jdbcTemplate.query("select * from account where id = ? ",new AccountRowMapper(),id);
return accounts.isEmpty() ? null : accounts.get(0);
}
@Override
public Account findAccountByName(String name) {
List<Account> accounts = jdbcTemplate.query("select * from account where name = ? ",new AccountRowMapper(),name);
//没有结果
if(accounts.isEmpty()){
return null;
}
//结果集大于1了,数据有问题
if(accounts.size() > 1){
throw new RuntimeException("结果集不唯一");
}
return accounts.get(0);
}
@Override
public void updateAccount(Account account) {
jdbcTemplate.update("update account set money = ? where id = ? ",account.getMoney(),account.getId());
}
}
测试类
package cn.itcast.ui;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.itcast.config.SpringConfiguration;
import cn.itcast.dao.IAccountDao;
import cn.itcast.domain.Account;
public class Client {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
IAccountDao accountDao = (IAccountDao) ac.getBean("accountDao");
Account account = accountDao.findAccountById(3);
System.out.println(account);
account.setMoney(80000f);
accountDao.updateAccount(account);
}
}
3、继承JdbcDaoSupport和在dao中定义jdbcTemplate有什么区别
继承JdbcDaoSupport的方式只能用于xml配置的方式,不能使用注解,而在dao中定义jdbcTemplate的方式,既可以用xml配置的方式,也可以用注解的方式