• 基于Spring Boot应用JdbcTemplate操作数据库(查增改删)


    记录:289

    场景:基于Spring Boot应用JdbcTemplate操作数据库。包括查、增、改、删操作。对应SQL关键字是select、insert into、update、delete。

    版本:

    1. Spring Boot 2.6.3
    2. Spring Framework 5.3.15
    3. MySQL 5.7.33
    4. 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传入参数对应的数据库表字段的数据类型。

    1. public List query(String sql, RowMapper rowMapper);
    2. public List query(String sql, RowMapper rowMapper, @Nullable Object... args);
    3. public List query(String sql, Object[] args, int[] argTypes, RowMapper rowMapper);

    1.2 query使用场景

    场景:使用query函数,可以把查询结果集按照自定义的JavaBean封装,并以List方式返回查询结果集。

    1.3 query使用举例

    1. /**
    2. * 1.query函数入参不带查询条件,如有查询条件直接写在SQL中
    3. * 2.使用自定义CityRowMapper封装返回值
    4. * 3.使用java.util.stream.Stream遍历结果
    5. */
    6. public static void f1_1() {
    7. // 1.获取查询sql
    8. String sql = getSelectSql01();
    9. // 2.获取JdbcTemplate
    10. JdbcTemplate jt = getJdbcTemplate();
    11. // 3.查询数据集
    12. List list = jt.query(sql, new CityRowMapper());
    13. // 4.遍历结果并打印
    14. Stream stream = list.stream().parallel();
    15. stream.forEach(cityPO -> {
    16. System.out.println(cityPO.toString());
    17. });
    18. }
    19. /**
    20. * 1.query函数入参带查询条件
    21. * 2.使用自定义CityRowMapper封装返回值
    22. * 3.使用java.util.stream.Stream遍历结果
    23. */
    24. public static void f1_2() {
    25. // 1.获取查询sql
    26. String sql = getSelectSql02();
    27. // 2.获取JdbcTemplate
    28. JdbcTemplate jt = getJdbcTemplate();
    29. // 3.组装查询条件
    30. Object[] args = new Object[]{"杭州", "1"};
    31. // 4.查询数据集
    32. List list = jt.query(sql, new CityRowMapper(), args);
    33. // 5.遍历结果并打印
    34. Stream stream = list.stream().parallel();
    35. stream.forEach(cityPO -> {
    36. System.out.println(cityPO.toString());
    37. });
    38. }
    39. /**
    40. * 1.query函数入参带查询条件,入参带参数类型
    41. * 2.使用自定义CityRowMapper封装返回值
    42. * 3.使用java.util.stream.Stream遍历结果
    43. */
    44. public static void f1_3() {
    45. // 1.获取查询sql
    46. String sql = getSelectSql02();
    47. // 2.获取JdbcTemplate
    48. JdbcTemplate jt = getJdbcTemplate();
    49. // 3.组装查询条件
    50. Object[] args = new Object[]{"杭州", "1"};
    51. int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
    52. // 4.查询数据集
    53. List list = jt.query(sql, args, argTypes, new CityRowMapper());
    54. // 5.遍历结果并打印
    55. Stream stream = list.stream().parallel();
    56. stream.forEach(cityPO -> {
    57. System.out.println(cityPO.toString());
    58. });
    59. }
    60. /**
    61. * 1.query函数入参带查询条件
    62. * 2.使用BeanPropertyRowMapper封装返回值
    63. * 3.使用java.util.stream.Stream遍历结果
    64. */
    65. public static void f1_4() {
    66. // 1.获取查询sql
    67. String sql = getSelectSql02();
    68. // 2.获取JdbcTemplate
    69. JdbcTemplate jt = getJdbcTemplate();
    70. // 3.组装查询条件
    71. Object[] args = new Object[]{"杭州", "1"};
    72. // 4.查询数据集
    73. List list = jt.query(sql, new BeanPropertyRowMapper<>(CityPO.class), args);
    74. // 5.遍历结果并打印
    75. Stream stream = list.stream().parallel();
    76. stream.forEach(cityPO -> {
    77. System.out.println(cityPO.toString());
    78. });
    79. }
    80. /**
    81. * 1.select语句
    82. * 2.query函数入参不带查询条件
    83. */
    84. public static String getSelectSql01() {
    85. String sql01 = "SELECT\n" +
    86. " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
    87. " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
    88. "FROM t_city ";
    89. return sql01.toString();
    90. }
    91. /**
    92. * 1.select语句
    93. * 2.query函数入参带查询条件
    94. */
    95. public static String getSelectSql02() {
    96. String sql02 = "SELECT\n" +
    97. " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
    98. " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
    99. "FROM t_city " +
    100. "WHERE CITY_NAME = ? AND ID =? ";
    101. return sql02.toString();
    102. }

    2.queryForStream函数

    2.1 queryForStream函数定义

    Stream,即java.util.stream.Stream,这个接口有点意思,值得花时间研究一下。

    参数sql:数据库执行的SQL语句。

    参数rowMapper:是RowMapper接口实现类,把数据库返回的结果集表字段与值,封装成自定义的JavaBean对象。

    参数args:是SQL中有占位符?时,传入变量的方式。

    参数argTypes:是args传入参数对应的数据库表字段的数据类型。

    参数pss: 封装入参。

    1. public Stream queryForStream(String sql, RowMapper rowMapper);
    2. public Stream queryForStream(String sql, RowMapper rowMapper, @Nullable Object... args);
    3. public Stream queryForStream(String sql, @Nullable PreparedStatementSetter pss, RowMapper rowMapper);

    2.2 queryForStream使用场景

    场景:使用queryForStream函数,可以把查询结果集按照自定义的JavaBean封装,并以Stream方式返回查询结果集。

    2.3 queryForStream使用举例

    1. /**
    2. * 1.queryForStream函数入参不带查询条件,如有查询条件直接写在SQL中
    3. * 2.使用自定义CityRowMapper封装返回值
    4. * 3.使用java.util.stream.Stream遍历结果
    5. */
    6. public static void f2_1() {
    7. // 1.获取查询sql
    8. String sql = getSelectSql01();
    9. // 2.获取JdbcTemplate
    10. JdbcTemplate jt = getJdbcTemplate();
    11. // 3.查询数据集
    12. Stream stream = jt.queryForStream(sql, new CityRowMapper());
    13. // 4.遍历结果并打印
    14. stream.forEach(cityPO -> {
    15. System.out.println(cityPO.toString());
    16. });
    17. }
    18. /**
    19. * 1.queryForStream函数入参带查询条件
    20. * 2.使用自定义CityRowMapper封装返回值
    21. * 3.使用java.util.stream.Stream遍历结果
    22. */
    23. public static void f2_2() {
    24. // 1.获取查询sql
    25. String sql = getSelectSql02();
    26. // 2.获取JdbcTemplate
    27. JdbcTemplate jt = getJdbcTemplate();
    28. // 3.组装查询条件
    29. Object[] args = new Object[]{"杭州", "1"};
    30. // 4.查询数据集
    31. Stream stream = jt.queryForStream(sql, new CityRowMapper(), args);
    32. // 5.遍历结果并打印
    33. stream.forEach(cityPO -> {
    34. System.out.println(cityPO.toString());
    35. });
    36. }
    37. /**
    38. * 1.queryForStream函数入参带查询条件
    39. * 2.使用自定义CityRowMapper封装返回值
    40. * 3.使用java.util.stream.Stream遍历结果
    41. */
    42. public static void f2_3() {
    43. // 1.获取查询sql
    44. String sql = getSelectSql02();
    45. // 2.获取JdbcTemplate
    46. JdbcTemplate jt = getJdbcTemplate();
    47. // 3.组装查询条件
    48. Object[] args = new Object[]{"杭州", "1"};
    49. // 4.查询数据集
    50. Stream stream = jt.queryForStream(sql, new ArgumentPreparedStatementSetter(args), new CityRowMapper());
    51. // 5.遍历结果并打印
    52. stream.forEach(cityPO -> {
    53. System.out.println(cityPO.toString());
    54. });
    55. }
    56. /**
    57. * 1.select语句
    58. * 2.query函数入参不带查询条件
    59. * 3.queryForStream函数入参不带查询条件
    60. */
    61. public static String getSelectSql01() {
    62. String sql01 = "SELECT\n" +
    63. " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
    64. " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
    65. "FROM t_city ";
    66. return sql01.toString();
    67. }
    68. /**
    69. * 1.select语句
    70. * 2.query函数入参带查询条件
    71. * 3.queryForStream函数入参带查询条件
    72. */
    73. public static String getSelectSql02() {
    74. String sql02 = "SELECT\n" +
    75. " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
    76. " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
    77. "FROM t_city " +
    78. "WHERE CITY_NAME = ? AND ID =? ";
    79. return sql02.toString();
    80. }

    3.queryForMap函数

    3.1 queryForMap函数定义

    结果集封装在一个Map中,即返回一条记录。

    1. public Map queryForMap(String sql);
    2. public Map queryForMap(String sql, @Nullable Object... args);
    3. public Map queryForMap(String sql, Object[] args, int[] argTypes);

    3.2 queryForMap使用场景

    场景:使用queryForMap函数,可以把查询结果集封装成Map,而且只能查询一条记录,即数据库表中一行数据。

    3.3 queryForMap使用举例

    1. /**
    2. * 1.queryForMap函数入参不带查询条件,如有查询条件直接写在SQL中
    3. * 2.查询条件中只能限定一条记录,返回结果封装在Map中
    4. * 3.使用java.util.stream.Stream遍历结果
    5. */
    6. public static void f3_1() {
    7. // 1.获取查询sql
    8. String sql = getSelectSql03();
    9. // 2.获取JdbcTemplate
    10. JdbcTemplate jt = getJdbcTemplate();
    11. // 3.查询数据集
    12. Map map = jt.queryForMap(sql);
    13. // 4.遍历结果并打印
    14. Stream> stream = map.entrySet().stream();
    15. stream.forEach(cityPO -> {
    16. System.out.println(cityPO.getKey() + " = " + cityPO.getValue());
    17. });
    18. }
    19. /**
    20. * 1.queryForMap函数入参带查询条件
    21. * 2.查询条件中只能限定一条记录,返回结果封装在Map中
    22. * 3.使用map.forEach遍历结果
    23. */
    24. public static void f3_2() {
    25. // 1.获取查询sql
    26. String sql = getSelectSql04();
    27. // 2.获取JdbcTemplate
    28. JdbcTemplate jt = getJdbcTemplate();
    29. // 3.组装查询条件
    30. Object[] args = new Object[]{"杭州", "1"};
    31. // 4.查询数据集
    32. Map map = jt.queryForMap(sql, args);
    33. // 5.遍历结果并打印
    34. map.forEach((key, value) -> {
    35. System.out.println(key + " = " + value.toString());
    36. });
    37. }
    38. /**
    39. * 1.queryForMap函数入参带查询条件,入参带参数类型
    40. * 2.查询条件中只能限定一条记录,返回结果封装在Map中
    41. * 3.使用Map.Entry遍历结果
    42. */
    43. public static void f3_3() {
    44. // 1.获取查询sql
    45. String sql = getSelectSql04();
    46. // 2.获取JdbcTemplate
    47. JdbcTemplate jt = getJdbcTemplate();
    48. // 3.组装查询条件
    49. Object[] args = new Object[]{"杭州", "1"};
    50. int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
    51. // 4.查询数据集
    52. Map map = jt.queryForMap(sql, args, argTypes);
    53. // 5.遍历结果并打印
    54. for (Map.Entry entry : map.entrySet()) {
    55. System.out.println(entry.getKey() + " = " + entry.getValue());
    56. }
    57. }
    58. /**
    59. * 1.select语句,查一条数据
    60. * 2.queryForMap函数入参不带查询条件
    61. */
    62. public static String getSelectSql03() {
    63. String sql03 = "SELECT\n" +
    64. " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
    65. " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
    66. "FROM t_city limit 1";
    67. return sql03.toString();
    68. }
    69. /**
    70. * 1.select语句,查一条数据
    71. * 2.queryForMap函数入参带查询条件
    72. */
    73. public static String getSelectSql04() {
    74. String sql04 = "SELECT\n" +
    75. " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
    76. " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
    77. "FROM t_city " +
    78. "WHERE CITY_NAME = ? AND ID =? limit 1";
    79. return sql04.toString();
    80. }

    4.queryForRowSet函数

    4.1 queryForRowSet函数定义

    queryForRowSet把结果封装成SqlRowSet,需要根据SqlRowSet的next()去遍历函数取值。

    不能直接取值否则报错:Caused by: java.sql.SQLException: 光标位置无效。

    需要调用调用SqlRowSet.next()后,内部会调用结果集ResultSet的结果索引值,才能遍历取值。

    参数sql:数据库执行的SQL语句。

    参数args:是SQL中有占位符?时,传入变量的方式。

    参数argTypes:是args传入参数对应的数据库表字段的数据类型。

    1. public SqlRowSet queryForRowSet(String sql);
    2. public SqlRowSet queryForRowSet(String sql, @Nullable Object... args);
    3. public SqlRowSet queryForRowSet(String sql, Object[] args, int[] argTypes);

    4.2 queryForRowSet使用场景

    场景:使用queryForRowSet函数,结果集封装成SqlRowSet,需要额外去遍历结果集取值。

    4.3 queryForRowSet使用举例

    1. /**
    2. * 1.queryForRowSet函数入参不带查询条件,如有查询条件直接写在SQL中
    3. * 2.使用SqlRowSet封装返回值
    4. * 3.使用sqlRowSet.next()遍历结果
    5. * 4.直接取值报错: Caused by: java.sql.SQLException: 光标位置无效
    6. * 5.调用SqlRowSet.next()后,取值,内部会调用结果集ResultSet的结果索引值即可以取值
    7. */
    8. public static void f4_1() {
    9. // 1.获取查询sql
    10. String sql = getSelectSql01();
    11. // 2.获取JdbcTemplate
    12. JdbcTemplate jt = getJdbcTemplate();
    13. jt.setFetchSize(2);
    14. // 3.查询数据集
    15. SqlRowSet sqlRowSet = jt.queryForRowSet(sql);
    16. // 4.遍历结果并打印
    17. while (sqlRowSet.next()) {
    18. Object result = sqlRowSet.getObject("CITY_NAME");
    19. System.out.println(result);
    20. }
    21. }
    22. /**
    23. * 1.queryForRowSet函数入参带查询条件
    24. * 2.使用SqlRowSet封装返回值
    25. * 3.使用sqlRowSet.next()遍历结果
    26. * 4.直接取值报错: Caused by: java.sql.SQLException: 光标位置无效
    27. * 5.调用SqlRowSet.next()后,取值,内部会调用结果集ResultSet的结果索引值即可以取值
    28. */
    29. public static void f4_2() {
    30. // 1.获取查询sql
    31. String sql = getSelectSql02();
    32. // 2.获取JdbcTemplate
    33. JdbcTemplate jt = getJdbcTemplate();
    34. // 3.组装查询条件
    35. Object[] args = new Object[]{"杭州", "1"};
    36. // 4.查询数据集
    37. SqlRowSet sqlRowSet = jt.queryForRowSet(sql, args);
    38. // 5.遍历结果并打印
    39. while (sqlRowSet.next()) {
    40. Object result = sqlRowSet.getObject("CITY_DESCRIBE");
    41. System.out.println(result);
    42. }
    43. }
    44. /**
    45. * 1.queryForRowSet函数入参带查询条件,入参带参数类型
    46. * 2.使用SqlRowSet封装返回值
    47. * 3.使用sqlRowSet.next()遍历结果
    48. * 4.直接取值报错: Caused by: java.sql.SQLException: 光标位置无效
    49. * 5.调用SqlRowSet.next()后,取值,内部会调用结果集ResultSet的结果索引值即可以取值
    50. */
    51. public static void f4_3() {
    52. // 1.获取查询sql
    53. String sql = getSelectSql02();
    54. // 2.获取JdbcTemplate
    55. JdbcTemplate jt = getJdbcTemplate();
    56. // 3.组装查询条件
    57. Object[] args = new Object[]{"杭州", "1"};
    58. int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
    59. // 4.查询数据集
    60. SqlRowSet sqlRowSet = jt.queryForRowSet(sql, args, argTypes);
    61. // 5.遍历结果并打印
    62. while (sqlRowSet.next()) {
    63. Object result = sqlRowSet.getObject("DATA_YEAR");
    64. System.out.println(result);
    65. }
    66. }
    67. /**
    68. * 1.select语句
    69. * 2.query函数入参不带查询条件
    70. * 3.queryForStream函数入参不带查询条件
    71. * 4.queryForRowSet函数入参不带查询条件
    72. */
    73. public static String getSelectSql01() {
    74. String sql01 = "SELECT\n" +
    75. " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
    76. " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
    77. "FROM t_city ";
    78. return sql01.toString();
    79. }
    80. /**
    81. * 1.select语句
    82. * 2.query函数入参带查询条件
    83. * 3.queryForStream函数入参带查询条件
    84. * 4.queryForRowSet函数入参带查询条件
    85. */
    86. public static String getSelectSql02() {
    87. String sql02 = "SELECT\n" +
    88. " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
    89. " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
    90. "FROM t_city " +
    91. "WHERE CITY_NAME = ? AND ID =? ";
    92. return sql02.toString();
    93. }

    5.queryForObject函数

    5.1 queryForObject查询一个字段

    5.1.1 queryForObject函数定义

    queryForObject的以下3个函数,查询一个字段值。

    参数sql:数据库执行的SQL语句。

    参数requiredType:封装返回值类型。

    参数args:是SQL中有占位符?时,传入变量的方式。

    参数argTypes:是args传入参数对应的数据库表字段的数据类型。

    1. public T queryForObject(String sql, Class requiredType);
    2. public T queryForObject(String sql, Class requiredType, @Nullable Object... args);
    3. public T queryForObject(String sql, Object[] args, int[] argTypes, Class requiredType);

    5.1.2 queryForObject使用场景

    场景:使用queryForObject函数,查询一条记录的一个字段值,根据基本类型封装返回值。

    5.1.3 queryForObject使用举例

    1. /**
    2. * 1.queryForObject函数入参不带查询条件,如有查询条件直接写在SQL中
    3. * 2.根据基本类型封装返回值
    4. * 3.查询一条记录的一个字段值
    5. */
    6. public static void f5_1_1() {
    7. // 1.获取查询sql
    8. String sql = getSelectSql05();
    9. // 2.获取JdbcTemplate
    10. JdbcTemplate jt = getJdbcTemplate();
    11. // 3.查询数据集
    12. String cityName = jt.queryForObject(sql, String.class);
    13. // 4.遍历结果并打印
    14. System.out.println(cityName);
    15. }
    16. /**
    17. * 1.queryForObject函数入参带查询条件
    18. * 2.根据基本类型封装返回值
    19. * 3.查询一条记录的一个字段值
    20. */
    21. public static void f5_1_2() {
    22. // 1.获取查询sql
    23. String sql = getSelectSql06();
    24. // 2.获取JdbcTemplate
    25. JdbcTemplate jt = getJdbcTemplate();
    26. // 3.组装查询条件
    27. Object[] args = new Object[]{"杭州", "1"};
    28. // 4.查询数据集
    29. String cityName = jt.queryForObject(sql, String.class, args);
    30. // 5.遍历结果并打印
    31. System.out.println(cityName);
    32. }
    33. /**
    34. * 1.queryForObject函数入参带查询条件,入参带参数类型
    35. * 2.根据基本类型封装返回值
    36. * 3.查询一条记录的一个字段值
    37. */
    38. public static void f5_1_3() {
    39. // 1.获取查询sql
    40. String sql = getSelectSql06();
    41. // 2.获取JdbcTemplate
    42. JdbcTemplate jt = getJdbcTemplate();
    43. // 3.组装查询条件
    44. Object[] args = new Object[]{"杭州", "1"};
    45. int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
    46. // 4.查询数据集
    47. String cityName = jt.queryForObject(sql, args, argTypes, String.class);
    48. // 5.遍历结果并打印
    49. System.out.println(cityName);
    50. }
    51. /**
    52. * 1.select语句,查一条数据的一个字段
    53. * 2.queryForObject函数入参带查询条件
    54. */
    55. public static String getSelectSql05() {
    56. String sql05 = "SELECT\n" +
    57. " CITY_NAME\n" +
    58. "FROM t_city limit 1";
    59. return sql05.toString();
    60. }
    61. /**
    62. * 1.select语句,查一条数据的一个字段
    63. * 2.queryForObject函数入参带查询条件
    64. */
    65. public static String getSelectSql06() {
    66. String sql06 = "SELECT\n" +
    67. " CITY_NAME \n" +
    68. "FROM t_city " +
    69. "WHERE CITY_NAME = ? AND ID =? limit 1";
    70. return sql06.toString();
    71. }

    5.2 queryForObject查询一条记录

    5.2.1 queryForObject函数定义

    queryForObject的以下3个函数,查询一条记录。

    参数sql:数据库执行的SQL语句。

    参数rowMapper:是RowMapper接口实现类,把数据库返回的结果集表字段与值,封装成自定义的JavaBean对象。

    参数args:是SQL中有占位符?时,传入变量的方式。

    参数argTypes:是args传入参数对应的数据库表字段的数据类型。

    1. public T queryForObject(String sql, RowMapper rowMapper);
    2. public T queryForObject(String sql, RowMapper rowMapper, @Nullable Object... args);
    3. public T queryForObject(String sql, Object[] args, int[] argTypes, RowMapper rowMapper);

    5.2.2 queryForObject使用场景

    场景:使用queryForObject函数,可以把查询结果集按照自定义的JavaBean封装,返回值为JavaBean。

    5.2.3 queryForObject使用举例

    1. /**
    2. * 1.queryForObject函数入参不带查询条件,如有查询条件直接写在SQL中
    3. * 2.使用自定义CityRowMapper封装返回值
    4. * 3.查询一条记录,返回值即自定义对象
    5. */
    6. public static void f5_2_1() {
    7. // 1.获取查询sql
    8. String sql = getSelectSql03();
    9. // 2.获取JdbcTemplate
    10. JdbcTemplate jt = getJdbcTemplate();
    11. // 3.查询数据集
    12. CityPO cityPO = jt.queryForObject(sql, new CityRowMapper());
    13. // 4.遍历结果并打印
    14. System.out.println(cityPO);
    15. }
    16. /**
    17. * 1.queryForObject函数入参带查询条件
    18. * 2.使用自定义CityRowMapper封装返回值
    19. * 3.查询一条记录,返回值即自定义对象
    20. */
    21. public static void f5_2_2() {
    22. // 1.获取查询sql
    23. String sql = getSelectSql04();
    24. // 2.获取JdbcTemplate
    25. JdbcTemplate jt = getJdbcTemplate();
    26. // 3.组装查询条件
    27. Object[] args = new Object[]{"杭州", "1"};
    28. // 4.查询数据集
    29. CityPO cityPO = jt.queryForObject(sql, new CityRowMapper(), args);
    30. // 5.遍历结果并打印
    31. System.out.println(cityPO);
    32. }
    33. /**
    34. * 1.queryForObject函数入参带查询条件,入参带参数类型
    35. * 2.使用自定义CityRowMapper封装返回值
    36. * 3.查询一条记录,返回值即自定义对象
    37. */
    38. public static void f5_2_3() {
    39. // 1.获取查询sql
    40. String sql = getSelectSql04();
    41. // 2.获取JdbcTemplate
    42. JdbcTemplate jt = getJdbcTemplate();
    43. // 3.组装查询条件
    44. Object[] args = new Object[]{"杭州", "1"};
    45. int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
    46. // 4.查询数据集
    47. CityPO cityPO = jt.queryForObject(sql, args, argTypes, new CityRowMapper());
    48. // 5.遍历结果并打印
    49. System.out.println(cityPO);
    50. }
    51. /**
    52. * 1.select语句,查一条数据
    53. * 2.queryForMap函数入参不带查询条件
    54. * 3.queryForObject函数入参不带查询条件
    55. */
    56. public static String getSelectSql03() {
    57. String sql01 = "SELECT\n" +
    58. " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
    59. " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
    60. "FROM t_city limit 1";
    61. return sql01.toString();
    62. }
    63. /**
    64. * 1.select语句,查一条数据
    65. * 2.queryForMap函数入参带查询条件
    66. * 3.queryForObject函数入参带查询条件
    67. */
    68. public static String getSelectSql04() {
    69. String sql02 = "SELECT\n" +
    70. " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
    71. " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
    72. "FROM t_city " +
    73. "WHERE CITY_NAME = ? AND ID =? limit 1";
    74. return sql02.toString();
    75. }

    6.queryForList函数

    6.1 queryForList查询多条记录

    6.1.1 queryForList函数定义

    参数sql:数据库执行的SQL语句。

    参数args:是SQL中有占位符?时,传入变量的方式。

    参数argTypes:是args传入参数对应的数据库表字段的数据类型。

    1. public List> queryForList(String sql)
    2. public List> queryForList(String sql, @Nullable Object... args);
    3. public List> queryForList(String sql, Object[] args, int[] argTypes);

    6.1.2 queryForList使用场景

    场景:使用queryForList函数,把查询结果集封装为List>,遍历List取出每条记录,即一条记录一个Map,一个Map对应数据库表中的字段和字段值,即Map的key,value键值对。

    6.1.3 queryForList使用举例

    1. /**
    2. * 1.queryForList函数入参不带查询条件,如有查询条件直接写在SQL中
    3. * 2.使用List>封装返回值
    4. * 3.使用java.util.stream.Stream遍历结果
    5. */
    6. public static void f6_1_1() {
    7. // 1.获取查询sql
    8. String sql = getSelectSql01();
    9. // 2.获取JdbcTemplate
    10. JdbcTemplate jt = getJdbcTemplate();
    11. // 3.查询数据集
    12. List> list = jt.queryForList(sql);
    13. // 4.遍历结果并打印,使用Stream函数式遍历
    14. Stream> stream = list.stream();
    15. System.out.println("遍历List.");
    16. AtomicInteger i = new AtomicInteger(1);
    17. stream.forEach(map -> {
    18. System.out.println("遍历第 " + i + " 条记录.");
    19. AtomicInteger j = new AtomicInteger(1);
    20. map.forEach((key, value) -> {
    21. System.out.println(key + " = " + value.toString());
    22. });
    23. i.getAndIncrement();
    24. });
    25. }
    26. /**
    27. * 1.queryForList函数入参带查询条件
    28. * 2.使用List>封装返回值
    29. * 3.使用for循环和Map.Entry遍历结果
    30. */
    31. public static void f6_1_2() {
    32. // 1.获取查询sql
    33. String sql = getSelectSql02();
    34. // 2.获取JdbcTemplate
    35. JdbcTemplate jt = getJdbcTemplate();
    36. // 3.组装查询条件
    37. Object[] args = new Object[]{"杭州", "1"};
    38. // 4.查询数据集
    39. List> list = jt.queryForList(sql, args);
    40. // 5.遍历结果并打印,使用for遍历
    41. for (Map map : list) {
    42. for (Map.Entry entry : map.entrySet()) {
    43. System.out.println(entry.getKey() + " = " + entry.getValue());
    44. }
    45. }
    46. }
    47. /**
    48. * 1.queryForList函数入参带查询条件,入参带参数类型
    49. * 2.使用List>封装返回值
    50. * 3.使用for循环和while循环和Map.Entry遍历结果
    51. */
    52. public static void f6_1_3() {
    53. // 1.获取查询sql
    54. String sql = getSelectSql02();
    55. // 2.获取JdbcTemplate
    56. JdbcTemplate jt = getJdbcTemplate();
    57. // 3.组装查询条件
    58. Object[] args = new Object[]{"杭州", "1"};
    59. int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
    60. // 4.查询数据集
    61. List> list = jt.queryForList(sql, args, argTypes);
    62. // 5.遍历结果并打印,使用for遍历,和while遍历
    63. for (int i = 0; i < list.size(); i++) {
    64. Map map = list.get(i);
    65. Iterator> entries = map.entrySet().iterator();
    66. while (entries.hasNext()) {
    67. Map.Entry entry = entries.next();
    68. System.out.println(entry.getKey() + " = " + entry.getValue());
    69. }
    70. }
    71. }
    72. /**
    73. * 1.select语句
    74. * 2.query函数入参不带查询条件
    75. * 3.queryForStream函数入参不带查询条件
    76. * 4.queryForRowSet函数入参不带查询条件
    77. * 5.queryForList函数入参不带查询条件
    78. */
    79. public static String getSelectSql01() {
    80. String sql01 = "SELECT\n" +
    81. " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
    82. " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
    83. "FROM t_city ";
    84. return sql01.toString();
    85. }
    86. /**
    87. * 1.select语句
    88. * 2.query函数入参带查询条件
    89. * 3.queryForStream函数入参带查询条件
    90. * 4.queryForRowSet函数入参带查询条件
    91. * 5.queryForList函数入参带查询条件
    92. */
    93. public static String getSelectSql02() {
    94. String sql02 = "SELECT\n" +
    95. " ID,CITY_NAME,LAND_AREA,POPULATION,GROSS,\n" +
    96. " CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
    97. "FROM t_city " +
    98. "WHERE CITY_NAME = ? AND ID =? ";
    99. return sql02.toString();
    100. }

    6.2 queryForList查一个字段的多条记录

    6.2.1 queryForList函数定义

    参数sql:数据库执行的SQL语句。

    参数elementType:封装返回值类型。

    参数args:是SQL中有占位符?时,传入变量的方式。

    参数argTypes:是args传入参数对应的数据库表字段的数据类型。

    1. public List queryForList(String sql, Class elementType);
    2. public List queryForList(String sql, Class elementType, @Nullable Object... args);
    3. public List queryForList(String sql, Object[] args, int[] argTypes, Class elementType);

    6.2.2 queryForList使用场景

    场景:使用queryForList函数,把查询结果封装为指定的基本类型,返回值封装在 List 中。适合查询一个字段的多条记录。

    6.2.3 queryForList使用举例

    1. /**
    2. * 1.queryForList函数入参不带查询条件,如有查询条件直接写在SQL中
    3. * 2.查一个字段的多条记录,使用List封装返回值
    4. * 3.使用java.util.stream.Stream遍历结果
    5. */
    6. public static void f6_2_1() {
    7. // 1.获取查询sql
    8. String sql = getSelectSql07();
    9. // 2.获取JdbcTemplate
    10. JdbcTemplate jt = getJdbcTemplate();
    11. // 3.查询数据集
    12. List list = jt.queryForList(sql, String.class);
    13. // 4.遍历结果并打印
    14. Stream stream = list.stream();
    15. stream.forEach(cityName -> {
    16. System.out.println(cityName.toString());
    17. });
    18. }
    19. /**
    20. * 1.queryForList函数入参带查询条件
    21. * 2.查一个字段的多条记录,使用List封装返回值
    22. * 3.使用java.util.stream.Stream遍历结果
    23. */
    24. public static void f6_2_2() {
    25. // 1.获取查询sql
    26. String sql = getSelectSql08();
    27. // 2.获取JdbcTemplate
    28. JdbcTemplate jt = getJdbcTemplate();
    29. // 3.组装查询条件
    30. Object[] args = new Object[]{"杭州", "1"};
    31. // 4.查询数据集
    32. List list = jt.queryForList(sql, String.class, args);
    33. // 5.遍历结果并打印
    34. Stream stream = list.stream();
    35. stream.forEach(cityName -> {
    36. System.out.println(cityName.toString());
    37. });
    38. }
    39. /**
    40. * 1.queryForList函数入参带查询条件,入参带参数类型
    41. * 2.查一个字段的多条记录,使用List封装返回值
    42. * 3.使用java.util.stream.Stream遍历结果
    43. */
    44. public static void f6_2_3() {
    45. // 1.获取查询sql
    46. String sql = getSelectSql08();
    47. // 2.获取JdbcTemplate
    48. JdbcTemplate jt = getJdbcTemplate();
    49. // 3.组装查询条件
    50. Object[] args = new Object[]{"杭州", "1"};
    51. int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
    52. // 4.查询数据集
    53. List list = jt.queryForList(sql, args, argTypes, String.class);
    54. // 5.遍历结果并打印
    55. Stream stream = list.stream();
    56. stream.forEach(cityName -> {
    57. System.out.println(cityName.toString());
    58. });
    59. }
    60. /**
    61. * 1.select语句,一个字段的多条记录
    62. * 2.queryForList函数入参不带查询条件
    63. */
    64. public static String getSelectSql07() {
    65. String sql07 = "SELECT\n" +
    66. " CITY_NAME\n" +
    67. "FROM t_city ";
    68. return sql07.toString();
    69. }
    70. /**
    71. * 1.select语句,一个字段的多条记录
    72. * 2.queryForList函数入参带查询条件
    73. */
    74. public static String getSelectSql08() {
    75. String sql08 = "SELECT\n" +
    76. " CITY_NAME\n" +
    77. "FROM t_city " +
    78. "WHERE CITY_NAME = ? AND ID =? ";
    79. return sql08.toString();
    80. }

    7.查询函数共用代码

    7.1 获取JdbcTemplate实例对象

    封装统一方法获取JdbcTemplate,使用时替换为实际数据库连接信息。

    1. /**
    2. * 获取一个JdbcTemplate实例对象
    3. */
    4. public static JdbcTemplate getJdbcTemplate() {
    5. String username = "***自定义填写**";
    6. String password = "***自定义填写**";
    7. String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/***自定义填写**";
    8. String driverName = "com.mysql.cj.jdbc.Driver";
    9. DruidDataSource dataSource = new DruidDataSource();
    10. dataSource.setPassword(password);
    11. dataSource.setUrl(jdbcUrl);
    12. dataSource.setUsername(username);
    13. dataSource.setDriverClassName(driverName);
    14. JdbcTemplate jdbcTemplate = new JdbcTemplate();
    15. jdbcTemplate.setDataSource(dataSource);
    16. return jdbcTemplate;
    17. }

    7.2 实现RowMapper接口对象

    本例CityRowMapper实现RowMapper接口,封装结果集和JavaBean对应关系。

    1. /**
    2. * 实现JdbcTemplate的RowMapper接口
    3. * 数据库查询的字段和自定义JavaBean属性匹配
    4. */
    5. private static class CityRowMapper implements RowMapper {
    6. @Override
    7. public CityPO mapRow(ResultSet rs, int rowNum) throws SQLException {
    8. CityPO cityPO = new CityPO();
    9. cityPO.setId((Long) rs.getObject("ID"));
    10. cityPO.setCityName((String) rs.getObject("CITY_NAME"));
    11. cityPO.setLandArea((Double) rs.getObject("LAND_AREA"));
    12. cityPO.setPopulation((Long) rs.getObject("POPULATION"));
    13. cityPO.setGross((Double) rs.getObject("GROSS"));
    14. cityPO.setCityDescribe((String) rs.getObject("CITY_DESCRIBE"));
    15. cityPO.setDataYear((String) rs.getObject("DATA_YEAR"));
    16. cityPO.setUpdateTime((LocalDateTime) rs.getObject("UPDATE_TIME"));
    17. return cityPO;
    18. }
    19. }

    7.3 JavaBean对象

    JavaBean对象与数据库表字段一一对应,以驼峰法命名。

    1. @Data
    2. @NoArgsConstructor
    3. public class CityPO {
    4. private long id;
    5. private String cityName;
    6. private double landArea;
    7. private long population;
    8. private double gross;
    9. private String cityDescribe;
    10. private String dataYear;
    11. private LocalDateTime updateTime;

    二、增

    增,即使用JdbcTemplate对数据库的数据做插入操作。

    SQL关键字:insert into。

    1.update函数

    1.1 update函数定义

    执行数据数据库insert into插入数据,使用update函数实现。

    参数sql:数据库执行的SQL语句。

    参数pss:对应入参和占位符字段匹配关系。

    参数args:是SQL中有占位符?时,传入变量的方式。

    参数argTypes:是args传入参数对应的数据库表字段的数据类型。

    1. public int update(final String sql);
    2. public int update(String sql, @Nullable Object... args);
    3. public int update(String sql, @Nullable PreparedStatementSetter pss);
    4. public int update(String sql, Object[] args, int[] argTypes);

    1.2 update使用场景

    场景:使用update函数,可以执行数据库的insert into插入数据。

    1.3 update使用举例

    1. /**
    2. * 1.insert插入语句,使用update函数
    3. * 2.update函数入参不带插入数据,数据直接写在insert into语句中
    4. */
    5. public static void f7_1() {
    6. // 1.获取插入sql
    7. String sql = getInsertSql02();
    8. // 2.获取JdbcTemplate
    9. JdbcTemplate jt = getJdbcTemplate();
    10. // 3.执行insert into语句
    11. int result = jt.update(sql);
    12. // 4.打印返回值
    13. System.out.println("插入返回值: " + result);
    14. }
    15. /**
    16. * 1.insert插入语句,使用update函数
    17. * 2.update函数入参带插入数据
    18. */
    19. public static void f7_2() {
    20. // 1.获取插入sql
    21. String sql = getInsertSql01();
    22. // 2.获取JdbcTemplate
    23. JdbcTemplate jt = getJdbcTemplate();
    24. // 3.组装插入参数
    25. Object[] args = new Object[]{
    26. "杭州", "16850", "1200", "1.61",
    27. "杭州是一个好城市", "2020", "2022-07-23 16:39:16"
    28. };
    29. // 4.执行insert into语句
    30. int result = jt.update(sql, args);
    31. // 5.打印返回值
    32. System.out.println("插入返回值: " + result);
    33. }
    34. /**
    35. * 1.insert插入语句,使用update函数
    36. * 2.update函数入参带插入数据
    37. * 3.使用PreparedStatementSetter对应入参和字段关系
    38. */
    39. public static void f7_3() {
    40. // 1.获取插入sql
    41. String sql = getInsertSql01();
    42. // 2.获取JdbcTemplate
    43. JdbcTemplate jt = getJdbcTemplate();
    44. // 3.组装插入参数
    45. Object[] args = new Object[]{
    46. "杭州", "16850", "1200", "1.61",
    47. "杭州是一个好城市", "2020", "2022-07-23 16:39:18"
    48. };
    49. // 4.执行insert语句(插入一条数据)
    50. int result = jt.update(sql, new PreparedStatementSetter() {
    51. @Override
    52. public void setValues(PreparedStatement ps) throws SQLException {
    53. ps.setObject(1, args[0]);
    54. ps.setObject(2, args[1]);
    55. ps.setObject(3, args[2]);
    56. ps.setObject(4, args[3]);
    57. ps.setObject(5, args[4]);
    58. ps.setObject(6, args[5]);
    59. ps.setObject(7, args[6]);
    60. }
    61. });
    62. // 5.打印返回值
    63. System.out.println("插入返回值: " + result);
    64. }
    65. /**
    66. * 1.insert插入语句,使用update函数
    67. * 2.update函数入参带插入数据,入参带参数类型
    68. */
    69. public static void f7_4() {
    70. // 1.获取插入sql
    71. String sql = getInsertSql01();
    72. // 2.获取JdbcTemplate
    73. JdbcTemplate jt = getJdbcTemplate();
    74. // 3.组装插入参数
    75. Object[] args = new Object[]{
    76. "杭州", "16850", "1200", "1.61",
    77. "杭州是一个好城市", "2020", "2022-07-23 16:39:19"
    78. };
    79. int[] argTypes = new int[]{Types.VARCHAR,
    80. Types.DOUBLE, Types.BIGINT, Types.DOUBLE,
    81. Types.VARCHAR, Types.VARCHAR, Types.TIMESTAMP
    82. };
    83. // 4.执行insert语句
    84. int result = jt.update(sql, args, argTypes);
    85. // 5.打印返回值
    86. System.out.println("插入返回值: " + result);
    87. }
    88. /**
    89. * 1.insert语句,插入数据
    90. * 2.update函数入参带插入数据
    91. */
    92. public static String getInsertSql01() {
    93. String sql01 = "INSERT INTO t_city (\n" +
    94. " CITY_NAME,LAND_AREA,POPULATION,\n" +
    95. " GROSS,CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
    96. ")\n" +
    97. "VALUES (?, ?, ?, ?, ?, ?, ?)";
    98. return sql01.toString();
    99. }
    100. /**
    101. * 1.insert语句,插入数据
    102. * 2.update函数入参不带插入数据
    103. */
    104. public static String getInsertSql02() {
    105. String sql02 = "INSERT INTO t_city (\n" +
    106. " CITY_NAME,LAND_AREA,POPULATION,\n" +
    107. " GROSS,CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME)\n" +
    108. " VALUES('杭州','16850','1200','1.61',\n" +
    109. " '杭州是一个好城市','2020','2022-07-23 16:39:16')";
    110. return sql02.toString();
    111. }

    2.batchUpdate函数

    2.1 batchUpdate函数定义

    执行数据数据库insert into批量插入数据,使用batchUpdate函数实现。

    参数sql:数据库执行的SQL语句。

    参数pss:对应入参和占位符字段匹配关系。

    参数batchArgs:是SQL中有占位符?时,传入变量的方式。

    参数argTypes:是args传入参数对应的数据库表字段的数据类型。

    参数batchSize:入参大小,即batchArgs条数。

    1. public int[] batchUpdate(final String... sql);
    2. public int[] batchUpdate(String sql, List batchArgs);
    3. public int[] batchUpdate(String sql, List batchArgs, final int[] argTypes);
    4. public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss);
    5. public int[][] batchUpdate(String sql, final Collection batchArgs, final int batchSize, final ParameterizedPreparedStatementSetter pss);

    2.2 batchUpdate使用场景

    场景:使用batchUpdate函数,可以执行数据库的insert into批量插入数据。

    2.3 batchUpdate使用举例

    1. /**
    2. * 1.insert插入语句,使用batchUpdate函数
    3. * 2.batchUpdate函数入参不带插入数据,数据直接写在insert into语句中
    4. */
    5. public static void f8_1() {
    6. // 1.获取插入sql
    7. String[] sql = getInsertSql03();
    8. // 2.获取JdbcTemplate
    9. JdbcTemplate jt = getJdbcTemplate();
    10. // 3.执行insert语句
    11. int[] result = jt.batchUpdate(sql);
    12. // 4.遍历并打印返回值
    13. List list = Arrays.stream(result).boxed().collect(Collectors.toList());
    14. for (Object var : list) {
    15. System.out.println("返回值: " + var);
    16. }
    17. }
    18. /**
    19. * 1.insert插入语句,使用batchUpdate函数
    20. * 2.batchUpdate函数入参带插入数据
    21. */
    22. public static void f8_2() {
    23. // 1.获取插入sql
    24. String sql = getInsertSql01();
    25. // 2.获取JdbcTemplate
    26. JdbcTemplate jt = getJdbcTemplate();
    27. // 3.组装插入参数
    28. List batchArgs = getInsertBatchArgs();
    29. // 4.执行insert语句
    30. int[] result = jt.batchUpdate(sql, batchArgs);
    31. // 5.打印返回值
    32. List list = Arrays.stream(result).boxed().collect(Collectors.toList());
    33. for (Object var : list) {
    34. System.out.println("返回值: " + var);
    35. }
    36. }
    37. /**
    38. * 1.insert插入语句,使用batchUpdate函数
    39. * 2.batchUpdate函数入参带插入数据,入参带参数类型
    40. */
    41. public static void f8_3() {
    42. // 1.获取插入sql
    43. String sql = getInsertSql01();
    44. // 2.获取JdbcTemplate
    45. JdbcTemplate jt = getJdbcTemplate();
    46. // 3.组装插入参数
    47. List batchArgs = getInsertBatchArgs();
    48. int[] argTypes = new int[]{Types.VARCHAR,
    49. Types.DOUBLE, Types.BIGINT, Types.DOUBLE,
    50. Types.VARCHAR, Types.VARCHAR, Types.TIMESTAMP
    51. };
    52. // 4.执行insert语句
    53. int[] result = jt.batchUpdate(sql, batchArgs, argTypes);
    54. // 5.打印返回值
    55. List list = Arrays.stream(result).boxed().collect(Collectors.toList());
    56. for (Object var : list) {
    57. System.out.println("返回值: " + var);
    58. }
    59. }
    60. /**
    61. * 1.insert插入语句,使用batchUpdate函数
    62. * 2.batchUpdate函数入参带插入数据
    63. * 3.使用BatchPreparedStatementSetter对应入参和字段关系
    64. */
    65. public static void f8_4() {
    66. // 1.获取插入sql
    67. String sql = getInsertSql01();
    68. // 2.获取JdbcTemplate
    69. JdbcTemplate jt = getJdbcTemplate();
    70. // 3.组装插入参数
    71. List batchArgs = getInsertBatchArgs();
    72. // 4.执行insert语句
    73. int[] result = jt.batchUpdate(sql, new BatchPreparedStatementSetter() {
    74. @Override
    75. public void setValues(PreparedStatement ps, int i) throws SQLException {
    76. // 第一行开始
    77. Object[] args = batchArgs.get(i);
    78. ps.setObject(1, args[0]);
    79. ps.setObject(2, args[1]);
    80. ps.setObject(3, args[2]);
    81. ps.setObject(4, args[3]);
    82. ps.setObject(5, args[4]);
    83. ps.setObject(6, args[5]);
    84. ps.setObject(7, args[6]);
    85. }
    86. @Override
    87. public int getBatchSize() {
    88. return batchArgs.size();
    89. }
    90. });
    91. // 5.打印返回值
    92. List list = Arrays.stream(result).boxed().collect(Collectors.toList());
    93. for (Object var : list) {
    94. System.out.println("返回值: " + var);
    95. }
    96. }
    97. /**
    98. * 1.insert插入语句,使用batchUpdate函数
    99. * 2.batchUpdate函数入参带插入数据
    100. * 3.使用ParameterizedPreparedStatementSetter对应入参和字段关系
    101. */
    102. public static void f8_5() {
    103. // 1.获取插入sql
    104. String sql = getInsertSql01();
    105. // 2.获取JdbcTemplate
    106. JdbcTemplate jt = getJdbcTemplate();
    107. // 3.组装插入参数
    108. List batchArgs = getInsertBatchArgs();
    109. // 4.执行insert语句
    110. int[][] result = jt.batchUpdate(sql, batchArgs, batchArgs.size(),
    111. new ParameterizedPreparedStatementSetter() {
    112. @Override
    113. public void setValues(PreparedStatement ps, Object argument) throws SQLException {
    114. Object[] args = (Object[]) argument;
    115. ps.setObject(1, args[0]);
    116. ps.setObject(2, args[1]);
    117. ps.setObject(3, args[2]);
    118. ps.setObject(4, args[3]);
    119. ps.setObject(5, args[4]);
    120. ps.setObject(6, args[5]);
    121. ps.setObject(7, args[6]);
    122. }
    123. });
    124. // 5.打印返回值
    125. for (int[] ints : result) {
    126. for (int anInt : ints) {
    127. System.out.println("返回值: " + anInt);
    128. }
    129. }
    130. }
    131. /**
    132. * 1.insert语句,插入数据
    133. * 2.update函数入参带插入数据
    134. */
    135. public static String getInsertSql01() {
    136. String sql01 = "INSERT INTO t_city (\n" +
    137. " CITY_NAME,LAND_AREA,POPULATION,\n" +
    138. " GROSS,CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME\n" +
    139. ")\n" +
    140. "VALUES (?, ?, ?, ?, ?, ?, ?)";
    141. return sql01.toString();
    142. }
    143. /**
    144. * 1.insert语句,插入数据
    145. * 2.update函数入参不带插入数据
    146. */
    147. public static String[] getInsertSql03() {
    148. String sql01 = "INSERT INTO t_city (\n" +
    149. " CITY_NAME,LAND_AREA,POPULATION,\n" +
    150. " GROSS,CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME)\n" +
    151. " VALUES('杭州','16850','1200','1.61',\n" +
    152. " '杭州是一个好城市','2020','2022-07-23 16:39:16')";
    153. String sql02 = "INSERT INTO t_city (\n" +
    154. " CITY_NAME,LAND_AREA,POPULATION,\n" +
    155. " GROSS,CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME)\n" +
    156. " VALUES('杭州','16850','1200','1.81',\n" +
    157. " '杭州是一个好城市','2021','2022-07-23 16:39:19')";
    158. return new String[]{sql01, sql02};
    159. }
    160. /**
    161. * 1.执行数据库insert into语句
    162. * 2.获取批量插入数据
    163. */
    164. public static List getInsertBatchArgs() {
    165. Object[] args1 = new Object[]{
    166. "杭州", "16850", "1200", "1.61",
    167. "杭州是一个好城市", "2020", "2022-07-23 16:39:51"
    168. };
    169. Object[] args2 = new Object[]{
    170. "杭州", "16850", "1200", "1.81",
    171. "杭州是一个好城市", "2021", "2022-07-23 16:39:52"
    172. };
    173. List batchArgs = new ArrayList<>();
    174. batchArgs.add(args1);
    175. batchArgs.add(args2);
    176. return batchArgs;
    177. }

    三、改

    改,即使用JdbcTemplate对数据库的数据做修改操作。

    SQL关键字:update。

    1.update函数

    1.1 update函数定义

    执行数据数据库update修改数据,使用update函数实现。

    参数sql:数据库执行的SQL语句。

    参数pss:对应入参和占位符字段匹配关系。

    参数args:是SQL中有占位符?时,传入变量的方式。

    参数argTypes:是args传入参数对应的数据库表字段的数据类型。

    1. public int update(final String sql);
    2. public int update(String sql, @Nullable Object... args);
    3. public int update(String sql, @Nullable PreparedStatementSetter pss);
    4. public int update(String sql, Object[] args, int[] argTypes);

    1.2 update使用场景

    场景:使用update函数,可以执行数据库的update需改数据。

    1.3 update使用举例

    1. /**
    2. * 1.update修改数据语句,使用update函数
    3. * 2.update函数入参不带修改数据,数据直接写在update语句中
    4. */
    5. public static void f9_1() {
    6. // 1.获取修改sql
    7. String sql = getUpdateSql01();
    8. // 2.获取JdbcTemplate
    9. JdbcTemplate jt = getJdbcTemplate();
    10. // 3.执行update语句
    11. int result = jt.update(sql);
    12. // 4.遍历并打印返回值
    13. System.out.println("返回值: " + result);
    14. }
    15. /**
    16. * 1.update修改数据语句,使用update函数
    17. * 2.update函数入参带修改数据
    18. */
    19. public static void f9_2() {
    20. // 1.获取修改sql
    21. String sql = getUpdateSql02();
    22. // 2.获取JdbcTemplate
    23. JdbcTemplate jt = getJdbcTemplate();
    24. // 3.组装修改参数
    25. Object[] args = new Object[]{"杭州是互联网城市", "2022-07-23 17:39:51", "杭州", "1"};
    26. // 4.执行update语句
    27. int result = jt.update(sql, args);
    28. // 5.打印返回值
    29. System.out.println("插入返回值: " + result);
    30. }
    31. /**
    32. * 1.update修改数据语句,使用update函数
    33. * 2.update函数入参带修改数据
    34. * 3.使用PreparedStatementSetter对应入参和字段关系
    35. */
    36. public static void f9_3() {
    37. // 1.获取修改sql
    38. String sql = getUpdateSql02();
    39. // 2.获取JdbcTemplate
    40. JdbcTemplate jt = getJdbcTemplate();
    41. // 3.组装修改参数
    42. Object[] args = new Object[]{"杭州是互联网城市", "2022-07-23 16:39:22", "杭州", "1"};
    43. // 4.执行update语句
    44. int result = jt.update(sql, new PreparedStatementSetter() {
    45. @Override
    46. public void setValues(PreparedStatement ps) throws SQLException {
    47. ps.setObject(1, args[0]);
    48. ps.setObject(2, args[1]);
    49. ps.setObject(3, args[2]);
    50. ps.setObject(4, args[3]);
    51. }
    52. });
    53. // 5.打印返回值
    54. System.out.println("插入返回值: " + result);
    55. }
    56. /**
    57. * 1.update修改数据语句,使用update函数
    58. * 2.update函数入参带修改数据,入参带参数类型
    59. */
    60. public static void f9_4() {
    61. // 1.获取修改sql
    62. String sql = getUpdateSql02();
    63. // 2.获取JdbcTemplate
    64. JdbcTemplate jt = getJdbcTemplate();
    65. // 3.组装修改参数
    66. Object[] args = new Object[]{"杭州是互联网城市", "2022-07-23 16:39:35", "杭州", "1"};
    67. int[] argTypes = new int[]{Types.VARCHAR, Types.TIMESTAMP,
    68. Types.VARCHAR, Types.BIGINT
    69. };
    70. // 4.执行update语句
    71. int result = jt.update(sql, args, argTypes);
    72. // 5.打印返回值
    73. System.out.println("插入返回值: " + result);
    74. }
    75. /**
    76. * 1.update语句修改数据
    77. * 2.update函数入参不带修改数据
    78. */
    79. public static String getUpdateSql01() {
    80. String sql = "UPDATE t_city\n" +
    81. "SET CITY_DESCRIBE = '杭州是互联网城市'\n" +
    82. "WHERE CITY_NAME = '杭州' AND ID = '1' ";
    83. return sql.toString();
    84. }
    85. /**
    86. * 1.update语句,修改数据
    87. * 2.使用update函数入参带修改数据
    88. * 3.使用batchUpdate函数入参带修改数据
    89. */
    90. public static String getUpdateSql02() {
    91. String sql = "UPDATE t_city\n" +
    92. "SET CITY_DESCRIBE = ?,UPDATE_TIME = ?\n" +
    93. "WHERE CITY_NAME = ? AND ID = ? ";
    94. return sql.toString();
    95. }

    2.batchUpdate函数

    2.1 batchUpdate函数定义

    执行数据数据库update批量修改数据,使用batchUpdate函数实现。

    参数sql:数据库执行的SQL语句。

    参数pss:对应入参和占位符字段匹配关系。

    参数batchArgs:是SQL中有占位符?时,传入变量的方式。

    参数argTypes:是args传入参数对应的数据库表字段的数据类型。

    参数batchSize:入参大小,即batchArgs条数。

    1. public int[] batchUpdate(final String... sql);
    2. public int[] batchUpdate(String sql, List batchArgs);
    3. public int[] batchUpdate(String sql, List batchArgs, final int[] argTypes);
    4. public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss);
    5. public int[][] batchUpdate(String sql, final Collection batchArgs, final int batchSize, final ParameterizedPreparedStatementSetter pss);

    2.2 batchUpdate使用场景

    场景:使用batchUpdate函数,可以执行数据库的update批量修改数据。

    2.3 batchUpdate使用举例

    1. /**
    2. * 1.update修改数据语句,使用batchUpdate函数
    3. * 2.batchUpdate函数入参不带修改数据,数据直接写在update语句中
    4. */
    5. public static void f10_1() {
    6. // 1.获取修改sql
    7. String[] sql = getUpdateSql03();
    8. // 2.获取JdbcTemplate
    9. JdbcTemplate jt = getJdbcTemplate();
    10. // 3.执行update语句
    11. int[] result = jt.batchUpdate(sql);
    12. // 4.遍历并打印返回值
    13. List list = Arrays.stream(result).boxed().collect(Collectors.toList());
    14. for (Object var : list) {
    15. System.out.println("返回值: " + var);
    16. }
    17. }
    18. /**
    19. * 1.update修改数据语句,使用batchUpdate函数
    20. * 2.batchUpdate函数入参带修改数据
    21. */
    22. public static void f10_2() {
    23. // 1.获取修改sql
    24. String sql = getUpdateSql02();
    25. // 2.获取JdbcTemplate
    26. JdbcTemplate jt = getJdbcTemplate();
    27. // 3.组装修改参数
    28. List batchArgs = getUpdateBatchArgs();
    29. // 4.执行update语句
    30. int[] result = jt.batchUpdate(sql, batchArgs);
    31. // 5.打印返回值
    32. List list = Arrays.stream(result).boxed().collect(Collectors.toList());
    33. for (Object var : list) {
    34. System.out.println("返回值: " + var);
    35. }
    36. }
    37. /**
    38. * 1.update修改数据语句,使用batchUpdate函数
    39. * 2.batchUpdate函数入参带修改数据,入参带参数类型
    40. */
    41. public static void f10_3() {
    42. // 1.获取修改sql
    43. String sql = getUpdateSql02();
    44. // 2.获取JdbcTemplate
    45. JdbcTemplate jt = getJdbcTemplate();
    46. // 3.组装修改参数
    47. List batchArgs = getUpdateBatchArgs();
    48. int[] argTypes = new int[]{Types.VARCHAR, Types.TIMESTAMP,
    49. Types.VARCHAR, Types.BIGINT
    50. };
    51. // 4.执行update语句
    52. int[] result = jt.batchUpdate(sql, batchArgs, argTypes);
    53. // 5.打印返回值
    54. List list = Arrays.stream(result).boxed().collect(Collectors.toList());
    55. for (Object var : list) {
    56. System.out.println("返回值: " + var);
    57. }
    58. }
    59. /**
    60. * 1.update修改数据语句,使用batchUpdate函数
    61. * 2.batchUpdate函数入参带修改数据
    62. * 3.使用BatchPreparedStatementSetter对应入参和字段关系
    63. */
    64. public static void f10_4() {
    65. // 1.获取修改sql
    66. String sql = getUpdateSql02();
    67. // 2.获取JdbcTemplate
    68. JdbcTemplate jt = getJdbcTemplate();
    69. // 3.组装修改参数
    70. List batchArgs = getUpdateBatchArgs();
    71. // 4.执行update语句
    72. int[] result = jt.batchUpdate(sql, new BatchPreparedStatementSetter() {
    73. @Override
    74. public void setValues(PreparedStatement ps, int i) throws SQLException {
    75. // 第一行开始
    76. Object[] args = batchArgs.get(i);
    77. ps.setObject(1, args[0]);
    78. ps.setObject(2, args[1]);
    79. ps.setObject(3, args[2]);
    80. ps.setObject(4, args[3]);
    81. }
    82. @Override
    83. public int getBatchSize() {
    84. return batchArgs.size();
    85. }
    86. });
    87. // 5.打印返回值
    88. List list = Arrays.stream(result).boxed().collect(Collectors.toList());
    89. for (Object var : list) {
    90. System.out.println("返回值: " + var);
    91. }
    92. }
    93. /**
    94. * 1.update修改数据语句,使用batchUpdate函数
    95. * 2.batchUpdate函数入参带修改数据
    96. * 3.使用ParameterizedPreparedStatementSetter对应入参和字段关系
    97. */
    98. public static void f10_5() {
    99. // 1.获取修改sql
    100. String sql = getUpdateSql02();
    101. // 2.获取JdbcTemplate
    102. JdbcTemplate jt = getJdbcTemplate();
    103. // 3.组装修改参数
    104. List batchArgs = getUpdateBatchArgs();
    105. // 4.执行update语句
    106. int[][] result = jt.batchUpdate(sql, batchArgs, batchArgs.size(),
    107. new ParameterizedPreparedStatementSetter() {
    108. @Override
    109. public void setValues(PreparedStatement ps, Object argument) throws SQLException {
    110. Object[] args = (Object[]) argument;
    111. ps.setObject(1, args[0]);
    112. ps.setObject(2, args[1]);
    113. ps.setObject(3, args[2]);
    114. ps.setObject(4, args[3]);
    115. }
    116. });
    117. // 5.打印返回值
    118. for (int[] ints : result) {
    119. for (int anInt : ints) {
    120. System.out.println("返回值: " + anInt);
    121. }
    122. }
    123. }
    124. /**
    125. * 1.update语句,修改数据
    126. * 2.使用update函数入参带修改数据
    127. * 3.使用batchUpdate函数入参带修改数据
    128. */
    129. public static String getUpdateSql02() {
    130. String sql = "UPDATE t_city\n" +
    131. "SET CITY_DESCRIBE = ?,UPDATE_TIME = ?\n" +
    132. "WHERE CITY_NAME = ? AND ID = ? ";
    133. return sql.toString();
    134. }
    135. /**
    136. * 1.update语句修改数据
    137. * 2.使用batchUpdate函数入参不带修改数据
    138. */
    139. public static String[] getUpdateSql03() {
    140. String sql01 = "UPDATE t_city\n" +
    141. "SET CITY_DESCRIBE = '杭州是互联网城市01'\n" +
    142. "WHERE CITY_NAME = '杭州' AND ID = '1' ";
    143. String sql02 = "UPDATE t_city\n" +
    144. "SET CITY_DESCRIBE = '杭州是互联网城市02'\n" +
    145. "WHERE CITY_NAME = '杭州' AND ID = '2' ";
    146. return new String[]{sql01, sql02};
    147. }
    148. /**
    149. * 1.执行数据库update语句
    150. * 2.获取批量修改数据
    151. */
    152. public static List getUpdateBatchArgs() {
    153. Object[] args1 = new Object[]{"杭州是互联网城市01", "2022-07-23 16:39:57", "杭州", "1"};
    154. Object[] args2 = new Object[]{"杭州是互联网城市02", "2022-07-23 16:39:58", "杭州", "2"};
    155. List batchArgs = new ArrayList<>();
    156. batchArgs.add(args1);
    157. batchArgs.add(args2);
    158. return batchArgs;
    159. }

    四、删

    删,即使用JdbcTemplate对数据库的数据做删除操作。

    SQL关键字:delete。

    1.update函数

    1.1 update函数定义

    执行数据数据库delete删除数据,使用update函数实现。

    参数sql:数据库执行的SQL语句。

    参数pss:对应入参和占位符字段匹配关系。

    参数args:是SQL中有占位符?时,传入变量的方式。

    参数argTypes:是args传入参数对应的数据库表字段的数据类型。

    1. public int update(final String sql);
    2. public int update(String sql, @Nullable Object... args);
    3. public int update(String sql, @Nullable PreparedStatementSetter pss);
    4. public int update(String sql, Object[] args, int[] argTypes);

    1.2 update使用场景

    场景:使用update函数,可以执行数据库的delete删除数据。

    1.3 update使用举例

    1. /**
    2. * 1.delete删除语句,使用update函数
    3. * 2.update函数入参不带删除数据,数据直接写在delete语句中
    4. */
    5. public static void f11_1() {
    6. // 1.获取删除sql
    7. String sql = getDeleteSql01();
    8. // 2.获取JdbcTemplate
    9. JdbcTemplate jt = getJdbcTemplate();
    10. // 3.执行delete语句
    11. int result = jt.update(sql);
    12. // 4.遍历并打印返回值
    13. System.out.println("返回值: " + result);
    14. }
    15. /**
    16. * 1.delete删除语句,使用update函数
    17. * 2.update函数入参带删除数据
    18. */
    19. public static void f11_2() {
    20. // 1.获取删除sql
    21. String sql = getDeleteSql02();
    22. // 2.获取JdbcTemplate
    23. JdbcTemplate jt = getJdbcTemplate();
    24. // 3.组装删除条件参数
    25. Object[] args = new Object[]{"杭州", "1"};
    26. // 4.执行delete语句
    27. int result = jt.update(sql, args);
    28. // 5.打印返回值
    29. System.out.println("插入返回值: " + result);
    30. }
    31. /**
    32. * 1.delete删除语句,使用update函数
    33. * 2.update函数入参带删除数据
    34. * 3.使用PreparedStatementSetter对应入参和字段关系
    35. */
    36. public static void f11_3() {
    37. // 1.获取删除sql
    38. String sql = getDeleteSql02();
    39. // 2.获取JdbcTemplate
    40. JdbcTemplate jt = getJdbcTemplate();
    41. // 3.组装删除条件参数
    42. Object[] args = new Object[]{"杭州", "1"};
    43. // 4.执行delete语句
    44. int result = jt.update(sql, new PreparedStatementSetter() {
    45. @Override
    46. public void setValues(PreparedStatement ps) throws SQLException {
    47. ps.setObject(1, args[0]);
    48. ps.setObject(2, args[1]);
    49. }
    50. });
    51. // 5.打印返回值
    52. System.out.println("插入返回值: " + result);
    53. }
    54. /**
    55. * 1.delete删除语句,使用update函数
    56. * 2.update函数入参带删除数据,入参带参数类型
    57. */
    58. public static void f11_4() {
    59. // 1.获取删除sql
    60. String sql = getDeleteSql02();
    61. // 2.获取JdbcTemplate
    62. JdbcTemplate jt = getJdbcTemplate();
    63. // 3.组装删除条件参数
    64. Object[] args = new Object[]{"杭州", "1"};
    65. int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
    66. // 4.执行delete语句
    67. int result = jt.update(sql, args, argTypes);
    68. // 5.打印返回值
    69. System.out.println("插入返回值: " + result);
    70. }
    71. /**
    72. * 1.delete语句,删除数据
    73. * 2.使用update函数
    74. */
    75. public static String getDeleteSql01() {
    76. String sql = "DELETE FROM t_city WHERE CITY_NAME = '杭州' AND ID = '1' ";
    77. return sql.toString();
    78. }
    79. /**
    80. * 1.delete语句,删除数据
    81. * 2.使用update函数
    82. */
    83. public static String getDeleteSql02() {
    84. String sql = "DELETE FROM t_city WHERE CITY_NAME = ? AND ID = ?";
    85. return sql.toString();
    86. }

    2.batchUpdate函数

    2.1 batchUpdate函数定义

    执行数据数据库delete批量删除数据,使用batchUpdate函数实现。

    参数sql:数据库执行的SQL语句。

    参数pss:对应入参和占位符字段匹配关系。

    参数batchArgs:是SQL中有占位符?时,传入变量的方式。

    参数argTypes:是args传入参数对应的数据库表字段的数据类型。

    参数batchSize:入参大小,即batchArgs条数。

    1. public int[] batchUpdate(final String... sql);
    2. public int[] batchUpdate(String sql, List batchArgs);
    3. public int[] batchUpdate(String sql, List batchArgs, final int[] argTypes);
    4. public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss);
    5. public int[][] batchUpdate(String sql, final Collection batchArgs, final int batchSize, final ParameterizedPreparedStatementSetter pss);

    2.2 batchUpdate使用场景

    场景:使用batchUpdate函数,可以执行数据库的delete批量删除数据。

    2.3 batchUpdate使用举例

    1. /**
    2. * 1.delete删除语句,使用batchUpdate函数
    3. * 2.batchUpdate函数入参不带删除数据,数据直接写在delete语句中
    4. */
    5. public static void f12_1() {
    6. // 1.获取删除sql
    7. String[] sql = getDeleteSql03();
    8. // 2.获取JdbcTemplate
    9. JdbcTemplate jt = getJdbcTemplate();
    10. // 3.执行delete语句
    11. int[] result = jt.batchUpdate(sql);
    12. // 4.遍历并打印返回值
    13. List list = Arrays.stream(result).boxed().collect(Collectors.toList());
    14. for (Object var : list) {
    15. System.out.println("返回值: " + var);
    16. }
    17. }
    18. /**
    19. * 1.delete删除语句,使用batchUpdate函数
    20. * 2.batchUpdate函数入参带删除数据
    21. */
    22. public static void f12_2() {
    23. // 1.获取删除sql
    24. String sql = getDeleteSql02();
    25. // 2.获取JdbcTemplate
    26. JdbcTemplate jt = getJdbcTemplate();
    27. // 3.组装删除条件参数
    28. List batchArgs = getDeleteBatchArgs();
    29. // 4.执行delete语句
    30. int[] result = jt.batchUpdate(sql, batchArgs);
    31. // 5.打印返回值
    32. List list = Arrays.stream(result).boxed().collect(Collectors.toList());
    33. for (Object var : list) {
    34. System.out.println("返回值: " + var);
    35. }
    36. }
    37. /**
    38. * 1.delete删除语句,使用batchUpdate函数
    39. * 2.batchUpdate函数入参带删除数据,入参带参数类型
    40. */
    41. public static void f12_3() {
    42. // 1.获取删除sql
    43. String sql = getDeleteSql02();
    44. // 2.获取JdbcTemplate
    45. JdbcTemplate jt = getJdbcTemplate();
    46. // 3.组装删除条件参数
    47. List batchArgs = getDeleteBatchArgs();
    48. int[] argTypes = new int[]{Types.VARCHAR, Types.BIGINT};
    49. // 4.执行delete语句
    50. int[] result = jt.batchUpdate(sql, batchArgs, argTypes);
    51. // 5.打印返回值
    52. List list = Arrays.stream(result).boxed().collect(Collectors.toList());
    53. for (Object var : list) {
    54. System.out.println("返回值: " + var);
    55. }
    56. }
    57. /**
    58. * 1.delete删除语句,使用batchUpdate函数
    59. * 2.batchUpdate函数入参带删除数据
    60. * 3.使用BatchPreparedStatementSetter对应入参和字段关系
    61. */
    62. public static void f12_4() {
    63. // 1.获取删除sql
    64. String sql = getDeleteSql02();
    65. // 2.获取JdbcTemplate
    66. JdbcTemplate jt = getJdbcTemplate();
    67. // 3.组装删除条件参数
    68. List batchArgs = getDeleteBatchArgs();
    69. // 4.执行delete语句
    70. int[] result = jt.batchUpdate(sql, new BatchPreparedStatementSetter() {
    71. @Override
    72. public void setValues(PreparedStatement ps, int i) throws SQLException {
    73. // 第一行开始
    74. Object[] args = batchArgs.get(i);
    75. ps.setObject(1, args[0]);
    76. ps.setObject(2, args[1]);
    77. }
    78. @Override
    79. public int getBatchSize() {
    80. return batchArgs.size();
    81. }
    82. });
    83. // 5.打印返回值
    84. List list = Arrays.stream(result).boxed().collect(Collectors.toList());
    85. for (Object var : list) {
    86. System.out.println("返回值: " + var);
    87. }
    88. }
    89. /**
    90. * 1.delete删除语句,使用batchUpdate函数
    91. * 2.batchUpdate函数入参带删除数据
    92. * 3.使用ParameterizedPreparedStatementSetter对应入参和字段关系
    93. */
    94. public static void f12_5() {
    95. // 1.获取删除sql
    96. String sql = getDeleteSql02();
    97. // 2.获取JdbcTemplate
    98. JdbcTemplate jt = getJdbcTemplate();
    99. // 3.组装删除条件参数
    100. List batchArgs = getDeleteBatchArgs();
    101. // 4.执行delete语句
    102. int[][] result = jt.batchUpdate(sql, batchArgs, batchArgs.size(),
    103. new ParameterizedPreparedStatementSetter() {
    104. @Override
    105. public void setValues(PreparedStatement ps, Object argument) throws SQLException {
    106. Object[] args = (Object[]) argument;
    107. ps.setObject(1, args[0]);
    108. ps.setObject(2, args[1]);
    109. }
    110. });
    111. // 5.打印返回值
    112. for (int[] ints : result) {
    113. for (int anInt : ints) {
    114. System.out.println("返回值: " + anInt);
    115. }
    116. }
    117. }
    118. /**
    119. * 1.delete语句,删除数据
    120. * 2.使用update函数
    121. */
    122. public static String getDeleteSql02() {
    123. String sql = "DELETE FROM t_city WHERE CITY_NAME = ? AND ID = ?";
    124. return sql.toString();
    125. }
    126. /**
    127. * 1.delete语句,删除数据
    128. * 2.使用batchUpdate函数
    129. */
    130. public static String[] getDeleteSql03() {
    131. String sql01 = "DELETE FROM t_city WHERE CITY_NAME = '杭州' AND ID = '1' ";
    132. String sql02 = "DELETE FROM t_city WHERE CITY_NAME = '杭州' AND ID = '2' ";
    133. return new String[]{sql01, sql02};
    134. }
    135. /**
    136. * 1.delete语句
    137. * 2.获取批量删除参数
    138. */
    139. public static List getDeleteBatchArgs() {
    140. Object[] args1 = new Object[]{"杭州", "1"};
    141. Object[] args2 = new Object[]{"杭州", "2"};
    142. List batchArgs = new ArrayList<>();
    143. batchArgs.add(args1);
    144. batchArgs.add(args2);
    145. return batchArgs;
    146. }

    五、支撑

    针对本例使用JdbcTemplate对数据库的数据做查增改删操作,使用到的建表语句和数据初始化语句。

    1.建表语句

    建表语句,主键使用了MySQL的自增功能,即插入一条数据,可以不用赋值,但是赋值的话需判断不重复即可。

    1. CREATE TABLE t_city (
    2. ID BIGINT(16) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '主键',
    3. CITY_NAME VARCHAR(64) COLLATE utf8_bin NOT NULL COMMENT '城市名',
    4. LAND_AREA DOUBLE DEFAULT NULL COMMENT '城市面积',
    5. POPULATION BIGINT(16) DEFAULT NULL COMMENT '城市人口',
    6. GROSS DOUBLE DEFAULT NULL COMMENT '生产总值',
    7. CITY_DESCRIBE VARCHAR(512) COLLATE utf8_bin DEFAULT NULL COMMENT '城市描述',
    8. DATA_YEAR VARCHAR(16) COLLATE utf8_bin DEFAULT NULL COMMENT '数据年份',
    9. UPDATE_TIME DATETIME DEFAULT NULL COMMENT '更新时间'
    10. ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='城市信息表';

    2.插入语句

    插入语句,插入数据便于验证查询、更新、删除功能。

    1. INSERT INTO t_city (
    2. ID,CITY_NAME,LAND_AREA,POPULATION,
    3. GROSS,CITY_DESCRIBE,DATA_YEAR,UPDATE_TIME)
    4. VALUES
    5. ('1','杭州','16850','1200','1.61','杭州是一个好城市','2020','2022-07-23 16:39:16'),
    6. ('2','杭州','16850','1200','1.81','杭州是一个好城市','2021','2022-07-23 16:39:16');

    六、JdbcTemplate源码窥探

    JdbcTemplate源码调用逻辑,以queryForList的如下函数为例。

    public List> queryForList(String sql, @Nullable Object... args);

    1.初始化JdbcTemplate

    创建JdbcTemplate实例对象,

    (1)可以设置fetchSize,每次加载条数。

    (2)可以设置queryTimeout,执行SQL的超时时间,减低超时锁表等风险。

    (3)可以设置maxRows,限制查询最大条数。降低大数据量拖库风险。

    1. /**
    2. * 获取一个JdbcTemplate实例对象
    3. */
    4. public static JdbcTemplate getJdbcTemplate() {
    5. String username = "***自定义填写**";
    6. String password = "***自定义填写**";
    7. String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/***自定义填写**";
    8. String driverName = "com.mysql.cj.jdbc.Driver";
    9. DruidDataSource dataSource = new DruidDataSource();
    10. dataSource.setPassword(password);
    11. dataSource.setUrl(jdbcUrl);
    12. dataSource.setUsername(username);
    13. dataSource.setDriverClassName(driverName);
    14. JdbcTemplate jdbcTemplate = new JdbcTemplate();
    15. jdbcTemplate.setDataSource(dataSource);
    16. return jdbcTemplate;
    17. }

    2.调用queryForList

    调用queryForList,具体可以查看queryForList举例。

    (1)调用query函数。

    (2)调用getColumnMapRowMapper,会创建ColumnMapRowMapper对数据库数据集以字段名称和字段值映射到Map的key和value中。

    1. public List> queryForList(String sql, @Nullable Object... args) throws DataAccessException {
    2. return this.query(sql, args, this.getColumnMapRowMapper());
    3. }

    3.调用query

    调用query,创建RowMapperResultSetExtractor,处理结果集的实例对象。

    1. public List query(String sql, @Nullable Object[] args, RowMapper rowMapper) throws DataAccessException {
    2. return (List)result(this.query((String)sql, (Object[])args, (ResultSetExtractor)(new RowMapperResultSetExtractor(rowMapper))));
    3. }

    4.调用query

    调用query,创建ArgumentPreparedStatementSetter,处理参数的实例对象。

    1. public T query(String sql, @Nullable Object[] args, ResultSetExtractor rse) throws DataAccessException {
    2. return this.query(sql, this.newArgPreparedStatementSetter(args), rse);
    3. }

    5.调用query

    调用query,创建SimplePreparedStatementCreator,处理SQL的实例对象。

    1. public T query(String sql, @Nullable PreparedStatementSetter pss, ResultSetExtractor rse) throws DataAccessException {
    2. return this.query((PreparedStatementCreator)(new JdbcTemplate.SimplePreparedStatementCreator(sql)), (PreparedStatementSetter)pss, (ResultSetExtractor)rse);
    3. }

    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函数具体执行。

    1. public T query(PreparedStatementCreator psc, @Nullable final PreparedStatementSetter pss, final ResultSetExtractor rse) throws DataAccessException {
    2. Assert.notNull(rse, "ResultSetExtractor must not be null");
    3. this.logger.debug("Executing prepared SQL query");
    4. return this.execute(psc, new PreparedStatementCallback() {
    5. @Nullable
    6. public T doInPreparedStatement(PreparedStatement ps) throws SQLException {
    7. ResultSet rs = null;
    8. Object var3;
    9. try {
    10. if (pss != null) {
    11. pss.setValues(ps);
    12. }
    13. rs = ps.executeQuery();
    14. var3 = rse.extractData(rs);
    15. } finally {
    16. JdbcUtils.closeResultSet(rs);
    17. if (pss instanceof ParameterDisposer) {
    18. ((ParameterDisposer)pss).cleanupParameters();
    19. }
    20. }
    21. return var3;
    22. }
    23. }, true);
    24. }

    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释放连接,释放资源。

    1. private T execute(PreparedStatementCreator psc, PreparedStatementCallback action, boolean closeResources) throws DataAccessException {
    2. Assert.notNull(psc, "PreparedStatementCreator must not be null");
    3. Assert.notNull(action, "Callback object must not be null");
    4. if (this.logger.isDebugEnabled()) {
    5. String sql = getSql(psc);
    6. this.logger.debug("Executing prepared SQL statement" + (sql != null ? " [" + sql + "]" : ""));
    7. }
    8. Connection con = DataSourceUtils.getConnection(this.obtainDataSource());
    9. PreparedStatement ps = null;
    10. Object var14;
    11. try {
    12. ps = psc.createPreparedStatement(con);
    13. this.applyStatementSettings(ps);
    14. T result = action.doInPreparedStatement(ps);
    15. this.handleWarnings((Statement)ps);
    16. var14 = result;
    17. } catch (SQLException var11) {
    18. if (psc instanceof ParameterDisposer) {
    19. ((ParameterDisposer)psc).cleanupParameters();
    20. }
    21. String sql = getSql(psc);
    22. psc = null;
    23. JdbcUtils.closeStatement(ps);
    24. ps = null;
    25. DataSourceUtils.releaseConnection(con, this.getDataSource());
    26. con = null;
    27. throw this.translateException("PreparedStatementCallback", sql, var11);
    28. } finally {
    29. if (closeResources) {
    30. if (psc instanceof ParameterDisposer) {
    31. ((ParameterDisposer)psc).cleanupParameters();
    32. }
    33. JdbcUtils.closeStatement(ps);
    34. DataSourceUtils.releaseConnection(con, this.getDataSource());
    35. }
    36. }
    37. return var14;
    38. }

    以下步骤,已经是比较底层内容了。

    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驱动包里面类,例如下:

    1. public ResultSet executeQuery() throws SQLException {
    2. ResultSet rs = null;
    3. try {
    4. if (this.wrappedStmt == null) {
    5. throw SQLError.createSQLException(Messages.getString("Statement.AlreadyClosed"), "S1000", this.exceptionInterceptor);
    6. }
    7. rs = ((PreparedStatement)this.wrappedStmt).executeQuery();
    8. ((ResultSetInternalMethods)rs).setWrapperStatement(this);
    9. } catch (SQLException var3) {
    10. this.checkAndFireConnectionError(var3);
    11. }
    12. return rs;
    13. }

    8.3调用extractData

    调用extractData,即org.springframework.jdbc.core.RowMapperResultSetExtractor

    本质上还是去遍历ResultSet结果集去包装返回值,

    ResultSet,即java.sql.ResultSet,也是底层原始Java的类。

    1. public List extractData(ResultSet rs) throws SQLException {
    2. List results = this.rowsExpected > 0 ? new ArrayList(this.rowsExpected) : new ArrayList();
    3. int var3 = 0;
    4. while(rs.next()) {
    5. results.add(this.rowMapper.mapRow(rs, var3++));
    6. }
    7. return results;
    8. }

    以上,感谢。

    2022年8月6日

  • 相关阅读:
    MVSNet depthfusion配置流程
    C语言-数组
    python零基础入门 (6)-- python的函数
    判断某点是否在三角形内(Python)
    CompletableFuture详解
    大数据:【学习笔记系列】Flink基础架构
    idea git提交代码
    泡泡玛特加速海外布局,泰国首店开业吸引超千名粉丝排队
    位图BitMap不好用?那来看看进化版本的RoaringBitmap,包您满意
    多任务多场景
  • 原文地址:https://blog.csdn.net/zhangbeizhen18/article/details/126201698