前期mysql准备
create database cong use cong; create table account( id int primary key auto_increment, name varchar(40), money float )character set utf8 collate utf8_general_ci; insert into account(name,money) values('aaa',1000); insert into account(name,money) values('bbb',1000); insert into account(name,money) values('ccc',1000);
啰里巴嗦的JdbcTemplate大概内容
Spring框架对JDBC的简单封装,提供了一个JDBCTemplate对象用来简化JDBC的开发 其实有比 JDBC Template 更好的操作数据库的框架(如 Mybatis), 但是 JDBC Template 是基础,有助于我们更好的了解 Spring 中JDBC 操作,所以还是讲解一下。 使用 Spring 组件 JDBC Template 简化持久化操作。 步骤: 1.导入jar包 2.准备数据源dataSource 3.创建JDBCTemplate对象,参数要传递DataSource 4.执行操作 纯java代码大概如下 public class Demo1 { public static void main(String[] args) { //准备数据源:spring的内置数据源 DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/cong"); dataSource.setUsername("root"); dataSource.setPassword("123456"); //1.创建JdbcTemplate对象 JdbcTemplate jdbcTemplate = new JdbcTemplate(); //2.给这个对象设置数据源 jdbcTemplate.setDataSource(dataSource); //3.执行操作 jdbcTemplate.execute("insert into account(name,money) values('will',20000)"); } } 如何执行操作是重点 首先是:update()方法 它可以执行增删改的DML语句 比如: jdbcTemplate.update("insert into account(name,money) values(?,?)", "will", 500f); jdbcTemplate.update("delete from account where id = ?", 11); jdbcTemplate.update("update account set name=?,money=? where id = ?", "hiRainbow", 222222, 3); 然后是查询,查询的方法有很多个 query():查询结果,将结果封装为JavaBean对象 queryForMap():将查询结果封装为map集合 queryForList():将查询结果封装为List集合 queryForObject:查询结果,将结果封装为对象
此外,还有很多方法,有兴趣的可以翻阅文档
1.创建maven工程,再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>com.cong</groupId> <artifactId>spring_JdbcTemplate</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!-- JdbcTemplate在下面的包中 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!-- 导入org.springframework还需要导入spring-tx,它是与事务相关的,操作jdbc离不开事务 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> </project>
2.再java目录下创建com.cong.pojo.Account类
package com.cong.pojo; import java.io.Serializable; public class Account implements Serializable { private int id; private String name; private float money; public int getId() { return id; } public void setId(int 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 + '}'; } }
3.在java目录下创建com.cong.jdbcTemplate.Demo1类
演示JdbcTemplate的基本用法,向数据库中插入一条数据,通过navicate查看,插入成功
package com.cong.jdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; /** * JdbcTemplate的最基本用法 * 然后可以发现,下面的代码中有new关键字,也就是可以放到ioc容器中 * 在demo2中讲解 */ public class Demo1 { public static void main(String[] args) { //准备数据源:spring的内置数据源 DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/cong"); dataSource.setUsername("root"); dataSource.setPassword("123456"); //1.创建JdbcTemplate对象 JdbcTemplate jdbcTemplate = new JdbcTemplate(); //2.给这个对象设置数据源 jdbcTemplate.setDataSource(dataSource); //3.执行操作 jdbcTemplate.execute("insert into account(name,money) values('will',20000)"); } }
4.将对象注入到ioc容器中,让spring为我们管理需要用到的对象
在resources下创建applicationContext.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/cong"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> </bean> </beans>
5.在jdbcTemplate包下创建Demo2类
package com.cong.jdbcTemplate; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.jdbc.core.JdbcTemplate; /** * 将需要用到的对象注入到ioc容器中 * 除了插入,数据库应该还有其他用法,在demo3中展示 */ public class Demo2 { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); JdbcTemplate jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate"); jdbcTemplate.execute("insert into account(name,money) VALUE ('will',100000)"); } }
6.在jdbcTemplate包下创建Demo3类,演示JdbcTemplate的crud操作
package com.cong.jdbcTemplate; import com.cong.pojo.Account; import org.junit.Test; 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; import java.util.Map; /** * jdbcTemplate 的 crud操作 */ public class Demo3 { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); JdbcTemplate jdbcTemplate = context.getBean("jdbcTemplate", JdbcTemplate.class); //查询所有 @Test public void findAll() { //通过自定义的封装策略将查询到的结果封装到集合里面 //List<Account> accounts = jdbcTemplate.query("select * from account where id > ?", new AccountRowMapper(), 0); //spring提供的将对象封装到集合里面的方法,更常用 List<Account> accounts = jdbcTemplate.query("select * from account where money > ?", new BeanPropertyRowMapper<Account>(Account.class), 1f); for (Account account : accounts) { System.out.println(account.toString()); } } //查询一个,通过BeanPropertyRowMapper封装到List集合中 @Test public void findOne() { List<Account> accounts = jdbcTemplate.query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class), 1); System.out.println(accounts.isEmpty() ? "without account" : accounts.get(0)); } //查询数量,查询返回一行一列,queryForObject一般用来查询聚合函数,但不加group by子句 @Test public void findCount() { Long count = jdbcTemplate.queryForObject("select count(*) from account where id> ?", Long.class, 0); System.out.println(count); } //保存 @Test public void saveAccount() { jdbcTemplate.update("insert into account(name,money) values(?,?)", "will", 500f); } //更新 @Test public void updateAccount() { jdbcTemplate.update("update account set name=?,money=? where id = ?", "hiRainbow", 222222, 3); } //删除 @Test public void deleteAccount() { jdbcTemplate.update("delete from account where id = ?", 11); } //查询所有,封装为List集合,List里面装的是Map集合 @Test public void findAllToList(){ String sql = "select * from account"; List<Map<String, Object>> list = jdbcTemplate.queryForList(sql); for (Map<String, Object> stringObjectMap : list) { System.out.println(stringObjectMap); } } //查询1个,将结果封装到Map中 //要注意的是查询的结果集长度只能是1,将列名作为key,值作为value封装为map集合 @Test public void testMap(){ Map<String,Object> map = jdbcTemplate.queryForMap("select * from account where id = ?",1); System.out.println(map); } } /** * 自定义Account的封装策略 * 就是我们自己将从mysqll查询到的数据手动封装起来 * 而BeanPropertyRowMapper是spring为我们提供的将查询结果自动封装成对象 */ class AccountRowMapper implements RowMapper<Account> { /** * 把结果集中的数据封装到Account中,然后由spring把每个Account加到集合中 * * @param rs * @param rowNum * @return * @throws SQLException */ @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; } }
7.学习了JdbcTemplate的基本用法,那么在dao层中如何使用JdbcComplate
在dao中使用JdbcTemplate
一种方法是在dao类中写入JdbcTemplate成员变量,然后在spring ioc容器注入dataResource
public class AccountDao{ private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public Account findAccountById(int id) { List<Account> accounts = jdbcTemplate.query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class),id); return (accounts.isEmpty()?null:accounts.get(0)); } }
<bean id="accountDao" class="com.cong.dao.AccountDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
另外一种方法就是让dao层的类继承JdbcDaoSupport
JdbcDaoSupport 是 spring 框架为我们提供的一个类,该类中定义了一个 JdbcTemplate 对象,我们可以
直接获取使用,但是要想创建该对象,需要为其提供一个数据源:
public class AccountDao2 extends JdbcDaoSupport{ public Account findAccountById(int id) { List<Account> accounts = super.getJdbcTemplate().query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class),id); return (accounts.isEmpty()?null:accounts.get(0)); } } <bean id="accountDao2" class="com.cong.dao.AccountDao2"> <property name="dataSource" ref="datasource"></property> </bean>
优略:
第一种在 Dao 类中定义 JdbcTemplate 的方式,适用于所有配置方式(xml 和注解都可以),只不过它每个dao类都会有一个setter方法
第二种让 Dao 继承 JdbcDaoSupport 的方式,只能用于基于 XML 的方式,注解用不了。
总结
JDBC Template 优点:
- 简单
- 灵活
JDBC Template 缺点:
- SQL 与 Java 代码参杂
- 功能不丰富
总结:
JDBC Template是 Spring 框架对 JDBC 操作的封装。简单、灵活但不够强大。实际应用中还需要和其他 ORM 框架混合使用。