记录:289
场景:基于Spring Boot应用JdbcTemplate操作数据库。包括查、增、改、删操作。对应SQL关键字是select、insert into、update、delete。
版本:
- Spring Boot 2.6.3
- Spring Framework 5.3.15
- MySQL 5.7.33
- JDK 1.8
名词:
JDBC:即Java DataBase Connectivity的缩写,它是Java程序访问数据库的标准接口。
目的:
便于查阅和窥探JdbcTemplate的查、增、改、删操作。清楚描述一个函数,了解函数入参类型,了解返回值类型,应该就可以参透这个函数,至少应用层面是没问题。
一、查
查,即使用JdbcTemplate对数据库的数据做查询操作。
SQL关键字:select。
1.query函数
1.1 query函数定义
参数sql:数据库执行的SQL语句。
参数rowMapper:是RowMapper接口实现类,把数据库返回的结果集表字段与值,封装成自定义的JavaBean对象。
参数args:是SQL中有占位符?时,传入变量的方式。
参数argTypes:是args传入参数对应的数据库表字段的数据类型。
- public
List query(String sql, RowMapper rowMapper) ; - public
List query(String sql, RowMapper rowMapper, @Nullable Object... args) ; - public
List query(String sql, Object[] args, int[] argTypes, RowMapper rowMapper) ;
1.2 query使用场景
场景:使用query函数,可以把查询结果集按照自定义的JavaBean封装,并以List方式返回查询结果集。
1.3 query使用举例
- /**
- * 1.query函数入参不带查询条件,如有查询条件直接写在SQL中
- * 2.使用自定义CityRowMapper封装返回值
- * 3.使用java.util.stream.Stream遍历结果
- */
- public static void f1_1() {
- // 1.获取查询sql
- String sql = getSelectSql01();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.查询数据集
- List
list = jt.query(sql, new CityRowMapper()); - // 4.遍历结果并打印
- Stream
stream = list.stream().parallel(); - stream.forEach(cityPO -> {
- System.out.println(cityPO.toString());
- });
- }
-
- /**
- * 1.query函数入参带查询条件
- * 2.使用自定义CityRowMapper封装返回值
- * 3.使用java.util.stream.Stream遍历结果
- */
- public static void f1_2() {
- // 1.获取查询sql
- String sql = getSelectSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- // 4.查询数据集
- List
list = jt.query(sql, new CityRowMapper(), args); - // 5.遍历结果并打印
- Stream
stream = list.stream().parallel(); - stream.forEach(cityPO -> {
- System.out.println(cityPO.toString());
- });
- }
-
- /**
- * 1.query函数入参带查询条件,入参带参数类型
- * 2.使用自定义CityRowMapper封装返回值
- * 3.使用java.util.stream.Stream遍历结果
- */
- public static void f1_3() {
- // 1.获取查询sql
- String sql = getSelectSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
- // 4.查询数据集
- List
list = jt.query(sql, args, argTypes, new CityRowMapper()); - // 5.遍历结果并打印
- Stream
stream = list.stream().parallel(); - stream.forEach(cityPO -> {
- System.out.println(cityPO.toString());
- });
- }
-
- /**
- * 1.query函数入参带查询条件
- * 2.使用BeanPropertyRowMapper封装返回值
- * 3.使用java.util.stream.Stream遍历结果
- */
- public static void f1_4() {
- // 1.获取查询sql
- String sql = getSelectSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- // 4.查询数据集
- List
list = jt.query(sql, new BeanPropertyRowMapper<>(CityPO.class), args); - // 5.遍历结果并打印
- Stream
stream = list.stream().parallel(); - stream.forEach(cityPO -> {
- System.out.println(cityPO.toString());
- });
- }
- /**
- * 1.select语句
- * 2.query函数入参不带查询条件
- */
- public static String getSelectSql01() {
- String sql01 = "SELECT\n" +
- " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
- " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
- "FROM t_city ";
- return sql01.toString();
- }
- /**
- * 1.select语句
- * 2.query函数入参带查询条件
- */
- public static String getSelectSql02() {
- String sql02 = "SELECT\n" +
- " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
- " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
- "FROM t_city " +
- "WHERE CITY_NAME = ? AND ID =? ";
- return sql02.toString();
- }
2.queryForStream函数
2.1 queryForStream函数定义
Stream,即java.util.stream.Stream,这个接口有点意思,值得花时间研究一下。
参数sql:数据库执行的SQL语句。
参数rowMapper:是RowMapper接口实现类,把数据库返回的结果集表字段与值,封装成自定义的JavaBean对象。
参数args:是SQL中有占位符?时,传入变量的方式。
参数argTypes:是args传入参数对应的数据库表字段的数据类型。
参数pss: 封装入参。
- public
Stream queryForStream(String sql, RowMapper rowMapper) ; - public
Stream queryForStream(String sql, RowMapper rowMapper, @Nullable Object... args) ; - public
Stream queryForStream(String sql, @Nullable PreparedStatementSetter pss, RowMapper rowMapper) ;
2.2 queryForStream使用场景
场景:使用queryForStream函数,可以把查询结果集按照自定义的JavaBean封装,并以Stream方式返回查询结果集。
2.3 queryForStream使用举例
- /**
- * 1.queryForStream函数入参不带查询条件,如有查询条件直接写在SQL中
- * 2.使用自定义CityRowMapper封装返回值
- * 3.使用java.util.stream.Stream遍历结果
- */
- public static void f2_1() {
- // 1.获取查询sql
- String sql = getSelectSql01();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.查询数据集
- Stream
stream = jt.queryForStream(sql, new CityRowMapper()); - // 4.遍历结果并打印
- stream.forEach(cityPO -> {
- System.out.println(cityPO.toString());
- });
- }
-
- /**
- * 1.queryForStream函数入参带查询条件
- * 2.使用自定义CityRowMapper封装返回值
- * 3.使用java.util.stream.Stream遍历结果
- */
- public static void f2_2() {
- // 1.获取查询sql
- String sql = getSelectSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- // 4.查询数据集
- Stream
stream = jt.queryForStream(sql, new CityRowMapper(), args); - // 5.遍历结果并打印
- stream.forEach(cityPO -> {
- System.out.println(cityPO.toString());
- });
- }
-
- /**
- * 1.queryForStream函数入参带查询条件
- * 2.使用自定义CityRowMapper封装返回值
- * 3.使用java.util.stream.Stream遍历结果
- */
- public static void f2_3() {
- // 1.获取查询sql
- String sql = getSelectSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- // 4.查询数据集
- Stream
stream = jt.queryForStream(sql, new ArgumentPreparedStatementSetter(args), new CityRowMapper()); - // 5.遍历结果并打印
- stream.forEach(cityPO -> {
- System.out.println(cityPO.toString());
- });
- }
-
- /**
- * 1.select语句
- * 2.query函数入参不带查询条件
- * 3.queryForStream函数入参不带查询条件
- */
- public static String getSelectSql01() {
- String sql01 = "SELECT\n" +
- " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
- " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
- "FROM t_city ";
- return sql01.toString();
- }
-
- /**
- * 1.select语句
- * 2.query函数入参带查询条件
- * 3.queryForStream函数入参带查询条件
- */
- public static String getSelectSql02() {
- String sql02 = "SELECT\n" +
- " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
- " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
- "FROM t_city " +
- "WHERE CITY_NAME = ? AND ID =? ";
- return sql02.toString();
- }
3.queryForMap函数
3.1 queryForMap函数定义
结果集封装在一个Map中,即返回一条记录。
- public Map
queryForMap(String sql); - public Map
queryForMap(String sql, @Nullable Object... args); - public Map
queryForMap(String sql, Object[] args, int[] argTypes);
3.2 queryForMap使用场景
场景:使用queryForMap函数,可以把查询结果集封装成Map
3.3 queryForMap使用举例
- /**
- * 1.queryForMap函数入参不带查询条件,如有查询条件直接写在SQL中
- * 2.查询条件中只能限定一条记录,返回结果封装在Map中
- * 3.使用java.util.stream.Stream遍历结果
- */
- public static void f3_1() {
- // 1.获取查询sql
- String sql = getSelectSql03();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.查询数据集
- Map
map = jt.queryForMap(sql); - // 4.遍历结果并打印
- Stream
> stream = map.entrySet().stream(); - stream.forEach(cityPO -> {
- System.out.println(cityPO.getKey() + " = " + cityPO.getValue());
- });
- }
-
- /**
- * 1.queryForMap函数入参带查询条件
- * 2.查询条件中只能限定一条记录,返回结果封装在Map中
- * 3.使用map.forEach遍历结果
- */
-
- public static void f3_2() {
- // 1.获取查询sql
- String sql = getSelectSql04();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- // 4.查询数据集
- Map
map = jt.queryForMap(sql, args); - // 5.遍历结果并打印
- map.forEach((key, value) -> {
- System.out.println(key + " = " + value.toString());
- });
- }
-
- /**
- * 1.queryForMap函数入参带查询条件,入参带参数类型
- * 2.查询条件中只能限定一条记录,返回结果封装在Map中
- * 3.使用Map.Entry遍历结果
- */
- public static void f3_3() {
- // 1.获取查询sql
- String sql = getSelectSql04();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
- // 4.查询数据集
- Map
map = jt.queryForMap(sql, args, argTypes); - // 5.遍历结果并打印
- for (Map.Entry
entry : map.entrySet()) { - System.out.println(entry.getKey() + " = " + entry.getValue());
- }
- }
-
- /**
- * 1.select语句,查一条数据
- * 2.queryForMap函数入参不带查询条件
- */
- public static String getSelectSql03() {
- String sql03 = "SELECT\n" +
- " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
- " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
- "FROM t_city limit 1";
- return sql03.toString();
- }
-
- /**
- * 1.select语句,查一条数据
- * 2.queryForMap函数入参带查询条件
- */
- public static String getSelectSql04() {
- String sql04 = "SELECT\n" +
- " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
- " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
- "FROM t_city " +
- "WHERE CITY_NAME = ? AND ID =? limit 1";
- return sql04.toString();
- }
4.queryForRowSet函数
4.1 queryForRowSet函数定义
queryForRowSet把结果封装成SqlRowSet,需要根据SqlRowSet的next()去遍历函数取值。
不能直接取值否则报错:Caused by: java.sql.SQLException: 光标位置无效。
需要调用调用SqlRowSet.next()后,内部会调用结果集ResultSet的结果索引值,才能遍历取值。
参数sql:数据库执行的SQL语句。
参数args:是SQL中有占位符?时,传入变量的方式。
参数argTypes:是args传入参数对应的数据库表字段的数据类型。
- public SqlRowSet queryForRowSet(String sql);
- public SqlRowSet queryForRowSet(String sql, @Nullable Object... args);
- public SqlRowSet queryForRowSet(String sql, Object[] args, int[] argTypes);
4.2 queryForRowSet使用场景
场景:使用queryForRowSet函数,结果集封装成SqlRowSet,需要额外去遍历结果集取值。
4.3 queryForRowSet使用举例
- /**
- * 1.queryForRowSet函数入参不带查询条件,如有查询条件直接写在SQL中
- * 2.使用SqlRowSet封装返回值
- * 3.使用sqlRowSet.next()遍历结果
- * 4.直接取值报错: Caused by: java.sql.SQLException: 光标位置无效
- * 5.调用SqlRowSet.next()后,取值,内部会调用结果集ResultSet的结果索引值即可以取值
- */
- public static void f4_1() {
- // 1.获取查询sql
- String sql = getSelectSql01();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- jt.setFetchSize(2);
- // 3.查询数据集
- SqlRowSet sqlRowSet = jt.queryForRowSet(sql);
- // 4.遍历结果并打印
- while (sqlRowSet.next()) {
- Object result = sqlRowSet.getObject("CITY_NAME");
- System.out.println(result);
- }
- }
-
- /**
- * 1.queryForRowSet函数入参带查询条件
- * 2.使用SqlRowSet封装返回值
- * 3.使用sqlRowSet.next()遍历结果
- * 4.直接取值报错: Caused by: java.sql.SQLException: 光标位置无效
- * 5.调用SqlRowSet.next()后,取值,内部会调用结果集ResultSet的结果索引值即可以取值
- */
-
- public static void f4_2() {
- // 1.获取查询sql
- String sql = getSelectSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- // 4.查询数据集
- SqlRowSet sqlRowSet = jt.queryForRowSet(sql, args);
- // 5.遍历结果并打印
- while (sqlRowSet.next()) {
- Object result = sqlRowSet.getObject("CITY_DESCRIBE");
- System.out.println(result);
- }
- }
-
- /**
- * 1.queryForRowSet函数入参带查询条件,入参带参数类型
- * 2.使用SqlRowSet封装返回值
- * 3.使用sqlRowSet.next()遍历结果
- * 4.直接取值报错: Caused by: java.sql.SQLException: 光标位置无效
- * 5.调用SqlRowSet.next()后,取值,内部会调用结果集ResultSet的结果索引值即可以取值
- */
- public static void f4_3() {
- // 1.获取查询sql
- String sql = getSelectSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
- // 4.查询数据集
- SqlRowSet sqlRowSet = jt.queryForRowSet(sql, args, argTypes);
- // 5.遍历结果并打印
- while (sqlRowSet.next()) {
- Object result = sqlRowSet.getObject("DATA_YEAR");
- System.out.println(result);
- }
- }
-
- /**
- * 1.select语句
- * 2.query函数入参不带查询条件
- * 3.queryForStream函数入参不带查询条件
- * 4.queryForRowSet函数入参不带查询条件
- */
- public static String getSelectSql01() {
- String sql01 = "SELECT\n" +
- " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
- " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
- "FROM t_city ";
- return sql01.toString();
- }
- /**
- * 1.select语句
- * 2.query函数入参带查询条件
- * 3.queryForStream函数入参带查询条件
- * 4.queryForRowSet函数入参带查询条件
- */
- public static String getSelectSql02() {
- String sql02 = "SELECT\n" +
- " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
- " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
- "FROM t_city " +
- "WHERE CITY_NAME = ? AND ID =? ";
- return sql02.toString();
- }
5.queryForObject函数
5.1 queryForObject查询一个字段
5.1.1 queryForObject函数定义
queryForObject的以下3个函数,查询一个字段值。
参数sql:数据库执行的SQL语句。
参数requiredType:封装返回值类型。
参数args:是SQL中有占位符?时,传入变量的方式。
参数argTypes:是args传入参数对应的数据库表字段的数据类型。
- public
T queryForObject(String sql, Class requiredType) ; - public
T queryForObject(String sql, Class requiredType, @Nullable Object... args) ; - public
T queryForObject(String sql, Object[] args, int[] argTypes, Class requiredType) ;
5.1.2 queryForObject使用场景
场景:使用queryForObject函数,查询一条记录的一个字段值,根据基本类型封装返回值。
5.1.3 queryForObject使用举例
- /**
- * 1.queryForObject函数入参不带查询条件,如有查询条件直接写在SQL中
- * 2.根据基本类型封装返回值
- * 3.查询一条记录的一个字段值
- */
- public static void f5_1_1() {
- // 1.获取查询sql
- String sql = getSelectSql05();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.查询数据集
- String cityName = jt.queryForObject(sql, String.class);
- // 4.遍历结果并打印
- System.out.println(cityName);
- }
-
- /**
- * 1.queryForObject函数入参带查询条件
- * 2.根据基本类型封装返回值
- * 3.查询一条记录的一个字段值
- */
- public static void f5_1_2() {
- // 1.获取查询sql
- String sql = getSelectSql06();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- // 4.查询数据集
- String cityName = jt.queryForObject(sql, String.class, args);
- // 5.遍历结果并打印
- System.out.println(cityName);
- }
-
- /**
- * 1.queryForObject函数入参带查询条件,入参带参数类型
- * 2.根据基本类型封装返回值
- * 3.查询一条记录的一个字段值
- */
- public static void f5_1_3() {
- // 1.获取查询sql
- String sql = getSelectSql06();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
- // 4.查询数据集
- String cityName = jt.queryForObject(sql, args, argTypes, String.class);
- // 5.遍历结果并打印
- System.out.println(cityName);
- }
-
- /**
- * 1.select语句,查一条数据的一个字段
- * 2.queryForObject函数入参带查询条件
- */
- public static String getSelectSql05() {
- String sql05 = "SELECT\n" +
- " CITY_NAME\n" +
- "FROM t_city limit 1";
- return sql05.toString();
- }
- /**
- * 1.select语句,查一条数据的一个字段
- * 2.queryForObject函数入参带查询条件
- */
- public static String getSelectSql06() {
- String sql06 = "SELECT\n" +
- " CITY_NAME \n" +
- "FROM t_city " +
- "WHERE CITY_NAME = ? AND ID =? limit 1";
- return sql06.toString();
- }
5.2 queryForObject查询一条记录
5.2.1 queryForObject函数定义
queryForObject的以下3个函数,查询一条记录。
参数sql:数据库执行的SQL语句。
参数rowMapper:是RowMapper接口实现类,把数据库返回的结果集表字段与值,封装成自定义的JavaBean对象。
参数args:是SQL中有占位符?时,传入变量的方式。
参数argTypes:是args传入参数对应的数据库表字段的数据类型。
- public
T queryForObject(String sql, RowMapper rowMapper) ; - public
T queryForObject(String sql, RowMapper rowMapper, @Nullable Object... args) ; - public
T queryForObject(String sql, Object[] args, int[] argTypes, RowMapper rowMapper) ;
5.2.2 queryForObject使用场景
场景:使用queryForObject函数,可以把查询结果集按照自定义的JavaBean封装,返回值为JavaBean。
5.2.3 queryForObject使用举例
- /**
- * 1.queryForObject函数入参不带查询条件,如有查询条件直接写在SQL中
- * 2.使用自定义CityRowMapper封装返回值
- * 3.查询一条记录,返回值即自定义对象
- */
- public static void f5_2_1() {
- // 1.获取查询sql
- String sql = getSelectSql03();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.查询数据集
- CityPO cityPO = jt.queryForObject(sql, new CityRowMapper());
- // 4.遍历结果并打印
- System.out.println(cityPO);
- }
- /**
- * 1.queryForObject函数入参带查询条件
- * 2.使用自定义CityRowMapper封装返回值
- * 3.查询一条记录,返回值即自定义对象
- */
- public static void f5_2_2() {
- // 1.获取查询sql
- String sql = getSelectSql04();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- // 4.查询数据集
- CityPO cityPO = jt.queryForObject(sql, new CityRowMapper(), args);
- // 5.遍历结果并打印
- System.out.println(cityPO);
- }
- /**
- * 1.queryForObject函数入参带查询条件,入参带参数类型
- * 2.使用自定义CityRowMapper封装返回值
- * 3.查询一条记录,返回值即自定义对象
- */
- public static void f5_2_3() {
- // 1.获取查询sql
- String sql = getSelectSql04();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
- // 4.查询数据集
- CityPO cityPO = jt.queryForObject(sql, args, argTypes, new CityRowMapper());
- // 5.遍历结果并打印
- System.out.println(cityPO);
- }
-
- /**
- * 1.select语句,查一条数据
- * 2.queryForMap函数入参不带查询条件
- * 3.queryForObject函数入参不带查询条件
- */
- public static String getSelectSql03() {
- String sql01 = "SELECT\n" +
- " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
- " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
- "FROM t_city limit 1";
- return sql01.toString();
- }
-
- /**
- * 1.select语句,查一条数据
- * 2.queryForMap函数入参带查询条件
- * 3.queryForObject函数入参带查询条件
- */
- public static String getSelectSql04() {
- String sql02 = "SELECT\n" +
- " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
- " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
- "FROM t_city " +
- "WHERE CITY_NAME = ? AND ID =? limit 1";
- return sql02.toString();
- }
6.queryForList函数
6.1 queryForList查询多条记录
6.1.1 queryForList函数定义
参数sql:数据库执行的SQL语句。
参数args:是SQL中有占位符?时,传入变量的方式。
参数argTypes:是args传入参数对应的数据库表字段的数据类型。
- public List
- public List
- public List
6.1.2 queryForList使用场景
场景:使用queryForList函数,把查询结果集封装为List
6.1.3 queryForList使用举例
- /**
- * 1.queryForList函数入参不带查询条件,如有查询条件直接写在SQL中
- * 2.使用List
- * 3.使用java.util.stream.Stream遍历结果
- */
- public static void f6_1_1() {
- // 1.获取查询sql
- String sql = getSelectSql01();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.查询数据集
- List
- // 4.遍历结果并打印,使用Stream函数式遍历
- Stream
- System.out.println("遍历List.");
- AtomicInteger i = new AtomicInteger(1);
- stream.forEach(map -> {
- System.out.println("遍历第 " + i + " 条记录.");
- AtomicInteger j = new AtomicInteger(1);
- map.forEach((key, value) -> {
- System.out.println(key + " = " + value.toString());
- });
- i.getAndIncrement();
- });
- }
-
- /**
- * 1.queryForList函数入参带查询条件
- * 2.使用List
- * 3.使用for循环和Map.Entry遍历结果
- */
- public static void f6_1_2() {
- // 1.获取查询sql
- String sql = getSelectSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- // 4.查询数据集
- List
- // 5.遍历结果并打印,使用for遍历
- for (Map
map : list) { - for (Map.Entry
entry : map.entrySet()) { - System.out.println(entry.getKey() + " = " + entry.getValue());
- }
- }
- }
-
- /**
- * 1.queryForList函数入参带查询条件,入参带参数类型
- * 2.使用List
- * 3.使用for循环和while循环和Map.Entry遍历结果
- */
- public static void f6_1_3() {
- // 1.获取查询sql
- String sql = getSelectSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
- // 4.查询数据集
- List
- // 5.遍历结果并打印,使用for遍历,和while遍历
- for (int i = 0; i < list.size(); i++) {
- Map
map = list.get(i); - Iterator
> entries = map.entrySet().iterator(); - while (entries.hasNext()) {
- Map.Entry
entry = entries.next(); - System.out.println(entry.getKey() + " = " + entry.getValue());
- }
- }
- }
-
- /**
- * 1.select语句
- * 2.query函数入参不带查询条件
- * 3.queryForStream函数入参不带查询条件
- * 4.queryForRowSet函数入参不带查询条件
- * 5.queryForList函数入参不带查询条件
- */
- public static String getSelectSql01() {
- String sql01 = "SELECT\n" +
- " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
- " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
- "FROM t_city ";
- return sql01.toString();
- }
- /**
- * 1.select语句
- * 2.query函数入参带查询条件
- * 3.queryForStream函数入参带查询条件
- * 4.queryForRowSet函数入参带查询条件
- * 5.queryForList函数入参带查询条件
- */
- public static String getSelectSql02() {
- String sql02 = "SELECT\n" +
- " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
- " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
- "FROM t_city " +
- "WHERE CITY_NAME = ? AND ID =? ";
- return sql02.toString();
- }
6.2 queryForList查一个字段的多条记录
6.2.1 queryForList函数定义
参数sql:数据库执行的SQL语句。
参数elementType:封装返回值类型。
参数args:是SQL中有占位符?时,传入变量的方式。
参数argTypes:是args传入参数对应的数据库表字段的数据类型。
- public
List queryForList(String sql, Class elementType) ; - public
List queryForList(String sql, Class elementType, @Nullable Object... args) ; - public
List queryForList(String sql, Object[] args, int[] argTypes, Class elementType) ;
6.2.2 queryForList使用场景
场景:使用queryForList函数,把查询结果封装为指定的基本类型,返回值封装在 List
6.2.3 queryForList使用举例
- /**
- * 1.queryForList函数入参不带查询条件,如有查询条件直接写在SQL中
- * 2.查一个字段的多条记录,使用List
封装返回值 - * 3.使用java.util.stream.Stream遍历结果
- */
- public static void f6_2_1() {
- // 1.获取查询sql
- String sql = getSelectSql07();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.查询数据集
- List
list = jt.queryForList(sql, String.class); - // 4.遍历结果并打印
- Stream
stream = list.stream(); - stream.forEach(cityName -> {
- System.out.println(cityName.toString());
- });
- }
-
- /**
- * 1.queryForList函数入参带查询条件
- * 2.查一个字段的多条记录,使用List
封装返回值 - * 3.使用java.util.stream.Stream遍历结果
- */
- public static void f6_2_2() {
- // 1.获取查询sql
- String sql = getSelectSql08();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- // 4.查询数据集
- List
list = jt.queryForList(sql, String.class, args); - // 5.遍历结果并打印
- Stream
stream = list.stream(); - stream.forEach(cityName -> {
- System.out.println(cityName.toString());
- });
- }
-
- /**
- * 1.queryForList函数入参带查询条件,入参带参数类型
- * 2.查一个字段的多条记录,使用List
封装返回值 - * 3.使用java.util.stream.Stream遍历结果
- */
- public static void f6_2_3() {
- // 1.获取查询sql
- String sql = getSelectSql08();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装查询条件
- Object[] args = new Object[]{"杭州", "1"};
- int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
- // 4.查询数据集
- List
list = jt.queryForList(sql, args, argTypes, String.class); - // 5.遍历结果并打印
- Stream
stream = list.stream(); - stream.forEach(cityName -> {
- System.out.println(cityName.toString());
- });
- }
-
- /**
- * 1.select语句,一个字段的多条记录
- * 2.queryForList函数入参不带查询条件
- */
- public static String getSelectSql07() {
- String sql07 = "SELECT\n" +
- " CITY_NAME\n" +
- "FROM t_city ";
- return sql07.toString();
- }
- /**
- * 1.select语句,一个字段的多条记录
- * 2.queryForList函数入参带查询条件
- */
- public static String getSelectSql08() {
- String sql08 = "SELECT\n" +
- " CITY_NAME\n" +
- "FROM t_city " +
- "WHERE CITY_NAME = ? AND ID =? ";
- return sql08.toString();
- }
7.查询函数共用代码
7.1 获取JdbcTemplate实例对象
封装统一方法获取JdbcTemplate,使用时替换为实际数据库连接信息。
- /**
- * 获取一个JdbcTemplate实例对象
- */
- public static JdbcTemplate getJdbcTemplate() {
- String username = "***自定义填写**";
- String password = "***自定义填写**";
- String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/***自定义填写**";
- String driverName = "com.mysql.cj.jdbc.Driver";
- DruidDataSource dataSource = new DruidDataSource();
- dataSource.setPassword(password);
- dataSource.setUrl(jdbcUrl);
- dataSource.setUsername(username);
- dataSource.setDriverClassName(driverName);
- JdbcTemplate jdbcTemplate = new JdbcTemplate();
- jdbcTemplate.setDataSource(dataSource);
- return jdbcTemplate;
- }
7.2 实现RowMapper接口对象
本例CityRowMapper实现RowMapper接口,封装结果集和JavaBean对应关系。
- /**
- * 实现JdbcTemplate的RowMapper接口
- * 数据库查询的字段和自定义JavaBean属性匹配
- */
- private static class CityRowMapper implements RowMapper
{ - @Override
- public CityPO mapRow(ResultSet rs, int rowNum) throws SQLException {
- CityPO cityPO = new CityPO();
- cityPO.setId((Long) rs.getObject("ID"));
- cityPO.setCityName((String) rs.getObject("CITY_NAME"));
- cityPO.setLandArea((Double) rs.getObject("LAND_AREA"));
- cityPO.setPopulation((Long) rs.getObject("POPULATION"));
- cityPO.setGross((Double) rs.getObject("GROSS"));
- cityPO.setCityDescribe((String) rs.getObject("CITY_DESCRIBE"));
- cityPO.setDataYear((String) rs.getObject("DATA_YEAR"));
- cityPO.setUpdateTime((LocalDateTime) rs.getObject("UPDATE_TIME"));
- return cityPO;
- }
- }
7.3 JavaBean对象
JavaBean对象与数据库表字段一一对应,以驼峰法命名。
- @Data
- @NoArgsConstructor
- public class CityPO {
- private long id;
- private String cityName;
- private double landArea;
- private long population;
- private double gross;
- private String cityDescribe;
- private String dataYear;
- private LocalDateTime updateTime;
二、增
增,即使用JdbcTemplate对数据库的数据做插入操作。
SQL关键字:insert into。
1.update函数
1.1 update函数定义
执行数据数据库insert into插入数据,使用update函数实现。
参数sql:数据库执行的SQL语句。
参数pss:对应入参和占位符字段匹配关系。
参数args:是SQL中有占位符?时,传入变量的方式。
参数argTypes:是args传入参数对应的数据库表字段的数据类型。
- public int update(final String sql);
- public int update(String sql, @Nullable Object... args);
- public int update(String sql, @Nullable PreparedStatementSetter pss);
- public int update(String sql, Object[] args, int[] argTypes);
1.2 update使用场景
场景:使用update函数,可以执行数据库的insert into插入数据。
1.3 update使用举例
- /**
- * 1.insert插入语句,使用update函数
- * 2.update函数入参不带插入数据,数据直接写在insert into语句中
- */
- public static void f7_1() {
- // 1.获取插入sql
- String sql = getInsertSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.执行insert into语句
- int result = jt.update(sql);
- // 4.打印返回值
- System.out.println("插入返回值: " + result);
- }
-
- /**
- * 1.insert插入语句,使用update函数
- * 2.update函数入参带插入数据
- */
- public static void f7_2() {
- // 1.获取插入sql
- String sql = getInsertSql01();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装插入参数
- Object[] args = new Object[]{
- "杭州", "16850", "1200", "1.61",
- "杭州是一个好城市", "2020", "2022-07-23 16:39:16"
- };
- // 4.执行insert into语句
- int result = jt.update(sql, args);
- // 5.打印返回值
- System.out.println("插入返回值: " + result);
- }
-
- /**
- * 1.insert插入语句,使用update函数
- * 2.update函数入参带插入数据
- * 3.使用PreparedStatementSetter对应入参和字段关系
- */
- public static void f7_3() {
- // 1.获取插入sql
- String sql = getInsertSql01();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装插入参数
- Object[] args = new Object[]{
- "杭州", "16850", "1200", "1.61",
- "杭州是一个好城市", "2020", "2022-07-23 16:39:18"
- };
- // 4.执行insert语句(插入一条数据)
- int result = jt.update(sql, new PreparedStatementSetter() {
- @Override
- public void setValues(PreparedStatement ps) throws SQLException {
- ps.setObject(1, args[0]);
- ps.setObject(2, args[1]);
- ps.setObject(3, args[2]);
- ps.setObject(4, args[3]);
- ps.setObject(5, args[4]);
- ps.setObject(6, args[5]);
- ps.setObject(7, args[6]);
- }
- });
- // 5.打印返回值
- System.out.println("插入返回值: " + result);
- }
-
- /**
- * 1.insert插入语句,使用update函数
- * 2.update函数入参带插入数据,入参带参数类型
- */
- public static void f7_4() {
- // 1.获取插入sql
- String sql = getInsertSql01();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装插入参数
- Object[] args = new Object[]{
- "杭州", "16850", "1200", "1.61",
- "杭州是一个好城市", "2020", "2022-07-23 16:39:19"
- };
- int[] argTypes = new int[]{Types.VARCHAR,
- Types.DOUBLE, Types.BIGINT, Types.DOUBLE,
- Types.VARCHAR, Types.VARCHAR, Types.TIMESTAMP
- };
- // 4.执行insert语句
- int result = jt.update(sql, args, argTypes);
- // 5.打印返回值
- System.out.println("插入返回值: " + result);
- }
-
- /**
- * 1.insert语句,插入数据
- * 2.update函数入参带插入数据
- */
- public static String getInsertSql01() {
- String sql01 = "INSERT INTO t_city (\n" +
- " CITY_NAME,LAND_AREA,POPULATION,\n" +
- " GROSS,CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
- ")\n" +
- "VALUES (?, ?, ?, ?, ?, ?, ?)";
- return sql01.toString();
- }
-
- /**
- * 1.insert语句,插入数据
- * 2.update函数入参不带插入数据
- */
- public static String getInsertSql02() {
- String sql02 = "INSERT INTO t_city (\n" +
- " CITY_NAME,LAND_AREA,POPULATION,\n" +
- " GROSS,CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME)\n" +
- " VALUES('杭州','16850','1200','1.61',\n" +
- " '杭州是一个好城市','2020','2022-07-23 16:39:16')";
- return sql02.toString();
- }
2.batchUpdate函数
2.1 batchUpdate函数定义
执行数据数据库insert into批量插入数据,使用batchUpdate函数实现。
参数sql:数据库执行的SQL语句。
参数pss:对应入参和占位符字段匹配关系。
参数batchArgs:是SQL中有占位符?时,传入变量的方式。
参数argTypes:是args传入参数对应的数据库表字段的数据类型。
参数batchSize:入参大小,即batchArgs条数。
- public int[] batchUpdate(final String... sql);
- public int[] batchUpdate(String sql, List
- public int[] batchUpdate(String sql, List
- public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss);
- public
int[][] batchUpdate(String sql, final Collection batchArgs, final int batchSize, final ParameterizedPreparedStatementSetter pss);
2.2 batchUpdate使用场景
场景:使用batchUpdate函数,可以执行数据库的insert into批量插入数据。
2.3 batchUpdate使用举例
- /**
- * 1.insert插入语句,使用batchUpdate函数
- * 2.batchUpdate函数入参不带插入数据,数据直接写在insert into语句中
- */
- public static void f8_1() {
- // 1.获取插入sql
- String[] sql = getInsertSql03();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.执行insert语句
- int[] result = jt.batchUpdate(sql);
- // 4.遍历并打印返回值
- List
list = Arrays.stream(result).boxed().collect(Collectors.toList()); - for (Object var : list) {
- System.out.println("返回值: " + var);
- }
- }
-
- /**
- * 1.insert插入语句,使用batchUpdate函数
- * 2.batchUpdate函数入参带插入数据
- */
- public static void f8_2() {
- // 1.获取插入sql
- String sql = getInsertSql01();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装插入参数
- List
- // 4.执行insert语句
- int[] result = jt.batchUpdate(sql, batchArgs);
- // 5.打印返回值
- List
list = Arrays.stream(result).boxed().collect(Collectors.toList()); - for (Object var : list) {
- System.out.println("返回值: " + var);
- }
- }
- /**
- * 1.insert插入语句,使用batchUpdate函数
- * 2.batchUpdate函数入参带插入数据,入参带参数类型
- */
- public static void f8_3() {
- // 1.获取插入sql
- String sql = getInsertSql01();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装插入参数
- List
- int[] argTypes = new int[]{Types.VARCHAR,
- Types.DOUBLE, Types.BIGINT, Types.DOUBLE,
- Types.VARCHAR, Types.VARCHAR, Types.TIMESTAMP
- };
- // 4.执行insert语句
- int[] result = jt.batchUpdate(sql, batchArgs, argTypes);
- // 5.打印返回值
- List
list = Arrays.stream(result).boxed().collect(Collectors.toList()); - for (Object var : list) {
- System.out.println("返回值: " + var);
- }
- }
-
- /**
- * 1.insert插入语句,使用batchUpdate函数
- * 2.batchUpdate函数入参带插入数据
- * 3.使用BatchPreparedStatementSetter对应入参和字段关系
- */
- public static void f8_4() {
- // 1.获取插入sql
- String sql = getInsertSql01();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装插入参数
- List
- // 4.执行insert语句
- int[] result = jt.batchUpdate(sql, new BatchPreparedStatementSetter() {
- @Override
- public void setValues(PreparedStatement ps, int i) throws SQLException {
- // 第一行开始
- Object[] args = batchArgs.get(i);
- ps.setObject(1, args[0]);
- ps.setObject(2, args[1]);
- ps.setObject(3, args[2]);
- ps.setObject(4, args[3]);
- ps.setObject(5, args[4]);
- ps.setObject(6, args[5]);
- ps.setObject(7, args[6]);
- }
- @Override
- public int getBatchSize() {
- return batchArgs.size();
- }
- });
- // 5.打印返回值
- List
list = Arrays.stream(result).boxed().collect(Collectors.toList()); - for (Object var : list) {
- System.out.println("返回值: " + var);
- }
- }
-
- /**
- * 1.insert插入语句,使用batchUpdate函数
- * 2.batchUpdate函数入参带插入数据
- * 3.使用ParameterizedPreparedStatementSetter对应入参和字段关系
- */
- public static void f8_5() {
- // 1.获取插入sql
- String sql = getInsertSql01();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装插入参数
- List
- // 4.执行insert语句
- int[][] result = jt.batchUpdate(sql, batchArgs, batchArgs.size(),
- new ParameterizedPreparedStatementSetter() {
- @Override
- public void setValues(PreparedStatement ps, Object argument) throws SQLException {
- Object[] args = (Object[]) argument;
- ps.setObject(1, args[0]);
- ps.setObject(2, args[1]);
- ps.setObject(3, args[2]);
- ps.setObject(4, args[3]);
- ps.setObject(5, args[4]);
- ps.setObject(6, args[5]);
- ps.setObject(7, args[6]);
- }
- });
- // 5.打印返回值
- for (int[] ints : result) {
- for (int anInt : ints) {
- System.out.println("返回值: " + anInt);
- }
- }
- }
-
- /**
- * 1.insert语句,插入数据
- * 2.update函数入参带插入数据
- */
- public static String getInsertSql01() {
- String sql01 = "INSERT INTO t_city (\n" +
- " CITY_NAME,LAND_AREA,POPULATION,\n" +
- " GROSS,CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
- ")\n" +
- "VALUES (?, ?, ?, ?, ?, ?, ?)";
- return sql01.toString();
- }
-
- /**
- * 1.insert语句,插入数据
- * 2.update函数入参不带插入数据
- */
- public static String[] getInsertSql03() {
- String sql01 = "INSERT INTO t_city (\n" +
- " CITY_NAME,LAND_AREA,POPULATION,\n" +
- " GROSS,CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME)\n" +
- " VALUES('杭州','16850','1200','1.61',\n" +
- " '杭州是一个好城市','2020','2022-07-23 16:39:16')";
- String sql02 = "INSERT INTO t_city (\n" +
- " CITY_NAME,LAND_AREA,POPULATION,\n" +
- " GROSS,CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME)\n" +
- " VALUES('杭州','16850','1200','1.81',\n" +
- " '杭州是一个好城市','2021','2022-07-23 16:39:19')";
- return new String[]{sql01, sql02};
- }
- /**
- * 1.执行数据库insert into语句
- * 2.获取批量插入数据
- */
- public static List
- Object[] args1 = new Object[]{
- "杭州", "16850", "1200", "1.61",
- "杭州是一个好城市", "2020", "2022-07-23 16:39:51"
- };
- Object[] args2 = new Object[]{
- "杭州", "16850", "1200", "1.81",
- "杭州是一个好城市", "2021", "2022-07-23 16:39:52"
- };
- List
- batchArgs.add(args1);
- batchArgs.add(args2);
- return batchArgs;
- }
三、改
改,即使用JdbcTemplate对数据库的数据做修改操作。
SQL关键字:update。
1.update函数
1.1 update函数定义
执行数据数据库update修改数据,使用update函数实现。
参数sql:数据库执行的SQL语句。
参数pss:对应入参和占位符字段匹配关系。
参数args:是SQL中有占位符?时,传入变量的方式。
参数argTypes:是args传入参数对应的数据库表字段的数据类型。
- public int update(final String sql);
- public int update(String sql, @Nullable Object... args);
- public int update(String sql, @Nullable PreparedStatementSetter pss);
- public int update(String sql, Object[] args, int[] argTypes);
1.2 update使用场景
场景:使用update函数,可以执行数据库的update需改数据。
1.3 update使用举例
- /**
- * 1.update修改数据语句,使用update函数
- * 2.update函数入参不带修改数据,数据直接写在update语句中
- */
- public static void f9_1() {
- // 1.获取修改sql
- String sql = getUpdateSql01();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.执行update语句
- int result = jt.update(sql);
- // 4.遍历并打印返回值
- System.out.println("返回值: " + result);
- }
- /**
- * 1.update修改数据语句,使用update函数
- * 2.update函数入参带修改数据
- */
- public static void f9_2() {
- // 1.获取修改sql
- String sql = getUpdateSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装修改参数
- Object[] args = new Object[]{"杭州是互联网城市", "2022-07-23 17:39:51", "杭州", "1"};
- // 4.执行update语句
- int result = jt.update(sql, args);
- // 5.打印返回值
- System.out.println("插入返回值: " + result);
- }
- /**
- * 1.update修改数据语句,使用update函数
- * 2.update函数入参带修改数据
- * 3.使用PreparedStatementSetter对应入参和字段关系
- */
- public static void f9_3() {
- // 1.获取修改sql
- String sql = getUpdateSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装修改参数
- Object[] args = new Object[]{"杭州是互联网城市", "2022-07-23 16:39:22", "杭州", "1"};
- // 4.执行update语句
- int result = jt.update(sql, new PreparedStatementSetter() {
- @Override
- public void setValues(PreparedStatement ps) throws SQLException {
- ps.setObject(1, args[0]);
- ps.setObject(2, args[1]);
- ps.setObject(3, args[2]);
- ps.setObject(4, args[3]);
- }
- });
- // 5.打印返回值
- System.out.println("插入返回值: " + result);
- }
- /**
- * 1.update修改数据语句,使用update函数
- * 2.update函数入参带修改数据,入参带参数类型
- */
- public static void f9_4() {
- // 1.获取修改sql
- String sql = getUpdateSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装修改参数
- Object[] args = new Object[]{"杭州是互联网城市", "2022-07-23 16:39:35", "杭州", "1"};
-
- int[] argTypes = new int[]{Types.VARCHAR, Types.TIMESTAMP,
- Types.VARCHAR, Types.BIGINT
- };
- // 4.执行update语句
- int result = jt.update(sql, args, argTypes);
- // 5.打印返回值
- System.out.println("插入返回值: " + result);
- }
-
- /**
- * 1.update语句修改数据
- * 2.update函数入参不带修改数据
- */
- public static String getUpdateSql01() {
- String sql = "UPDATE t_city\n" +
- "SET CITY_DESCRIBE = '杭州是互联网城市'\n" +
- "WHERE CITY_NAME = '杭州' AND ID = '1' ";
- return sql.toString();
- }
-
- /**
- * 1.update语句,修改数据
- * 2.使用update函数入参带修改数据
- * 3.使用batchUpdate函数入参带修改数据
- */
- public static String getUpdateSql02() {
- String sql = "UPDATE t_city\n" +
- "SET CITY_DESCRIBE = ?,UPDATE_TIME = ?\n" +
- "WHERE CITY_NAME = ? AND ID = ? ";
- return sql.toString();
- }
2.batchUpdate函数
2.1 batchUpdate函数定义
执行数据数据库update批量修改数据,使用batchUpdate函数实现。
参数sql:数据库执行的SQL语句。
参数pss:对应入参和占位符字段匹配关系。
参数batchArgs:是SQL中有占位符?时,传入变量的方式。
参数argTypes:是args传入参数对应的数据库表字段的数据类型。
参数batchSize:入参大小,即batchArgs条数。
- public int[] batchUpdate(final String... sql);
- public int[] batchUpdate(String sql, List
- public int[] batchUpdate(String sql, List
- public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss);
- public
int[][] batchUpdate(String sql, final Collection batchArgs, final int batchSize, final ParameterizedPreparedStatementSetter pss);
2.2 batchUpdate使用场景
场景:使用batchUpdate函数,可以执行数据库的update批量修改数据。
2.3 batchUpdate使用举例
- /**
- * 1.update修改数据语句,使用batchUpdate函数
- * 2.batchUpdate函数入参不带修改数据,数据直接写在update语句中
- */
- public static void f10_1() {
- // 1.获取修改sql
- String[] sql = getUpdateSql03();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.执行update语句
- int[] result = jt.batchUpdate(sql);
- // 4.遍历并打印返回值
- List
list = Arrays.stream(result).boxed().collect(Collectors.toList()); - for (Object var : list) {
- System.out.println("返回值: " + var);
- }
- }
- /**
- * 1.update修改数据语句,使用batchUpdate函数
- * 2.batchUpdate函数入参带修改数据
- */
- public static void f10_2() {
- // 1.获取修改sql
- String sql = getUpdateSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装修改参数
- List
- // 4.执行update语句
- int[] result = jt.batchUpdate(sql, batchArgs);
- // 5.打印返回值
- List
list = Arrays.stream(result).boxed().collect(Collectors.toList()); - for (Object var : list) {
- System.out.println("返回值: " + var);
- }
- }
- /**
- * 1.update修改数据语句,使用batchUpdate函数
- * 2.batchUpdate函数入参带修改数据,入参带参数类型
- */
- public static void f10_3() {
- // 1.获取修改sql
- String sql = getUpdateSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装修改参数
- List
- int[] argTypes = new int[]{Types.VARCHAR, Types.TIMESTAMP,
- Types.VARCHAR, Types.BIGINT
- };
- // 4.执行update语句
- int[] result = jt.batchUpdate(sql, batchArgs, argTypes);
- // 5.打印返回值
- List
list = Arrays.stream(result).boxed().collect(Collectors.toList()); - for (Object var : list) {
- System.out.println("返回值: " + var);
- }
- }
- /**
- * 1.update修改数据语句,使用batchUpdate函数
- * 2.batchUpdate函数入参带修改数据
- * 3.使用BatchPreparedStatementSetter对应入参和字段关系
- */
- public static void f10_4() {
- // 1.获取修改sql
- String sql = getUpdateSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装修改参数
- List
- // 4.执行update语句
- int[] result = jt.batchUpdate(sql, new BatchPreparedStatementSetter() {
- @Override
- public void setValues(PreparedStatement ps, int i) throws SQLException {
- // 第一行开始
- Object[] args = batchArgs.get(i);
- ps.setObject(1, args[0]);
- ps.setObject(2, args[1]);
- ps.setObject(3, args[2]);
- ps.setObject(4, args[3]);
- }
-
- @Override
- public int getBatchSize() {
- return batchArgs.size();
- }
- });
- // 5.打印返回值
- List
list = Arrays.stream(result).boxed().collect(Collectors.toList()); - for (Object var : list) {
- System.out.println("返回值: " + var);
- }
- }
- /**
- * 1.update修改数据语句,使用batchUpdate函数
- * 2.batchUpdate函数入参带修改数据
- * 3.使用ParameterizedPreparedStatementSetter对应入参和字段关系
- */
- public static void f10_5() {
- // 1.获取修改sql
- String sql = getUpdateSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装修改参数
- List
- // 4.执行update语句
- int[][] result = jt.batchUpdate(sql, batchArgs, batchArgs.size(),
- new ParameterizedPreparedStatementSetter() {
- @Override
- public void setValues(PreparedStatement ps, Object argument) throws SQLException {
- Object[] args = (Object[]) argument;
- ps.setObject(1, args[0]);
- ps.setObject(2, args[1]);
- ps.setObject(3, args[2]);
- ps.setObject(4, args[3]);
- }
- });
- // 5.打印返回值
- for (int[] ints : result) {
- for (int anInt : ints) {
- System.out.println("返回值: " + anInt);
- }
- }
- }
-
- /**
- * 1.update语句,修改数据
- * 2.使用update函数入参带修改数据
- * 3.使用batchUpdate函数入参带修改数据
- */
- public static String getUpdateSql02() {
- String sql = "UPDATE t_city\n" +
- "SET CITY_DESCRIBE = ?,UPDATE_TIME = ?\n" +
- "WHERE CITY_NAME = ? AND ID = ? ";
- return sql.toString();
- }
-
- /**
- * 1.update语句修改数据
- * 2.使用batchUpdate函数入参不带修改数据
- */
- public static String[] getUpdateSql03() {
- String sql01 = "UPDATE t_city\n" +
- "SET CITY_DESCRIBE = '杭州是互联网城市01'\n" +
- "WHERE CITY_NAME = '杭州' AND ID = '1' ";
-
- String sql02 = "UPDATE t_city\n" +
- "SET CITY_DESCRIBE = '杭州是互联网城市02'\n" +
- "WHERE CITY_NAME = '杭州' AND ID = '2' ";
- return new String[]{sql01, sql02};
- }
- /**
- * 1.执行数据库update语句
- * 2.获取批量修改数据
- */
- public static List
- Object[] args1 = new Object[]{"杭州是互联网城市01", "2022-07-23 16:39:57", "杭州", "1"};
- Object[] args2 = new Object[]{"杭州是互联网城市02", "2022-07-23 16:39:58", "杭州", "2"};
- List
- batchArgs.add(args1);
- batchArgs.add(args2);
- return batchArgs;
- }
四、删
删,即使用JdbcTemplate对数据库的数据做删除操作。
SQL关键字:delete。
1.update函数
1.1 update函数定义
执行数据数据库delete删除数据,使用update函数实现。
参数sql:数据库执行的SQL语句。
参数pss:对应入参和占位符字段匹配关系。
参数args:是SQL中有占位符?时,传入变量的方式。
参数argTypes:是args传入参数对应的数据库表字段的数据类型。
- public int update(final String sql);
- public int update(String sql, @Nullable Object... args);
- public int update(String sql, @Nullable PreparedStatementSetter pss);
- public int update(String sql, Object[] args, int[] argTypes);
1.2 update使用场景
场景:使用update函数,可以执行数据库的delete删除数据。
1.3 update使用举例
- /**
- * 1.delete删除语句,使用update函数
- * 2.update函数入参不带删除数据,数据直接写在delete语句中
- */
- public static void f11_1() {
- // 1.获取删除sql
- String sql = getDeleteSql01();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.执行delete语句
- int result = jt.update(sql);
- // 4.遍历并打印返回值
- System.out.println("返回值: " + result);
- }
- /**
- * 1.delete删除语句,使用update函数
- * 2.update函数入参带删除数据
- */
- public static void f11_2() {
- // 1.获取删除sql
- String sql = getDeleteSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装删除条件参数
- Object[] args = new Object[]{"杭州", "1"};
- // 4.执行delete语句
- int result = jt.update(sql, args);
- // 5.打印返回值
- System.out.println("插入返回值: " + result);
- }
- /**
- * 1.delete删除语句,使用update函数
- * 2.update函数入参带删除数据
- * 3.使用PreparedStatementSetter对应入参和字段关系
- */
- public static void f11_3() {
- // 1.获取删除sql
- String sql = getDeleteSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装删除条件参数
- Object[] args = new Object[]{"杭州", "1"};
- // 4.执行delete语句
- int result = jt.update(sql, new PreparedStatementSetter() {
- @Override
- public void setValues(PreparedStatement ps) throws SQLException {
- ps.setObject(1, args[0]);
- ps.setObject(2, args[1]);
- }
- });
- // 5.打印返回值
- System.out.println("插入返回值: " + result);
- }
-
- /**
- * 1.delete删除语句,使用update函数
- * 2.update函数入参带删除数据,入参带参数类型
- */
- public static void f11_4() {
- // 1.获取删除sql
- String sql = getDeleteSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装删除条件参数
- Object[] args = new Object[]{"杭州", "1"};
- int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
- // 4.执行delete语句
- int result = jt.update(sql, args, argTypes);
- // 5.打印返回值
- System.out.println("插入返回值: " + result);
- }
-
- /**
- * 1.delete语句,删除数据
- * 2.使用update函数
- */
- public static String getDeleteSql01() {
- String sql = "DELETE FROM t_city WHERE CITY_NAME = '杭州' AND ID = '1' ";
- return sql.toString();
- }
-
- /**
- * 1.delete语句,删除数据
- * 2.使用update函数
- */
- public static String getDeleteSql02() {
- String sql = "DELETE FROM t_city WHERE CITY_NAME = ? AND ID = ?";
- return sql.toString();
- }
2.batchUpdate函数
2.1 batchUpdate函数定义
执行数据数据库delete批量删除数据,使用batchUpdate函数实现。
参数sql:数据库执行的SQL语句。
参数pss:对应入参和占位符字段匹配关系。
参数batchArgs:是SQL中有占位符?时,传入变量的方式。
参数argTypes:是args传入参数对应的数据库表字段的数据类型。
参数batchSize:入参大小,即batchArgs条数。
- public int[] batchUpdate(final String... sql);
- public int[] batchUpdate(String sql, List
- public int[] batchUpdate(String sql, List
- public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss);
- public
int[][] batchUpdate(String sql, final Collection batchArgs, final int batchSize, final ParameterizedPreparedStatementSetter pss);
2.2 batchUpdate使用场景
场景:使用batchUpdate函数,可以执行数据库的delete批量删除数据。
2.3 batchUpdate使用举例
- /**
- * 1.delete删除语句,使用batchUpdate函数
- * 2.batchUpdate函数入参不带删除数据,数据直接写在delete语句中
- */
- public static void f12_1() {
- // 1.获取删除sql
- String[] sql = getDeleteSql03();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.执行delete语句
- int[] result = jt.batchUpdate(sql);
- // 4.遍历并打印返回值
- List
list = Arrays.stream(result).boxed().collect(Collectors.toList()); - for (Object var : list) {
- System.out.println("返回值: " + var);
- }
- }
- /**
- * 1.delete删除语句,使用batchUpdate函数
- * 2.batchUpdate函数入参带删除数据
- */
- public static void f12_2() {
- // 1.获取删除sql
- String sql = getDeleteSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装删除条件参数
- List
- // 4.执行delete语句
- int[] result = jt.batchUpdate(sql, batchArgs);
- // 5.打印返回值
- List
list = Arrays.stream(result).boxed().collect(Collectors.toList()); - for (Object var : list) {
- System.out.println("返回值: " + var);
- }
- }
- /**
- * 1.delete删除语句,使用batchUpdate函数
- * 2.batchUpdate函数入参带删除数据,入参带参数类型
- */
- public static void f12_3() {
- // 1.获取删除sql
- String sql = getDeleteSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装删除条件参数
- List
- int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
- // 4.执行delete语句
- int[] result = jt.batchUpdate(sql, batchArgs, argTypes);
- // 5.打印返回值
- List
list = Arrays.stream(result).boxed().collect(Collectors.toList()); - for (Object var : list) {
- System.out.println("返回值: " + var);
- }
- }
- /**
- * 1.delete删除语句,使用batchUpdate函数
- * 2.batchUpdate函数入参带删除数据
- * 3.使用BatchPreparedStatementSetter对应入参和字段关系
- */
- public static void f12_4() {
- // 1.获取删除sql
- String sql = getDeleteSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装删除条件参数
- List
- // 4.执行delete语句
- int[] result = jt.batchUpdate(sql, new BatchPreparedStatementSetter() {
- @Override
- public void setValues(PreparedStatement ps, int i) throws SQLException {
- // 第一行开始
- Object[] args = batchArgs.get(i);
- ps.setObject(1, args[0]);
- ps.setObject(2, args[1]);
- }
-
- @Override
- public int getBatchSize() {
- return batchArgs.size();
- }
- });
- // 5.打印返回值
- List
list = Arrays.stream(result).boxed().collect(Collectors.toList()); - for (Object var : list) {
- System.out.println("返回值: " + var);
- }
- }
- /**
- * 1.delete删除语句,使用batchUpdate函数
- * 2.batchUpdate函数入参带删除数据
- * 3.使用ParameterizedPreparedStatementSetter对应入参和字段关系
- */
- public static void f12_5() {
- // 1.获取删除sql
- String sql = getDeleteSql02();
- // 2.获取JdbcTemplate
- JdbcTemplate jt = getJdbcTemplate();
- // 3.组装删除条件参数
- List
- // 4.执行delete语句
- int[][] result = jt.batchUpdate(sql, batchArgs, batchArgs.size(),
- new ParameterizedPreparedStatementSetter() {
- @Override
- public void setValues(PreparedStatement ps, Object argument) throws SQLException {
- Object[] args = (Object[]) argument;
- ps.setObject(1, args[0]);
- ps.setObject(2, args[1]);
- }
- });
- // 5.打印返回值
- for (int[] ints : result) {
- for (int anInt : ints) {
- System.out.println("返回值: " + anInt);
- }
- }
- }
-
- /**
- * 1.delete语句,删除数据
- * 2.使用update函数
- */
- public static String getDeleteSql02() {
- String sql = "DELETE FROM t_city WHERE CITY_NAME = ? AND ID = ?";
- return sql.toString();
- }
-
- /**
- * 1.delete语句,删除数据
- * 2.使用batchUpdate函数
- */
- public static String[] getDeleteSql03() {
- String sql01 = "DELETE FROM t_city WHERE CITY_NAME = '杭州' AND ID = '1' ";
- String sql02 = "DELETE FROM t_city WHERE CITY_NAME = '杭州' AND ID = '2' ";
- return new String[]{sql01, sql02};
- }
-
- /**
- * 1.delete语句
- * 2.获取批量删除参数
- */
- public static List
- Object[] args1 = new Object[]{"杭州", "1"};
- Object[] args2 = new Object[]{"杭州", "2"};
- List
- batchArgs.add(args1);
- batchArgs.add(args2);
- return batchArgs;
- }
五、支撑
针对本例使用JdbcTemplate对数据库的数据做查增改删操作,使用到的建表语句和数据初始化语句。
1.建表语句
建表语句,主键使用了MySQL的自增功能,即插入一条数据,可以不用赋值,但是赋值的话需判断不重复即可。
- CREATE TABLE t_city (
- ID BIGINT(16) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '主键',
- CITY_NAME VARCHAR(64) COLLATE utf8_bin NOT NULL COMMENT '城市名',
- LAND_AREA DOUBLE DEFAULT NULL COMMENT '城市面积',
- POPULATION BIGINT(16) DEFAULT NULL COMMENT '城市人口',
- GROSS DOUBLE DEFAULT NULL COMMENT '生产总值',
- CITY_DESCRIBE VARCHAR(512) COLLATE utf8_bin DEFAULT NULL COMMENT '城市描述',
- DATA_YEAR VARCHAR(16) COLLATE utf8_bin DEFAULT NULL COMMENT '数据年份',
- UPDATE_TIME DATETIME DEFAULT NULL COMMENT '更新时间'
- ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='城市信息表';
2.插入语句
插入语句,插入数据便于验证查询、更新、删除功能。
- INSERT INTO t_city (
- ID,CITY_NAME,LAND_AREA,POPULATION,
- GROSS,CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME)
- VALUES
- ('1','杭州','16850','1200','1.61','杭州是一个好城市','2020','2022-07-23 16:39:16'),
- ('2','杭州','16850','1200','1.81','杭州是一个好城市','2021','2022-07-23 16:39:16');
六、JdbcTemplate源码窥探
JdbcTemplate源码调用逻辑,以queryForList的如下函数为例。
public List
1.初始化JdbcTemplate
创建JdbcTemplate实例对象,
(1)可以设置fetchSize,每次加载条数。
(2)可以设置queryTimeout,执行SQL的超时时间,减低超时锁表等风险。
(3)可以设置maxRows,限制查询最大条数。降低大数据量拖库风险。
- /**
- * 获取一个JdbcTemplate实例对象
- */
- public static JdbcTemplate getJdbcTemplate() {
- String username = "***自定义填写**";
- String password = "***自定义填写**";
- String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/***自定义填写**";
- String driverName = "com.mysql.cj.jdbc.Driver";
- DruidDataSource dataSource = new DruidDataSource();
- dataSource.setPassword(password);
- dataSource.setUrl(jdbcUrl);
- dataSource.setUsername(username);
- dataSource.setDriverClassName(driverName);
- JdbcTemplate jdbcTemplate = new JdbcTemplate();
- jdbcTemplate.setDataSource(dataSource);
- return jdbcTemplate;
- }
2.调用queryForList
调用queryForList,具体可以查看queryForList举例。
(1)调用query函数。
(2)调用getColumnMapRowMapper,会创建ColumnMapRowMapper对数据库数据集以字段名称和字段值映射到Map的key和value中。
- public List
- return this.query(sql, args, this.getColumnMapRowMapper());
- }
3.调用query
调用query,创建RowMapperResultSetExtractor,处理结果集的实例对象。
- public
List query(String sql, @Nullable Object[] args, RowMapper rowMapper) throws DataAccessException { - return (List)result(this.query((String)sql, (Object[])args, (ResultSetExtractor)(new RowMapperResultSetExtractor(rowMapper))));
- }
4.调用query
调用query,创建ArgumentPreparedStatementSetter,处理参数的实例对象。
- public
T query(String sql, @Nullable Object[] args, ResultSetExtractor rse) throws DataAccessException { - return this.query(sql, this.newArgPreparedStatementSetter(args), rse);
- }
5.调用query
调用query,创建SimplePreparedStatementCreator,处理SQL的实例对象。
- public
T query(String sql, @Nullable PreparedStatementSetter pss, ResultSetExtractor rse) throws DataAccessException { - return this.query((PreparedStatementCreator)(new JdbcTemplate.SimplePreparedStatementCreator(sql)), (PreparedStatementSetter)pss, (ResultSetExtractor)rse);
- }
6.调用query
调用query,在此函数中做如下操作
6.1创建PreparedStatementCallback匿名对象
创建PreparedStatementCallback接口的匿名对象,实现doInPreparedStatement方法。
(1)设置PreparedStatementSetter对应关系
(2)执行PreparedStatement的executeQuery函数执行SQL
(3)获取执行结果集ResultSet,executeQuery执行后即返回结果集。
(4)执行ResultSetExtractor的extractData处理结果集
(5)执行JdbcUtils.closeResultSet关闭结果集
6.2执行execute函数
步骤一中的PreparedStatementCallback接口的匿名对象实现类传入execute函数具体执行。
- public
T query(PreparedStatementCreator psc, @Nullable final PreparedStatementSetter pss, final ResultSetExtractor rse) throws DataAccessException { - Assert.notNull(rse, "ResultSetExtractor must not be null");
- this.logger.debug("Executing prepared SQL query");
- return this.execute(psc, new PreparedStatementCallback
() { - @Nullable
- public T doInPreparedStatement(PreparedStatement ps) throws SQLException {
- ResultSet rs = null;
- Object var3;
- try {
- if (pss != null) {
- pss.setValues(ps);
- }
- rs = ps.executeQuery();
- var3 = rse.extractData(rs);
- } finally {
- JdbcUtils.closeResultSet(rs);
- if (pss instanceof ParameterDisposer) {
- ((ParameterDisposer)pss).cleanupParameters();
- }
- }
- return var3;
- }
- }, true);
- }
7.execute函数
调用execute函数,做具体操作。
7.1获取SQL语句
从PreparedStatementCreator对象中获取处理过的SQ语句。
7.2 获取连接对象Connection
Connection对象是java.sql.Connection,是Java原生操作数据库的连接类。获取数据库数据源连接信息。
7.3 创建PreparedStatement对象
创建PreparedStatement实例对象,根据连接信息和Connection对象创建PreparedStatement实例对象。
7.4 执行PreparedStatementCallback的doInPreparedStatement
PreparedStatementCallback接口对象在入参时候,以匿名对象方式做了实现类。执行6.1步骤中定义的流程。
1>设置PreparedStatementSetter对应关系
2>执行PreparedStatement的executeQuery函数执行SQL
3>获取执行结果集ResultSet,executeQuery执行后即返回结果集。
4>执行ResultSetExtractor的extractData处理结果集
5>执行JdbcUtils.closeResultSet关闭结果集
6>结果集以Object类型返回
7.5 获取结果集对象Object
结果集对象Object,即执行PreparedStatementCallback的doInPreparedStatement的返回值。
7.6 异常处理(catch)
在catch中做异常处理,如果执行过程抛出异常。
1>使用JdbcUtils.closeStatement关闭PreparedStatement对象。
2>使用DataSourceUtils.releaseConnection释放连接,释放资源。
3>抛出异常给调用者,去捕获处理。
7.7 finally处理
1>使用JdbcUtils.closeStatement关闭PreparedStatement对象。
2>使用DataSourceUtils.releaseConnection释放连接,释放资源。
- private
T execute(PreparedStatementCreator psc, PreparedStatementCallback action, boolean closeResources) throws DataAccessException { - Assert.notNull(psc, "PreparedStatementCreator must not be null");
- Assert.notNull(action, "Callback object must not be null");
- if (this.logger.isDebugEnabled()) {
- String sql = getSql(psc);
- this.logger.debug("Executing prepared SQL statement" + (sql != null ? " [" + sql + "]" : ""));
- }
- Connection con = DataSourceUtils.getConnection(this.obtainDataSource());
- PreparedStatement ps = null;
- Object var14;
- try {
- ps = psc.createPreparedStatement(con);
- this.applyStatementSettings(ps);
- T result = action.doInPreparedStatement(ps);
- this.handleWarnings((Statement)ps);
- var14 = result;
- } catch (SQLException var11) {
- if (psc instanceof ParameterDisposer) {
- ((ParameterDisposer)psc).cleanupParameters();
- }
- String sql = getSql(psc);
- psc = null;
- JdbcUtils.closeStatement(ps);
- ps = null;
- DataSourceUtils.releaseConnection(con, this.getDataSource());
- con = null;
- throw this.translateException("PreparedStatementCallback", sql, var11);
- } finally {
- if (closeResources) {
- if (psc instanceof ParameterDisposer) {
- ((ParameterDisposer)psc).cleanupParameters();
- }
- JdbcUtils.closeStatement(ps);
- DataSourceUtils.releaseConnection(con, this.getDataSource());
- }
-
- }
- return var14;
- }
以下步骤,已经是比较底层内容了。
8.窥探execute函数底层调用
8.1调用getConnection获取Connection
使用DataSourceUtils.getConnection获取Connection。
底层调用dataSource.getConnection(),即javax.sql.DataSource的方法。
8.2调用executeQuery
executeQuery函数是实现java.sql.PreparedStatement底层接口函数。
本例实现类是:com.mysql.cj.jdbc.PreparedStatementWrapper,即MySQL驱动包里面类,例如下:
- public ResultSet executeQuery() throws SQLException {
- ResultSet rs = null;
- try {
- if (this.wrappedStmt == null) {
- throw SQLError.createSQLException(Messages.getString("Statement.AlreadyClosed"), "S1000", this.exceptionInterceptor);
- }
- rs = ((PreparedStatement)this.wrappedStmt).executeQuery();
- ((ResultSetInternalMethods)rs).setWrapperStatement(this);
- } catch (SQLException var3) {
- this.checkAndFireConnectionError(var3);
- }
- return rs;
- }
8.3调用extractData
调用extractData,即org.springframework.jdbc.core.RowMapperResultSetExtractor
本质上还是去遍历ResultSet结果集去包装返回值,
ResultSet,即java.sql.ResultSet,也是底层原始Java的类。
- public List
extractData(ResultSet rs) throws SQLException { - List
results = this.rowsExpected > 0 ? new ArrayList(this.rowsExpected) : new ArrayList(); - int var3 = 0;
- while(rs.next()) {
- results.add(this.rowMapper.mapRow(rs, var3++));
- }
- return results;
- }
以上,感谢。
2022年8月6日