1,JdbcTemplate 基本知识
- JdbcTemplate是Spring的一部分,是对数据库的操作在jdbc的封装,处理了资源的建立和释放(不需要我们管理连接了),我们只需要提供SQL语句(不需要我们设置参数了)和提取结果(查询时候可以直接返回对应的实体类),使JDBC更加易于使用。
- JdbcTemplate使用spring的注入功能,把DataSource注册到JdbcTemplate之中。
- DataSource是JDBC2.0提供了javax.sql.DataSource接口,它负责建立与数据库的连接,当在应用程序中访问数据库时不必编写连接数据库的代码,直接引用DataSource获取数据库的连接对象即可。用于获取操作数据Connection对象。
- 除了JDBC外都有DataSource对象。DataSource可以看作数据源,它封装了数据库参数,连接数据库,程序中操作DataSource对象即可对数据库进行增删改查操作。
不同方式中使用的DataSource对象不同。列举如下:
1,DBCP框架
dbcp框架中的DataSource类是:org.apache.commons.dbcp.BasicDataSource
这是commons-dbcp.jar包中的类。
2,C3P0框架
c3p0框架的DataSource类是:com.mchange.v2.c3p0.ComboPooledDataSource
这是c3p0.jar包中的类。
3,MyBatis框架
MyBatis框架的DataSource类是:org.apache.ibatis.datasource.pooled.PooledDataSource
这是mybatis.jar包中的类。
2,Spring Boot之JdbcTemplate基本配置
a,在pom.xml文件中添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
b,在application.properties文件中配置数据的信息
// secondary为我设置的第二数据库,如果是第一数据库省略该字段
// XXX.XXX.XXX.XXX为数据库的连接地址
spring.datasource.secondary.url =jdbc:sqlserver://XXX.XXX.XXX.XXX;database=cbhstmps
// 数据库的登录用户名
spring.datasource.secondary.username = XXX
// 数据库的登录密码
spring.datasource.secondary.password = XXXX
// sqlserver数据库的驱动
spring.datasource.driver-class-name = com.microsoft.sqlserver.jdbc.SQLServerDriver
// mysql数据库的驱动
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
// Oracle数据库的驱动
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
3,jdbcTmeplate的crud操作
3.1 T queryForObject(String sql, Class requiredType) --返回一个值
// 注意:参数requiredType只能是String,Integer这种类型,不能是自定义的实体类型,只能返回一个值,不能映射对象(映射对象下面会说)
public <T> T queryForObject(String sql, Class<T> requiredType) throws DataAccessException {
return this.queryForObject(sql, this.getSingleColumnRowMapper(requiredType));
}
// 使用
int count = jdbcTemplate.queryForObject("select count(*) from AAA", Integer.class);
3.2 T queryForObject(String sql, Object[] args, Class requiredType) --返回一个值
// 注入参数
public <T> T queryForObject(String sql, Object[] args, Class<T> requiredType) throws DataAccessException {
return this.queryForObject(sql, args, this.getSingleColumnRowMapper(requiredType));
}
// 使用
String name = jdbcTemplate.queryForObject("select name from AAA where id =?",new Object[]{id}, String.class);
// 相关,设置了参数类型
T queryForObject(String sql, Object[] args, int[] argTypes, Class<T> requiredType)
3.3 T queryForObject(String sql, RowMapper rowMapper) --返回一行记录,记录转换为一个对象
public void test() {
String sql = "select name,age from work_steps where id = 110";
WorkstepsEntity customer = jdbcTemplate.queryForObject(sql, new RowMapper<WorkstepsEntity>() {
@Override
public WorkstepsEntity mapRow(ResultSet rs, int i) throws SQLException {
WorkstepsEntity works = new WorkstepsEntity();
works.setName(rs.getString("name"));
works.setAge(rs.getInt("age"));
return works;
}
});
}
3.4 T queryForObject(String sql, Object[] args, RowMapper rowMapper) --注入参数,返回一行记录,记录转换为一个对象
public void test() {
String sql = "select name,age from work_steps where id = ?";
String id = "100010";
WorkstepsEntity customer = jdbcTemplate.queryForObject(sql,new Object[]{id}, new RowMapper<WorkstepsEntity>() {
@Override
public WorkstepsEntity mapRow(ResultSet rs, int i) throws SQLException {
WorkstepsEntity works = new WorkstepsEntity();
works.setName(rs.getString("name"));
works.setAge(rs.getInt("age"));
return works;
}
});
}
3.5 List<Map<String, Object>> queryForList(String sql) --返回一个list集合 ,
public void test() {
//如果Oracle用这个sql查询,返回的列名就是NAME(大写的),对应Map里面的key就是NAME
String sql = "select name from test where id > 0";
//如果用这个sql查询,返回的列名就是name(小写的),对应Map里面的key就是name
String sql2 = "select name as \"name\" from test where id > 0";
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);//这里用的是第一个sql
}
3.6 List<> queryForList(String sql, Class elementType) --返回一个指定数据类型的list集合 ,
public void test() {
String sql = "select name from test where age > 18";
List<String> list = jdbcTemplate.queryForList(sql,String.class);
}
3.7 List<> queryForList(String sql, Object[] args, Class elementType) --返回一个指定数据类型的list集合 ,可设置参数
public void test() {
String age="18";
String sql = "select name from test where age > ?";
List<String> list = jdbcTemplate.queryForList(sql,new Object[]{age},String.class);
}
或者
public void test() {
String age="18";
String sql = "select * from test where age > ?";
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql,new Object[]{age});
}
3.8 List<> query(String sql, RowMapper rowMapper) --返回一个list<对象>
public void test() {
String sql = "select name,age from test where id > 10";
List<CbhsXmftUnitmapEntity> list = jdbcTemplate.query(sql, new RowMapper<CbhsXmftUnitmapEntity>() {
@Override
public CbhsXmftUnitmapEntity mapRow(ResultSet rs, int rowNum) throws SQLException {
//这里必须new对象,如果不new,而是使用同一个对象,会导致存入到List中的都是一样的对象(都是最后一个对象)。
CbhsXmftUnitmapEntity cbhsXmftUnitmapEntity = new CbhsXmftUnitmapEntity();
cbhsXmftUnitmapEntity.setName(rs.getString("name"));
cbhsXmftUnitmapEntity.setAge(rs.getInt("age"));
return cbhsXmftUnitmapEntity;
}
});
}
补充:当我想返回的实体类正好是查询的表的时候
public void test() {
String sql = "select * from test where id > 10";
List<TestEntity> list = listpc=jdbcTemplate.query(sql ,new BeanPropertyRowMapper(TestEntity.class));
}
// 从其他数据处提取数据源并解决重复
Set<String> itemCodeList =
list.stream().collect(Collectors.groupingBy(new Function<Map<String, Object>, String>() {
@Override
public String apply(Map<String, Object> stringObjectMap) {
return stringObjectMap.get("ItemCode").toString();
}
}, Collectors.toList())).keySet();
//将处理后的数据作为条件参数
Map<String, BigDecimal> bigDecimalMap = commonApiDao.getScrollData(CbhsXmftCagitemEntity.class,
"itemCode in (?0)", new Object[]{itemCodeList}, new LinkedHashMap<>()
).getResultlist().stream().collect(
Collectors.toMap(CbhsXmftCagitemEntity::getItemCode, new Function<CbhsXmftCagitemEntity, BigDecimal>() {
@Override
public BigDecimal apply(CbhsXmftCagitemEntity cbhsXmftCagitemEntity) {
return cbhsXmftCagitemEntity.getPrice();
}
})
);
3.9 List<Map<>> query(String sql, RowMapper rowMapper) --返回一个list<Map<>>
public void test() {
String sql = "select name,age from test where id > 10";
List<Map<Integer,Object>> list = jdbcTemplate.query(sql, new RowMapper<Map<Integer,Object>>() {
@Override
public Map<Integer,Object> mapRow(ResultSet rs, int rowNum) throws SQLException {
Map<Integer,Object> objectMap = new Map<Integer,Object>();
objectMap.put(rowNum,rs.getString("name"));
objectMap.put(rowNum,rs.getInt("age"));
return objectMap;
}
});
}
3.10 List<> query(String sql, PreparedStatementSetter pss, RowMapper rowMapper) --返回一个list<对象>,可进行参数设置
public void test(final Integer id) {//参数也是局部变量,也必须用final修饰,内部类中才能访问(全局变量不用)
String sql = "select name,age from test where id > ?";
List<CbhsXmftUnitmapEntity> list = jdbcTemplate.query(sql, new PreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps)
throws SQLException {
ps.setInt(1, id);
}
}, new RowMapper<CbhsXmftUnitmapEntity>() {
@Override
public CbhsXmftUnitmapEntity mapRow(ResultSet rs, int rowNum)
throws SQLException {
CbhsXmftUnitmapEntity customer = new CbhsXmftUnitmapEntity();
customer.setName(rs.getString("name"));
customer.setAge(rs.getInt("age"));
return customer;
}
});
}
补充:自定义List<Object[]>数据类型参数
无返回数据,只需sql和参数
String sql = "delete from CBHS_XMFT_COSTMODEL where unitcode=? and itemcode=? ";
List<Object[]> delsqlList=new LinkedList<>();
delsqlList.add(new String[]{ list.get(i).get("unitcode").toString(), list.get(i).get("itemcode").toString() });
delsqlList.add(new String[]{ map.get("levelcode2").toString().trim() , list.get(i).get("itemcode").toString() });
jdbcTemplate.batchUpdate(sql,delsqlList);
NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
sql="select id unitid,unitcode,unitname from UNIT_INF where 1=1 and unitcode in (:unitcodes) and ItemCode in ItemCodes";
HashMap<String, Object> paramObject = new HashMap<>();
paramObject.put("unitcodes",unitcodeslist);
paramObject.put("ItemCodes",itemcodeslist);
paramObject.put("clinicalcodes",clinicalcodeslist);
list=namedParameterJdbcTemplate.queryForList(sql,paramObject);
或者(使用注解的方式)
@Autowired
protected NamedParameterJdbcTemplate npJdbcTemplate;
sql="select id unitid,unitcode,unitname from UNIT_INF where 1=1 and unitcode in (:unitcodes) and ItemCode in ItemCodes";
HashMap<String, Object> paramObject = new HashMap<>();
paramObject.put("unitcodes",unitcodeslist);
paramObject.put("ItemCodes",itemcodeslist);
paramObject.put("clinicalcodes",clinicalcodeslist);
list=npJdbcTemplate.queryForList(sql,paramObject);
4,参考链接:
JDBCTemplate初学简介
Spring Boot数据持久化之JdbcTemplate
JdbcTemplate完全学习