记得最开始学习使用数据库的时候都是使用底层的JDBC直接访问的,主要分成三个部分,
JdbcTemplate就是对JDBC的一种封装,使用起来更加的方便,但是JDBC的效率要比JdbcTemplate的效率要高一些,就像数组和List集合一样,毫无疑问,集合使用起来要比数组方便,功能更加的强大,但是数组的效率要比集合高得多。
RowMapper则主要是用来映射实体和数据库表,个人理解和ResultSet有些类似的地方,废话不多说,进入正题。
测试demo是搭建在SpringBoot上的。
首先准备一张用户表(MySQL)
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`user_id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`gender` int(3) NOT NULL,
`phone` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`note` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL,
PRIMARY KEY (`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
UserForm.java
package priv.cwr.model.vo;
import com.fasterxml.jackson.annotation.JsonProperty;
public class UserForm {
@JsonProperty("user_id")
private Long userId;
private String name;
private Integer gender;
private String phone;
private String note;
public String toString(){
return "user_id:" + this.userId
+ ",name:" + this.name
+ ",gender:" + this.gender
+ ",note:" + this.note;
}
/**
* 省略getter()、setter()
*/
}
UserRowMapper.java
package priv.cwr.rowmapper;
import org.springframework.jdbc.core.RowMapper;
import priv.cwr.model.vo.UserForm;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserRowMapper implements RowMapper {
@Override
public UserForm mapRow(ResultSet resultSet, int i) throws SQLException {
UserForm user = new UserForm();
//需要映射的字段
user.setUserId(resultSet.getLong("user_id"));
user.setName(resultSet.getString("name"));
user.setGender(resultSet.getInt("gender"));
user.setPhone(resultSet.getString("phone"));
user.setNote(resultSet.getString("note"));
return user;
}
}
测试方法
package priv.cwr;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.test.context.junit4.SpringRunner;
import priv.cwr.model.vo.UserForm;
import priv.cwr.rowmapper.UserRowMapper;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class JpaDemoApplicationTests {
@Test
public void contextLoads() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/java?characterEncoding=utf-8&useOldAliasMetadataBehavior=true");
dataSource.setUsername("root");
dataSource.setPassword("root");
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
//查询单个用户(使用已经定义好的RowMapper,如这里的UserRowMapper)
UserForm userForm1 = jdbcTemplate.queryForObject("SELECT * FROM t_user WHERE user_id = 1", new UserRowMapper());
System.out.println("userForm1 -> " + userForm1);
//使用一次性的RowMapper
UserForm userForm2 = jdbcTemplate.queryForObject("SELECT * FROM t_user WHERE user_id = 2", new RowMapper() {
@Override
public UserForm mapRow(ResultSet resultSet, int rowNum) throws SQLException {
UserForm user = new UserForm();
user.setUserId(resultSet.getLong("user_id"));
user.setName(resultSet.getString("name"));
user.setGender(resultSet.getInt("gender"));
user.setPhone(resultSet.getString("phone"));
user.setNote(resultSet.getString("note"));
return user;
}
});
System.out.println("userForm2 -> " + userForm2);
//查询用户列表
List userForms = new ArrayList<>();
jdbcTemplate.queryForList("SELECT * FROM t_user").forEach(temp -> {
//这里的temp其实是一个Map
UserForm t = new UserForm();
t.setUserId((Long) temp.get("user_id"));
t.setName((String) temp.get("name"));
t.setGender((Integer) temp.get("gender"));
t.setPhone((String) temp.get("phone"));
t.setNote((String) temp.get("note"));
userForms.add(t);
});
//输出列表
userForms.forEach(System.out::println);
}
}
输出结果如下
特别提醒
在使用RowMapper的时候一定要注意映射的字段一定要是查询出来的字段,举个例子:
SELECT user_id,name FROM t_user WHERE user_id = 1;
@Override
public UserForm mapRow(ResultSet resultSet, int rowNum) throws SQLException {
UserForm user = new UserForm();
user.setUserId(resultSet.getLong("user_id"));
user.setName(resultSet.getString("name"));
user.setGender(resultSet.getInt("gender"));
user.setPhone(resultSet.getString("phone"));
user.setNote(resultSet.getString("note"));
return user;
}
这样一条SQL,如果在RowMapper中定义成这样,那么就会出现这样的异常
这是因为你根本就没有SELECT gender、phone、note这几个字段,所以当然映射不了,所以就抛出了异常,这条SQL只查询出user_id和name两个字段,所以映射的时候也只能映射这两个字段。