SpingData-JDBC(看这篇文章就够了,新手入门指引)

news/2024/5/19 1:46:31 标签: 数据库, jdbc, jdbctemplate, spring jdbc

JdbcTemplate 的基本使用

写在前面:
在这里插入图片描述
当DDL操作时,一般是用execute方法,这也是一种规范吧,这个也可以运行DML但是通常来说我DML操作是需要返回值的,一般就是返回影响的行数。然后这篇文章主要介绍增删改查,因为表格的创建一般已经完成了。

查询

  1. query 方法
  • 描述
    在这里插入图片描述
    从描述我们可以清楚的看到,普通的query 方法执行静态sql,使用的是Statement,如果需要使用PreparedStatement,可以看到还有一个方法query(String, Object[], ResultSetExtractor),只需要将数据参数传为null即可。
  • code demo
    使用ResultSetExtractor是一个函数式接口,每一行在内部进行处理,返回最终的处理结果,这一点与下面的行处理进行对比就可以很直观的看出来。
public List<Foo> demoQuery() {
    List<Foo> result = jdbcTemplate.query("SELECT ID,BAR FROM foo", (rs) -> {
        List<Foo> res = new ArrayList<>();
        while (rs.next()) {
            Long id = rs.getLong(1);
            String bar = rs.getString("BAR");
            Foo foo = new Foo(id, bar);
            res.add(foo);
        }
        return res;
    });
    return result;
}

使用行处理器RowCallbackHandler

public List<Foo> demoQuery() {
    List<Foo> res = new ArrayList<>();
    // 需要传一个行处理器,由于是函数式接口所以可以采用lamda表达式
    jdbcTemplate.query("SELECT ID,BAR FROM foo",(rs) -> {
        // 这里可以将对象进行映射,或者做其它的一些处理
        while (rs.next()) {
            Long id = rs.getLong(1);
            String bar = rs.getString("BAR");
            Foo foo = new Foo(id, bar);
            res.add(foo);
        }
    });
    return res;
}

使用PreparedStatement

正如上面描述所说,上面的两段代码使用的是Statement,下面演示一下PreparedStatement的用法:

public List<Foo> demoQuery1() {
 List<Foo> result = jdbcTemplate.query("SELECT ID,BAR FROM foo WHERE ID IN (?,?,?)" ,new Object[]{2,3,4}, (rs) -> {
     List<Foo> res = new ArrayList<>();
     while (rs.next()) {
         Long id = rs.getLong(1);
         String bar = rs.getString("BAR");
         Foo foo = new Foo(id, bar);
         res.add(foo);
     }
     return res;
 });
 return result;
}

List query(String sql, RowMapper rowMapper) 这个方法就是有一个RowMapper 将数据映射为我们需要的数据,比如映射为一个Map

// ColumnMapRowMapper Spring JDBC 提供的一个实现
// 这里的实现完全和public Map<String, Object> queryForMap(String sql); 这个方法一样,只是这个方法把转换的Mapper 写到了里面
List<Map<String, Object>> resultMap = jdbcTemplate.query("SELECT ID,BAR FROM foo", new ColumnMapRowMapper());

在这里插入图片描述

当然也可以自定义:

// 同样使用lamada 表达式
List<Foo> foos = jdbcTemplate.query("SELECT ID,BAR FROM foo", (rs, rowIndex) -> {
    long id = rs.getLong("ID");
    String bar = rs.getString("BAR");
    Foo foo = new Foo(id, bar);
    return foo;
});

这是第一部分,相当于是对于数据的映射需要我们自己来处理,jdbcTemplate提供了一写其它方法比如queryForObject,queryForLis见(2)
2) 不用自己处理映射关系的方法,也
T queryForObject(String sql, Class requiredType)
List queryForList(String sql, Object[] args, int[] argTypes, Class elementType)
在这里插入图片描述
在这里插入图片描述
可以看到里面都是用了SingleColumnRowMapper,所以这两个方法不太好用,如果列超过了1就会抛出异常,只适合返回一个字段的场景

List<String> foos = jdbcTemplate.queryForList("SELECT BAR FROM foo", String.class);

