复习一下两个类的操作,说实话我还真是第一次见StopWatch这个类的。
简单的秒表,允许为多个任务计时,公开总运行时间和每个命名任务的运行时间。隐藏的使用System.nanoTime(),提高应用程序代码的可读性并减少计算错误的可能性。请注意,此对象并非设计为线程安全的,并且不使用同步。
此类通常用于在概念验证工作和开发过程中验证性能,而不是作为生产应用程序的一部分。
从Spring Framework 5.2开始,以纳秒为单位跟踪和报告运行时间。
void start()启动一个未命名的任务。
void start(String taskName)启动一个命名任务。
void stop()停止当前任务。
org.springframework.jdbc.core.JdbcTemplate类是JDBC核心包中的中心类。它简化了JDBC的使用,并有助于避免常见的错误。 它执行核心JDBC工作流,留下应用程序代码来提供SQL并提取结果。 该类执行SQL查询或更新,在ResultSet类上启动迭代并捕获JDBC异常,并将它们转换为org.springframework.dao包中定义的通用更详细的异常层次结构。使用这个类的代码只需要实现回调接口,给它们一个明确定义的协定。 Preparedstatementcreator 回调接口在给定 Connection 的情况下创建一个准备好的语句,提供 SQL 和任何必要的参数。 Resultsetextractor 接口从 ResultSet 中提取值。 请参阅 PreparedStatementSetter 和 RowMapper 了解两个流行的可选回调接口。
T execute(CallableStatementCreator csc, CallableStatementCallback action)Execute a JDBC data access operation, implemented as callback action working on a JDBC CallableStatement. 执行 JDBC 数据访问操作,实现为在 JDBC CallableStatement 上工作的回调动作
T execute(ConnectionCallback action)Execute a JDBC data access operation, implemented as callback action working on a JDBC Connection. 执行 JDBC 数据访问操作,实现为在 JDBC 连接上工作的回调动作
T execute(PreparedStatementCreator psc, PreparedStatementCallback action)Execute a JDBC data access operation, implemented as callback action working on a JDBC PreparedStatement. 执行 JDBC 数据访问操作,实现为在 JDBC PreparedStatement 上工作的回调动作
T execute(StatementCallback action)Execute a JDBC data access operation, implemented as callback action working on a JDBC Statement. 执行 JDBC 数据访问操作,实现为对 JDBC 语句的回调动作
void execute(String sql)Issue a single SQL execute, typically a DDL statement. 发出一个 SQL 执行,通常是一个 DDL 语句
T execute(String callString, CallableStatementCallback action)Execute a JDBC data access operation, implemented as callback action working on a JDBC CallableStatement. 执行 JDBC 数据访问操作,实现为在 JDBC CallableStatement 上工作的回调动作
T execute(String sql, PreparedStatementCallback action)Execute a JDBC data access operation, implemented as callback action working on a JDBC PreparedStatement. 执行 JDBC 数据访问操作,实现为在 JDBC PreparedStatement 上工作的回调动作
插入
String insertQuery = "insert into student (name, age) values (?, ?)";
jdbcTemplate.update( insertQuery, name, age)
查询
public List listStudents() {
String SQL = "select * from Student";
List students = jdbcTemplateObject.query(SQL, new StudentMapper());
return students;
}
public class StudentMapper implements RowMapper {
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student = new Student();
student.setId(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
return student;
}
}
带参数查询
public Student getStudent(Integer id) {
String SQL = "select * from Student where id = ?";
Student student = jdbcTemplateObject.queryForObject(SQL, new Object[] { id }, new StudentMapper());
return student;
}
public class StudentMapper implements RowMapper {
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student = new Student();
student.setId(rs.getInt("id")); // 列名
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
return student;
}
}
通过查看源码,无论是queryfor*还是query本身都是走的底层query方法
public T query(final String sql, final ResultSetExtractor rse) throws DataAccessException {
Assert.notNull(sql, "SQL must not be null");
Assert.notNull(rse, "ResultSetExtractor must not be null");
if (this.logger.isDebugEnabled()) {
this.logger.debug("Executing SQL query [" + sql + "]");
}
class QueryStatementCallback implements StatementCallback, SqlProvider {
QueryStatementCallback() {
}
public T doInStatement(Statement stmt) throws SQLException {
ResultSet rs = null;
Object var4;
try {
rs = stmt.executeQuery(sql);
ResultSet rsToUse = rs;
if (JdbcTemplate.this.nativeJdbcExtractor != null) {
rsToUse = JdbcTemplate.this.nativeJdbcExtractor.getNativeResultSet(rs);
}
var4 = rse.extractData(rsToUse);
} finally {
JdbcUtils.closeResultSet(rs);
}
return var4;
}
public String getSql() {
return sql;
}
}
return this.execute((StatementCallback)(new QueryStatementCallback()));
}
public T query(PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor rse) throws DataAccessException {
Assert.notNull(rse, "ResultSetExtractor must not be null");
this.logger.debug("Executing prepared SQL query");
return this.execute(psc, new PreparedStatementCallback() {
public T doInPreparedStatement(PreparedStatement ps) throws SQLException {
ResultSet rs = null;
Object var4;
try {
if (pss != null) {
pss.setValues(ps);
}
rs = ps.executeQuery();
ResultSet rsToUse = rs;
if (JdbcTemplate.this.nativeJdbcExtractor != null) {
rsToUse = JdbcTemplate.this.nativeJdbcExtractor.getNativeResultSet(rs);
}
var4 = rse.extractData(rsToUse);
} finally {
JdbcUtils.closeResultSet(rs);
if (pss instanceof ParameterDisposer) {
((ParameterDisposer)pss).cleanupParameters();
}
}
return var4;
}
});
}
更新
String updateQuery = "update Student set age = ? where id = ?";
jdbcTemplateObject.update(updateQuery, age, id);
批量更新
String SQL = "update Student set age = ? where id = ?";
int[] updateCounts = jdbcTemplateObject.batchUpdate(SQL,
new BatchPreparedStatementSetter() {
public void setValues(PreparedStatement ps, int i) throws SQLException {
ps.setInt(1, students.get(i).getAge());
ps.setInt(2, students.get(i).getId());
}
public int getBatchSize() {
return students.size();
}
});
删除
String deleteQuery = "delete from Student where id = ?";
jdbcTemplateObject.update(deleteQuery, id);
JdbcTemplate类使用org.springframework.jdbc.core.RowMapper 接口在每行的基础上映射ResultSet的行。该接口的实现执行将每行映射到结果对象的实际工作。如果抛出SQLExceptions将被调用的JdbcTemplate捕获和处理。
接口的声明以下是org.springframework.jdbc.core.RowMapper接口的声明 -
public interface RowMapper
用法
步骤1 - 使用配置的数据源创建一个JdbcTemplate对象。
步骤2 - 创建一个实现RowMapper接口的StudentMapper对象。
步骤3 - 使用JdbcTemplate对象方法在使用StudentMapper对象时进行数据库操作
public void insertMediaAll(MediaEntity media){
jdbcTemplate.update(MediaMapper.insertMediaAll, media.getId(), media.getRelativePath(), media.getCreateAtUtc(),media.getSnapshotPath()
,media.getMimeType(),media.getWidth(),media.getHeight(),media.getSize(),media.getFileType(),media.getFileName(),media.getAnnexType(),media.getVoiceTime());
}
//MediaMapper下的
public static final String insertMediaAll = “insert into medias_media(Id,RelativePath,CreateAtUtc,SnapshotPath,MimeType,Width,Height,Size,FileType,FileName,AnnexType,VoiceTime) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)”;
// 结果集映射 查询的时候 query
@Override
public List getMediaResourceByPlayIds(String playIds) {
String sql = MediaMapper.SQL_SELECT_MEDIA_RESOURE_PLAYIDS.replace("@ids", playIds);
return jdbcTemplate.query(sql, MediaMapper.MAPPER_MEDIAS_RESOURCE);
}
//region mapper 映射的列
public static final RowMapper MAPPER_MEDIAS_RESOURCE = new RowMapper() {
@Override
public MediaResourceEntity mapRow(ResultSet resultSet, int i) throws SQLException {
MediaResourceEntity mediaResource = new MediaResourceEntity();
mediaResource.setId(DBUtil.getString(resultSet, ID));
mediaResource.setPlaylistId(DBUtil.getString(resultSet, PLAYLISTID));
mediaResource.setCategory(DBUtil.getString(resultSet, CATEGORY));
mediaResource.setLevel(DBUtil.getString(resultSet, LEVEL));
mediaResource.setSource(DBUtil.getString(resultSet, SOURCE));
mediaResource.setCreateAtUtc(DBUtil.getDate(resultSet, CREATE_AT_UTC));
mediaResource.setDeleted(DBUtil.getBoolean(resultSet, IS_DELETED));
mediaResource.setSortIndex(DBUtil.getInt(resultSet, SORTINDEX));
mediaResource.setImg(DBUtil.getString(resultSet, IMG));
mediaResource.setNeedPaid(DBUtil.getBoolean(resultSet, NEEDPAID));
mediaResource.setPlayListName(DBUtil.getString(resultSet, PLAYLISTNAME));
return mediaResource;
}
};
// queryforobject
private static final String getSubTopicByNameSql = “select top 1 * from medias_subtopic where Name = ? and ParentId = ?”;
@Override
public TopicEntity getSubTopicByNameAndParent(String name, String parentId) {
try {
return jdbcTemplate.queryForObject(getSubTopicByNameSql, new String[]{name, parentId}, new RowMapper() {
@Override
public TopicEntity mapRow(ResultSet rs, int rowNum) throws SQLException {
TopicEntity topic = new TopicEntity();
topic.setId(DBUtil.getString(rs, “Id”));
topic.setName(DBUtil.getString(rs, “Name”));
topic.setParentId(DBUtil.getString(rs, “ParentId”));
return topic;
}
});
} catch (EmptyResultDataAccessException e) {
return null;
}
}
此接口为 JdbcTemplate 类提供的 PreparedStatement 设置值,该值用于使用相同 SQL 的批处理中的每个更新。 实现负责设置任何必要的参数。 已经提供了带占位符的 SQL。使用这个接口比使用 PreparedStatementCreator 更容易: JdbcTemplate 将创建 PreparedStatement,回调只负责设置参数值。实现不需要关注它们尝试的操作可能抛出的 SQLExceptions。 Jdbctemplate 类将适当地捕获和处理 SQLExceptions。
void setValues(PreparedStatement ps)Set parameter values on the given PreparedStatement. 在给定的 PreparedStatement 上设置参数值