本系列笔记均是对b站教程https://www.bilibili.com/video/av47952931 的学习笔记,非本人原创
JdbcTemplate的使用
我们先举一个使用jdbcTemplate的简单例子:
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>day04_jdbcTemplate</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
</dependencies>
</project>
package com.jiading.jdbctemplate;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
/*
JdbcTemplate的最基本用法
*/
public class JdbcTemplateDemo1 {
public static void main(String[] args) {
//准备数据源:spring内置数据源
DriverManagerDataSource ds=new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/jd_learning");
ds.setUsername("root");
ds.setPassword("<密码>");
//1.创建JdbcTemplate对象
JdbcTemplate jt=new JdbcTemplate();
//给jdbcTemplate设置数据源
jt.setDataSource(ds);
//2.执行操作
jt.execute("insert into account(name,money)values('ccc',1000)");
}
}
上面就是使用JdbcTemplate进行连接的一个例子,可以看到和dbUtils的使用很像。但是这样的配置显然太繁琐了,所以我们可以使用spring的ioc来简化:
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>
<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/jd_learning"></property>
<property name="username" value="root"></property>
<property name="password" value="<密码>"></property>
</bean>
</beans>
package com.jiading.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的最基本用法
*/
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('ddd',1000)");
}
}
这是CRUD的增的例子,其他操作方法为:
package com.jiading.jdbctemplate;
import com.jiading.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.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
/*
JdbcTemplate的最基本用法
*/
public class JdbcTemplateDemo3 {
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('ddd',1000)");
//保存
jt.update("insert into account(name,money)values(?,?)", "eee", 3333f);
//更新
jt.update("update account set name=? money=? where id=?", "test", 4567f, 7);
//删除
jt.update("delete from account where id=?", 8);
//查询所有
/*
有两种查询方法,和JDK版本有关
query(String sql,Object[] args,RowMapper<T> rowMapper)
这种方法各种JDK版本均可
query(String sql,RowMapper<T> rowMapper,Object... args)
只能在JDK1.5之后使用,因为这个是可变参数版,可变参数只有在1.5之后才被支持
*/
//这是用的第二种:query(String sql,RowMapper<T> rowMapper,Object... args)
List<Account> query = jt.query("select * from account where money>?", new AccountRowMapper(), 1000f);
/*
但是这种方法还是比如麻烦的,需要我们手动写ResultSet到Account的转换类,其实Spring和dbUtils一样,也提供了这样的类
传入的类型T是表示查询的结果的类型,而Account.class表示返回对象的类型
*/
List<Account> query1 = jt.query("select * from account where money>?", new BeanPropertyRowMapper<Account>(Account.class), 1000f);
//查询一个
//查询一个直接使用查询所有的方法即可,返回List但是get(0)
//查询返回一行一列(也就是使用聚合函数,但不使用group by子句)
Integer integer = jt.queryForObject("select count(*)from account where money>?", Integer.class, 1000f);
//第二个参数是返回值的类型
//这里只讲单表操作,多表操作同理
}
}
/*
定义Account的封装策略
*/
class AccountRowMapper implements RowMapper<Account> {
/*
把结果集中的数据封装到Account中,然后由spring把每个account加到集合中。形成最终查询得到的List<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;
}
}
将操作封装到Dao层中:
package com.jiading.dao.impl;
import com.jiading.dao.IAccountDao;
import com.jiading.domain.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
public class AccountDaoImpl implements IAccountDao {
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
private JdbcTemplate jdbcTemplate;
@Override
public Account findAccountById(Integer accountId) {
List<Account> query = jdbcTemplate.query("selecy * from account where id=?", new BeanPropertyRowMapper<Account>(Account.class), accountId);
if (query.isEmpty()) {
return null;
} else {
return query.get(0);
}
}
@Override
public Account findAccountByName(String name) {
List<Account> query = jdbcTemplate.query("selecy * from account where name=?", new BeanPropertyRowMapper<Account>(Account.class), name);
if (query.isEmpty()) {
return null;
} else if (query.size() > 1) {
throw new RuntimeException("结果集不唯一");
} else {
return query.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配置一下,让spring注入依赖:
<bean id="accountDao" class="com.jiading.dao.impl.AccountDaoImpl">
<property name="jdbcTemplate"ref="jdbcTemplate"></property>
</bean>
当然,如果要对多个表进行操作,不需要把jdbcTemplate注入到每一个类中,可以创建一个类来封装jdbcTemplate并提供set和get方法,然后让所有的Dao类都继承该类,这样就能直接使用该类的get方法来获取jdbcTemplate对象进行调用了,减少了重复代码
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao
这样,我们就可以在配置文件中给AccountDao注入DataSource而不是JdbcTemplate,因为它继承了JdbcDaoSupport中的setDataSource方法,会自动注入DataSource方法并创建JdbcTemplate对象
而这种方法spring已经为我们提供了,上面就是它的原理。我们在使用的时候只需要extends JdbcDaoSupport
即可
但是这样做也有弊端,就是不能使用注解配置了,这也好理解:注入的步骤在JdbcDaoSupport中实现了,而这个类是spring提供的,我们不能修改,自然也就不能给它加注解了。所以如果要使用注解配置的话不要用这种方法。