如果需要映射为对象还是需要用(1)中的方法映射,或者直接使用下面这个方法,返回一个Map的集合:

public List<Map<String, Object>> queryForList(String sql) throws DataAccessException {
	return query(sql, getColumnMapRowMapper());
}

插入

1) 使用update 这一类方法进行插入或更新,文档描述直接写了的
在这里插入图片描述
普通的使用

public Object demoInsert() {
    String sql = "INSERT INTO FOO (ID,BAR) VALUES('100','HHH')";
    // 返回的是插入以后影响的行数
    int update = jdbcTemplate.update(sql);
    return update;
}

预编译SQL

public Object demoInsert() {
     String sql = "INSERT INTO FOO (ID,BAR) VALUES(?,?)";
     // 返回的是插入以后影响的行数
     int update = jdbcTemplate.update(sql, new Object[]{100, "hhh"});
     // 当然也是可以直接写参数的,这种直接写更常用
     int update = jdbcTemplate.update(sql, 200,"mmm");
     return update;
 }

也可以不通过参数列表的形式,而是直接传递一个PreparedStatementSetter

public Object demoInsert() {
    String sql = "INSERT INTO FOO (ID,BAR) VALUES(?,?)";
    Map<String, Object> map = new HashMap<String,Object>(){{
        put("ID", 100);
        put("BAR", "bar");
    }};
    // 返回的是插入以后影响的行数
    int update = jdbcTemplate.update(sql, (ps) -> {
        ps.setObject(1, map.get("ID"));
        ps.setObject(2, map.get("BAR"));
    });
    return update;
}

2)SimpleJdbcInsert 这是包里面提供了一个类也可以做插入的操作,某些场景下可能还是比较方便的
首先我们需要注入将这个bean注入到容器

@Bean
@Autowired
public SimpleJdbcInsert simpleJdbcInsert(JdbcTemplate jdbcTemplate) {
	return new SimpleJdbcInsert(jdbcTemplate)
		 // 这里指定了bean 同时指定了主键自增策略
		.withTableName("FOO").usingGeneratedKeyColumns("ID");
}

插入后返回主键

public Number insertData() {
        Map<String, Object> row = new HashMap<>();
        row.put("bar", "c");
        // 插入后返回主键
        Number number = simpleJdbcInsert.executeAndReturnKey(row);
        return number;
    }

executeAndReturnKey 方法需要的参数是列名和值的map映射集合。

更新

更新用的方法依然是updata这一类函数,返回的同样是受影响的函数

public Object demoUpdate() {
  String sql = "UPDATE  FOO SET BAR = ? WHERE ID = ?";
  // 返回的是插入以后影响的行数
  int update = jdbcTemplate.update(sql, "UP", 2);
  int update = jdbcTemplate.update(sql, new Object[]{2,"up"});
  return update;
}

和插入基本差不多的,也可以像下面这么写:

public Object demoUpdate() {
   String sql = "UPDATE  FOO SET BAR = ? WHERE ID = ?";
   Map<String, Object> map = new HashMap<String,Object>(){{
       put("ID", 2);
       put("BAR", "TTT");
   }};
   // 返回的是插入以后影响的行数
   int update = jdbcTemplate.update(sql, (ps) -> {
       ps.setObject(2, map.get("ID"));
       ps.setObject(1, map.get("BAR"));
   });
   return update;
}

删除

删除操作

public void demoDelete() {
    String sql = "DELETE FROM foo WHERE ID= ?";
    int update = jdbcTemplate.update(sql, 2);
    System.out.println(update);
}

批量

对于批量操作来说,主要是批量更新和批量插入操作。
1)使用

@Bean
@Autowired
public NamedParameterJdbcTemplate namedParameterJdbcTemplate(DataSource dataSource) {
	return new NamedParameterJdbcTemplate(dataSource);
}

插入注入NamedParameterJdbcTemplate 后可以批量插入

@Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
List<Foo> list = new ArrayList<>();
        list.add(Foo.builder().id(100L).bar("b-100").build());
        list.add(Foo.builder().id(101L).bar("b-101").build());
        namedParameterJdbcTemplate
                .batchUpdate("INSERT INTO FOO (ID, BAR) VALUES (:id, :bar)",
                        SqlParameterSourceUtils.createBatch(list));

