● 基本介绍
- 通过 Spring 可以配置数据源,从而完成对数据表的操作
- JdbcTemplate 是 Spring 提供的访问数据库的技术。可以将 JDBC 的常用操作封装为模板方法。
使用API的技巧
- 先确定API的名字
- 根据API提供的相应的参数
- 把自己的调用思路清晰
使用 JdbcTemplate
查询 (SELECT
)
单行单列
第一种方式
这种写法是更推荐的方式,特别适用于查询单行单列并将结果映射到指定类型的情况。通过传递结果的预期类型作为
requiredType
参数,您可以确保查询结果将直接映射到该类型,而不需要手动编写RowMapper
实现。
@Test
public void test11() {
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
// 确定API
// public <T> T queryForObject(String sql, Class<T> requiredType, @Nullable Object... args)
String sql = "select name from monster where id = ?";
String name = jdbcTemplate.queryForObject(sql, String.class, 200);
System.out.println("name = " + name);
}
第二种方式
@Test
public void test10() {
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
// 确定API
// <T> T queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object... args)
String sql = "select name from monster where id = ?";
String name = jdbcTemplate.queryForObject(sql,
(ResultSet rs, int rowNum) -> rs.getString("name"), 200);
System.out.println("name = " + name);
}
单个对象
第一种方式
@Test
public void test6() {
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
// 确定API
// <T> T queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object... args)
String sql = "select id AS `monsterId`, name, skill from monster where id = ?";
//这里有一个细节就是名称需要一样, 即查询的表字需要和查询的字段保持一致
RowMapper<Monster> rowMapper = new RowMapper<Monster>() {
@Override
public Monster mapRow(ResultSet rs, int rowNum) throws SQLException {
Monster monster = new Monster();
monster.setSkill(rs.getString("skill"));
monster.setName(rs.getString("name"));
monster.setMonsterId(rs.getInt("monsterId"));
return monster;
}
};
// 可以使用lambda表达式简化
Monster monster = jdbcTemplate.queryForObject(sql, rowMapper, 100);
System.out.println("monster = " + monster);
}
第二种方式
@Test
public void test7() {
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
// 确定API
// <T> T queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object... args)
String sql = "select id AS `monsterId`, name, skill from monster where id = ?";
// 使用子类实现对象的封装
RowMapper<Monster> rowMapper = new BeanPropertyRowMapper<>(Monster.class);
Monster monster = jdbcTemplate.queryForObject(sql, rowMapper, 100);
System.out.println("monster = " + monster);
}
test6()
方法使用了匿名内部类实现的RowMapper
,在mapRow()
方法中手动设置了查询结果的映射关系,将查询结果映射到Monster
对象中。test7()
方法使用了BeanPropertyRowMapper
,它是Spring提供的一种方便的RowMapper
实现,可以根据结果集的列名和目标对象的属性名进行自动映射。
两种写法都是可以的,但有一些考虑因素可以帮助您选择适合您的情况:
- 如果您的查询结果需要进行
自定义的映射逻辑
,或者需要处理一些特殊的转换操作
,您可以选择test6()
的写法,并通过自定义的RowMapper
实现进行映射。 - 如果您的查询结果与目标对象的属性名和类型完全一致,或者您不需要进行额外的映射操作,您可以选择
test7()
的写法,并使用BeanPropertyRowMapper
进行自动映射。
总体而言,test7()
的写法更加简洁和方便,因为它利用了BeanPropertyRowMapper
的自动映射功能,可以减少手动编写映射逻辑的工作量。然而,如果您需要更复杂的映射逻辑或转换操作,test6()
的写法可以给您更大的灵活性
多个对象
方式一
@Test
public void test9() {
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
// 确定API
String sql = "select id AS `monsterId`, name, skill from monster where id > ?";
RowMapper<Monster> rowMapper = new BeanPropertyRowMapper<>(Monster.class);
List<Monster> query = jdbcTemplate.query(sql, rowMapper, 100);
for (Monster monster : query) {
System.out.println("monster = " + monster);
}
}
方式二
@Test
public void test8() {
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
// 确定API
// <T> T queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object... args)
String sql = "select id AS `monsterId`, name, skill from monster where id > ?";
// 使用lambda表达式简化
List<Monster> monsterList = jdbcTemplate.query(sql,
(ResultSet rs, int rowNum) -> {
Monster monsters = new Monster(rs.getInt("monsterId"), rs.getString("name"), rs.getString("skill"));
return monsters;
}, 100);
for (Monster monster : monsterList) {
System.out.println("monster = " + monster);
}
}
更新(INSERT
、UPDATE
和 DELETE
)
你可以使用 update(..)
方法来执行插入、更新和删除操作。参数值通常作为变量参数提供,或者作为一个对象数组提供
INSERT
this.jdbcTemplate.update( "insert into t_actor (first_name, last_name) values (?, ?)", "Leonor", "Watling");
如何实现插入多条数据 ?
@Test
public void test5() {
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
// 1. 批量插入 猜测update => 根据参数修改名称是 batchUpdate// 2. 根据参数提供数据
String sql = "insert into monster values (?, ?, ?)";
List<Object[]> list = new ArrayList<>();
list.add(new Object[]{700, "老鼠精", "偷吃粮食"});
list.add(new Object[]{800, "老猫精", "抓老鼠"});
// 3. 调试
// 说明:
// 返回结果是一个数组, 每一个元素对应的上面的sql语句影响的行数
int[] ints = jdbcTemplate.batchUpdate(sql, list);
// 4. 输出
for (int anInt : ints) {
System.out.println("anInt: " + anInt);
}
System.out.println("add ok ~");
}
UPDATE
this.jdbcTemplate.update(
"update t_actor set last_name = ? where id = ?",
"Banjo", 5276L);
DELETE
this.jdbcTemplate.update(
"delete from t_actor where id = ?",
Long.valueOf(actorId));
使用 NamedParameterJdbcTemplate
具名参数
具名参数的写法具有以下特点:
- 使用冒号(
:
)作为参数的前缀,例如:id
、:name
和:skill
。 - 冒号后面的字符串是参数的名称,用于在
Map
对象中进行参数值的映射。 - SQL语句中的具名参数和实际的参数值将在执行时进行匹配和替换。
@Test
public void test12() {
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("bean.xml");
NamedParameterJdbcTemplate namedParameterJdbcTemplate = ioc.getBean(NamedParameterJdbcTemplate.class);
// 具名参数
// :id, :name, :skill 不需要知道表的结构
String sql = "insert into monster values (:id, :name, :skill)";
Map<String, Object> map = new HashMap<>();
map.put("id", 900);
map.put("name", "蚂蚁精");
map.put("skill", "喜欢打洞");
int affected = namedParameterJdbcTemplate.update(sql, map);
System.out.println("affected = " + affected);
}
xml
文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans">
<!-- 配置数据源对象-DataSource-->
<bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
<property name="user" value="root"/>
<property name="password" value="hsp"/>
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring"/>
</bean>
<bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置 NamedParameterJdbcTemplate--><bean class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate" id="parameterJdbcTemplate">
<!-- 通过构造器, 设置属性-->
<constructor-arg name="dataSource" ref="dataSource" />
</bean>
</beans>
中文文档地址: springdoc.cn/
© 版权声明
文章版权归作者所有,未经允许请勿转载,侵权请联系 admin@trc20.tw 删除。
THE END