对于一些小的项目, 我们没有必要使用MyBatis/JPA/Hibernate等重量级技术, 直接使用Spring JDBC 即可, Spring JDBC 是对 jdbc的简单封装, 很容易掌握.
============================
Spring JdbcTemplate 和 JDBC API 对比
============================
JDBC API的缺点:
1. 我们的代码中包含充斥着很多这样的代码: 创建connection, 创建statement , 关闭connection, 关闭resultset.
2. 对于 resultset 操作也不太方便, 需要使用 while 循环 + 客户端游标.next() 等.
3. 实现 Row -> Object 的映射比较玛法.
3. 我们需要自己控制 transaction(老实说, 这既是缺点又是优点)
Spring JdbcTemplate的特点:
1. 不需要我们关注各种资源的打开/关闭
2. 很容易将 resultset 转成 Pojo 集合.
3. 自动能利用上 DB 连接池
============================
Spring Jdbc主要类
============================
JdbcTemplate 类: 这是Spring JDBC中最常用的类.
NamedParameterJdbcTemplate 类: Jdbc中传统的参数占位符是问号, 这个类提供对命名参数的支持.
SimpleJdbcInsert 类: 不需要写Insert语句,即可完成单表插入操作, 该类支持链式调用(fluent style)
SimpleJdbcCall 类: 简化的调用存储过程的类, 该类支持链式调用(fluent style)
一般情况下, 我们使用 JdbcTemplate 或 NamedParameterJdbcTemplate 类就足够了.
============================
JdbcTemplate 主要方法
============================
query(),最通用的Select查询, 如果要返回一个 List
queryForObject(): 用来获得Select 标量值, 结果必须是一列一行.
execute(): 多用来执行DDL操作, 也可以用来执行 DML 语句.
update(): 用来执行Insert/Update/Delete操作
call():执行存储过程
batchUpdate(): 批量执行增删改操作
============================
pom.xml & application.properties & DB
============================
<dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-jdbcartifactId> dependency> <dependency> <groupId>mysqlgroupId> <artifactId>mysql-connector-javaartifactId> <scope>runtimescope> dependency>
#application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/world?useUnicode=true&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=toor spring.datasource.driver-class-name=com.mysql.jdbc.Driver
在示例中使用了MySQL 官方提供的 sakila 样本数据库, 该数据用来模拟DVD租赁业务.
先 clone 一个actor_new 新表.
CREATE TABLE `actor_new` ( `actor_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, `first_name` varchar(45) NOT NULL, `last_name` varchar(45) NOT NULL, `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`actor_id`), KEY `idx_actor_last_name` (`last_name`) ) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8 insert into actor_new select * from actor ;
============================
java 示例代码
============================
package com.example.demo; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; @SpringBootApplication public class JdbcSampleApplication implements CommandLineRunner { @Autowired DataSource dataSource; @Autowired JdbcTemplate jdbcTemplate; TransactionTemplate transTemplate; /* * 该方法会被Spring自动在合适的时机调用, 用来初始化一个 TransactionTemplate 对象. 参数 dataSource 被自动注入. */ @Autowired private void transactionTemplate(DataSource dataSource) { transTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource)); } public static void main(String[] args) throws Exception { SpringApplication.run(JdbcSampleApplication.class, args); } @Override public void run(String... args) throws Exception { runSimpleSamples(); runRowToObjectSample(); runTransactionSamples(); runBatchSamples(); } /* * 将resultset 转成 Java 对象列表 */ public void runRowToObjectSample() { String querySql = "select * from actor_new where actor_id"; int id = 20; // 查询DB, Listactors = jdbcTemplate.query(querySql, new Object[] { id }, new ActorRowMapper()); for (Actor actor : actors) { System.out.println(actor.getFirstName()); } } /* * Query/DML执行 */ public void runSimpleSamples() throws SQLException { // 标量查询 Integer count = jdbcTemplate.queryForObject("Select count(*) from actor_new", Integer.class); System.out.println(String.format("actor_new record count:%d", count)); // DML执行 jdbcTemplate.update("Delete from actor_new where actor_id=?", 2); count = jdbcTemplate.queryForObject("Select count(*) from actor_new", Integer.class); System.out.println(String.format("actor_new record count:%d", count)); } /* * 带有事务控制的DML * 将DML操作放到 TransactionCallback类的doInTransaction()方法中. * 只有在下面两种情况下才会回滚: * 1. 通过设置 transactionStatus 为 RollbackOnly * 2. 抛出任何异常 * */ public void runTransactionSamples() throws SQLException { transTemplate.execute(new TransactionCallback
============================
参考
============================
https://blog.csdn.net/zq9017197/article/details/6321391?utm_source=blogxgwz0
Spring JDBC
https://www.baeldung.com/spring-jdbc-jdbctemplate
Spring JdbcTemplate方法详解
https://blog.csdn.net/dyllove98/article/details/7772463
TRANSACTIONS WITH JDBCTEMPLATE
http://www.javacreed.com/transactions-with-jdbctemplate/