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

news/2024/11/29 6:29:04/

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() {@Overridepublic void setValues(PreparedStatement ps, int i) throws SQLException {ps.setObject(1, foos.get(i).getId());ps.setObject(2, foos.get(i).getBar());}@Overridepublic int getBatchSize() {return 3;}});
}

http://www.ppmy.cn/news/676585.html

相关文章

什么是天线轴比

天线的轴比定义&#xff1a;任意极化波的瞬时电场矢量的端点轨迹为一椭圆&#xff0c;椭圆的长轴2A和短轴2B。 椭圆极化波的特性可用三个参数来描述&#xff0c;即旋转方向、椭圆极化轴比及椭圆的倾角&#xff0c;其中轴比是椭圆长轴与短轴之比。椭圆极化当轴比为无穷大时&…

宽窄带天线的区别w

窄带和宽带的区分也就是相对带宽的大小Br(fh-fl)/f0*100%&#xff0c;一般相对带宽小于1%的为窄带天线&#xff0c;1%至25%的为宽带天线&#xff0c;大于25%的为超宽带天线

天线越大越好吗_路由器的天线是不是越多越好?告知你真实答案,很多人都买错了...

路由器作为电脑上网流量共享以及手机WIFI上网必备的器材&#xff0c;经过十余年的发展&#xff0c;从最初的无WIFI功能路由器到今天的智能路由器&#xff0c;再到单天线路由器到目前的N个天线路由器。相信很多人对此就会产生疑问&#xff0c;那就是路由器的天线是不是越多越好&…

天线越大越好吗_天线越多无线WIFI信号就越强?选购无线路由器常见三大误区...

很多人在购买无线路由器的时候容易被外观所迷惑&#xff0c;而厂家也正抓住消费者的错误理解&#xff0c;生产的天线一个比一个多&#xff0c;甚至8根天线的路由器都出来了。下面装机之家小编来讲讲选购无线路由器常见三大误区。 第一&#xff1a;天线越多无线WiFi信号就越好&a…

天线越大越好吗_无线路由器真的是天线越多越好吗?

现在网络速度大幅提高后&#xff0c;很大一批老一代的无线路由器就显得不是那么好用了&#xff0c;最新的产品&#xff0c;比如4根天线的路由器&#xff0c;甚至更多天线&#xff0c;那么&#xff0c;到底是什么决定了无线路由器的性能&#xff0c;真的是天线根数吗&#xff1f…

电脑的wifi天线原理_详解无线路由器天线的原理

相信无线路由器是每一个家庭必备的网络设备&#xff0c;而WiFi这一词语相信很多用户也明白它的大体含义&#xff0c;不过WiFi无线信号具体传输的原理就不是用户所能了解的。直白的说无线信号传输的过程非常简单&#xff0c;WiFi无线信号就是通过路由器天线这一媒介向周围空间辐…

无线路由器天线上绑几个电池,真的会增强发射信号吗?

无线路由器天线上绑几个电池&#xff0c;不会增强发射信号&#xff0c;且也是没有任何科学根据的。 如下图实验&#xff1a;绑电池前信号强度是“-39dBm”&#xff0c;绑电池后信号强度是“-43dBm”。 信号强度理论上是绝对值越小越好&#xff0c;然后绑定电池后却变大了&…

常见的天线种类

常见的天线种类 RF模块都需要输入输出设备来实现数据的接收与发送&#xff0c;而天线就是用来接收和发射信息&#xff0c;不同的产品对天线的要求不一样&#xff0c;而不同的天线也对模块的性能产生影响。我们将介绍常见的天线类别&#xff0c;主要是消费品电子。 天线种类 …