2 使用JdbcTemplate

public void batchInsert() {
       List<Foo> foos = new ArrayList<Foo>(){{
           add(new Foo(100L, "10t0"));
           add(new Foo(200L, "20t0"));
           add(new Foo(300L, "30t0"));
       }};
       jdbcTemplate.batchUpdate("INSERT INTO FOO (ID,BAR) VALUES (?,?)",
               new BatchPreparedStatementSetter() {
                   @Override
                   public void setValues(PreparedStatement ps, int i) throws SQLException {
                       ps.setObject(1, foos.get(i).getId());
                       ps.setObject(2, foos.get(i).getBar());
                   }
                   @Override
                   public int getBatchSize() {
                       return 3;
                   }
               });
}

http://www.niftyadmin.cn/n/1006671.html

相关文章

大神博客。。。

JUC AQS ReentrantLock源码分析&#xff08;一&#xff09;_reentrantlock 子路_shadow?s的博客-CSDN博客 / reentrantLock https://www.cnblogs.com/liuyk-code/p/9886033.html springaop spring 源码解析&#xff08;一&#xff09;_鑫鑫向荣&#xff08;霍&#xff09;的…

【数学公式】一元三次方程求解

通用求根公式① 计算公式与步骤 a x 3 b x 3 c x d 0 ax^3bx^3cxd 0 ax3bx3cxd0 ① 计算 u u u和 v v v u 9 a b c − 27 a 2 d − 2 n 3 54 a 3 u \frac {9abc-27a^2d-2n3} {54a^3} u54a39abc−27a2d−2n3​ v 3 ( 4 a c 3 − b 2 c 2 − 18 a b c d 27 a 2 d 2 4…

C#ComponentResourceManager未声明或未赋值解决办法

一、由于VS无法直接打开.resources文件&#xff0c;但有时我们会遇到要将.resources转换为.resx文件的情况。 步骤&#xff1a; 1、将下面代码复制保存到*.bat&#xff0c;如&#xff1a;ConvertRes.bat echo off &setlocal enabledelayedexpansion rem echo 当前目录:%…

css新特性(五)

css基础&#xff08;一&#xff09;css基础&#xff08;一&#xff09;_上半场结束&#xff0c;中场已休息&#xff0c;下半场ing的博客-CSDN博客Emmet语法Emmet语法_上半场结束&#xff0c;中场已休息&#xff0c;下半场ing的博客-CSDN博客css基础&#xff08;二&#xff09;c…

POI合并单元格设置单元格样式

文章目录 设置居中设置背景颜色设置边框设置字体合并单元格实际使用运行效果 设置居中 CellStyle centerStyle wb.createCellStyle();centerStyle.setAlignment(HorizontalAlignment.CENTER); // 居中centerStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中设…

debug调试高级用法

文章目录 前言一、如何给程序加断点,并调试二、开始调试1.断点查看2.查看所有断点,去掉断点,批量去断点3. 断点改值4. 断点条件 总结 前言 在开发调试中,如果你不会debug调试,一般情况下,就只能控制台打印,然后一遍一遍重启了,所有debug是必不可少的技能,尤其当遇到问题的时候…

用户实操 | GBase 8a MPP Cluster慢SQL分析排查和优化方法

本期供稿 | 中国农业银行研发中心 蔡鹍鹏 01 排查和优化方法 SQL任务历史性能对比分析&#xff1a; 通过开启GBase 8a的audit_log审计日志&#xff0c;可以连续收集周期性任务的执行时间&#xff0c;通过对比相同SQL任务历史执行时长可以判定相同任务SQL长周期内的执行耗时趋…

论文导读 | Operation ResearchManagement Science近期文章精选

推文作者&#xff1a;周梓渊 编者按 本期我们选取了最近来自Operation Research和Management Science的六篇文章以飨读者&#xff0c;前四篇文章来自OR&#xff0c;最后两篇文章来自MS&#xff1b;内容涉及多个方面&#xff0c;实现了方法论与具体应用实践的结合&#xff0c;例…