JdbcTemplate 的增删改查操作及在dao中的使用
一.JdbcTemplate 的增删改查操作
1.准备工作
创建数据库:
create database spring;
use spring;
创建表:
create table account(
id int primary key auto_increment,
name varchar(40),
money float
)character set utf8 collate utf8_general_ci;
(先对着代码敲,总会有收获,加油,奥利给ヾ(◍°∇°◍)ノ゙),总结在最后面!!!
配置文件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">
<!--配置账户的持久层-->
<bean id="accountDao" class="com.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>
<!--配置数据源-->
<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:3306/spring"></property>
<property name="username" value="root"></property>
<property name="password" value="admin"></property>
</bean>
</beans>
账户的实体类Account
package com.domain;
/*
* 账户的实体类
* */
public class Account {
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 +
'}';
}
}
账户的持久层接口IAccountDao
package com.dao;
import com.domain.Account;
/*
* 账户的持久层接口
* */
public interface IAccountDao {
/*
* 根据id查找账户
* */
Account findAccountById(Integer accountId);
/*
* 根据姓名查找账户
* */
Account findAccountByName(String accountName);
/*
* 更新账户
* */
void updateAccount(Account account);
}
账户的持久层实现类AccountDaoImpl
package com.impl;
import com.dao.IAccountDao;
import com.domain.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
/*
* 账户的持久层实现类
* */
public class AccountDaoImpl implements IAccountDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public Account findAccountById(Integer accountId) {
List<Account> accounts = jdbcTemplate.query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class),accountId);
return (accounts.isEmpty()?null:accounts.get(0));
}
//考虑姓名不唯一的情况,区别于根据id查询
@Override
public Account findAccountByName(String accountName) {
List<Account> accounts = jdbcTemplate.query("select * from account where name = ?", new BeanPropertyRowMapper<Account>(Account.class),accountName);
if(accounts.isEmpty()){
return null;
}
if(accounts.size()>1){
throw new RuntimeException("结果集不唯一");
}
return accounts.get(0);
}
@Override
public void updateAccount(Account account) {
jdbcTemplate.update("update account set name = ?, money = ? where id = ?",
account.getName(), account.getMoney(), account.getId());
}
}
JdbcTemplate的简单操作(不使用dao)
package com.jdbctemplate;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import java.io.Serializable;
public class JdbcTemplateDemo2 implements Serializable {
public static void main(String[] args) {
//1.获取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.获取对象
JdbcTemplate jt = ac.getBean("jdbcTemplate", JdbcTemplate.class);
//3.执行操作
jt.execute("insert into account(name, money) values ('ddd', 2222)");
}
}
JdbcTemplate的CRUD操作(不使用dao)
package com.jdbctemplate;
import com.domain.Account;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
public class JdbcTemplateDemo3 implements Serializable {
public static void main(String[] args) {
//1.获取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.获取对象
JdbcTemplate jt = ac.getBean("jdbcTemplate", JdbcTemplate.class);
//3.执行操作
//保存
jt.update("insert into account(name, money) values (?, ?)", "eee", 500);
//更新
jt.update("update account set name = ?,money=? where id = 5", "fff", 5000);
//删除
jt.update("delete from account where id = ?", 5);
/*
查询所有
* 参数new AccoutRowMapper()可写成new BeanPropertyRowMapper<Account>(Account.class)
即可不用写AccoutRowMapper类
*/
List<Account> accounts = jt.query("select * from account where money > ?",new AccoutRowMapper(),1500f); for(Account account: accounts){
System.out.println(account);
}
//查询一个
List<Account> accounts = jt.query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),1);
System.out.println(accounts.isEmpty()?"没有内容" : accounts.get(0));
//查询返回一行一列:使用聚合函数,
// 在不使用 group by 字句时,都是返回一行一列。最长用的 就是分页中获取总记录条数
Long count = jt.queryForObject("select count(*) from account where money > ?", Long.class,1500);
System.out.println(count);
}
}
/*
* 定义Account的封装策略
* */
class AccoutRowMapper implements RowMapper<Account>{
/*
* 把结果集中的数据封装到Account中,然后由spring把每个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;
}
}
二.JdbcTemplate 在dao中的使用
第一种方式:在 dao 中定义 JdbcTemplate
此版本的 dao,需要给 dao注入 JdbcTemplate ,在配置文件中配置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> accounts = jdbcTemplate.query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class),accountId);
return (accounts.isEmpty()?null:accounts.get(0));
}
//考虑姓名不唯一的情况,区别于根据id查询
@Override
public Account findAccountByName(String accountName) {
List<Account> accounts = jdbcTemplate.query("select * from account where name = ?", new BeanPropertyRowMapper<Account>(Account.class),accountName);
if(accounts.isEmpty()){
return null;
}
if(accounts.size()>1){
throw new RuntimeException("结果集不唯一");
}
return accounts.get(0);
}
@Override
public void updateAccount(Account account) {
jdbcTemplate.update("update account set name = ?, money = ? where id = ?",
account.getName(), account.getMoney(), account.getId());
}
}
配置文件bean.xml,需要配置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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置账户的持久层-->
<bean id="accountDao" class="com.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>
<!--配置数据源-->
<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:3306/spring"></property>
<property name="username" value="root"></property>
<property name="password" value="admin"></property>
</bean>
</beans>
测试代码
public class JdbcTemplateDemo4 implements Serializable {
public static void main(String[] args) {
//1.获取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.获取对象
IAccountDao accountDao = ac.getBean("accountDao", AccountDaoImpl.class);
//3.执行操作
Account account = accountDao.findAccountById(1);
System.out.println(account);
account.setMoney(1000f);
account.setName("haha");
accountDao.updateAccount(account);
}
}
第二种方式:让 dao 继承 JdbcDaoSupport
JdbcDaoSupport 是spring 框架为我们提供的一个类,该类中定义了一个 JdbcTemplate 对象,我们可以 直接获取使用,但是要想创建该对象,需要为其提供一个数据源。
***该方法可不用给 dao注入 JdbcTemplate
/*
* 账户的持久层实现类
* JdbcDaoSupport 是spring 框架为我们提供的一个类,
* 该类中定义了一个 JdbcTemplate 对象,我们可以 直接获取使用,但是要想创建该对象,需要为其提供一个数据源
* */
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {
@Override
public Account findAccountById(Integer accountId) {
List<Account> accounts = getJdbcTemplate().query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class),accountId);
return (accounts.isEmpty()?null:accounts.get(0));
}
//考虑姓名不唯一的情况,区别于根据id查询
@Override
public Account findAccountByName(String accountName) {
//getJdbcTemplate()方法是从父类上继承下来的。
List<Account> accounts = getJdbcTemplate().query("select * from account where name = ?", new BeanPropertyRowMapper<Account>(Account.class),accountName);
if(accounts.isEmpty()){
return null;
}
if(accounts.size()>1){
throw new RuntimeException("结果集不唯一");
}
return accounts.get(0);
}
@Override
public void updateAccount(Account account) {
getJdbcTemplate().update("update account set name = ?, money = ? where id = ?",
account.getName(), account.getMoney(), account.getId());
}
}
配置文件bean.xml,需要给dao注入数据源,不需要配置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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置账户业务层-->
<bean id="accountService" class="com.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
<!--配置账户的持久层-->
<bean id="accountDao" class="com.impl.AccountDaoImpl">
<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://localhost:3306/spring"></property>
<property name="username" value="root"></property>
<property name="password" value="admin"></property>
</bean>
</beans>
方法二的好处是:
我们的 dao 有很多时,每个 dao 都有一些重复性的代码。
下面就是重复代码:
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
方法二可以把它抽取出来,减少了代码的冗余
两版 Dao有什么区别呢?
答案: