反射实例之封装对数据库的增删改查操作
Posted 二木成林
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反射实例之封装对数据库的增删改查操作相关的知识,希望对你有一定的参考价值。
需求
使用反射来封装对mysql数据库的增删改查操作,封装更通用的方法。
代码实现
第一步,创建数据库连接。
设置数据库连接参数,获取Connection。注意,改成自己数据库的连接参数。
/**
* 获取数据库连接的工具类,注意在该类设置数据库连接参数
*/
class JDBCUtil {
/**
* 获取数据库连接
*
* @return 数据库连接对象
*/
public static Connection getConnection() {
Connection connection = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost/test";
String user = "root";
String password = "root";
connection = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return connection;
}
}
第二步,创建BaseMapper接口。
该接口中定义了众多增删改查的默认方法。
public interface BaseMapper<T> {
// --------------------------------------插入操作------------------------------------------
/**
* 向数据库内插入一条记录。
* 插入SQL语句如例:insert into user(id,username,password,phone,email,memo,insert_time) values(20,'刘三刀','123456','1008611','1008611@163.com','我是一名用户','2021-08-10 21:28:35')
*
* @param t 带插入的实体类对象
* @return 返回受影响行数
* @throws IllegalAccessException
* @throws SQLException
*/
default int insert(T t) throws IllegalAccessException, SQLException {
// 使用泛型参数,是因为不清楚会传什么实体类,所以使用泛型
// 获取输入参数t的Class类对象
Class<?> tClass = t.getClass();
// 使用StringBuilder来存放SQL语句
StringBuilder sb = new StringBuilder();
// 插入SQL语句的头部"insert into "
sb.append("insert into ");
// 获取类名,但需要将类名转换成小写,虽然在MySQL中不区分大小写
sb.append(tClass.getSimpleName().toLowerCase());
sb.append("(");
// 获取属性数组,即获取t所表示的实体类中的所有属性,而不是该类中的所有方法
Field[] fields = tClass.getDeclaredFields();
int i = 0;
for (Field field : fields) {
sb.append(field.getName());// 添加属性名
sb.append(",");
i++;
}
// 除去最后一个逗号,添加一个右括号
String s = sb.substring(0, sb.length() - 1) + ")";
StringBuilder result = new StringBuilder(s);
result.append(" values(");
for (int j = 0; j < i; j++) {
result.append("?,");
}
// 到这一步,一个完整的SQL语句完成了,只是没有传入参数
// 例如:insert into user(phone,username,insert_time,email,memo,id,password) values(?,?,?,?,?,?,?)
String sql = result.substring(0, result.length() - 1) + ")";
// 接下来就是进行插入操作
// 获取数据库连接
Connection connection = JDBCUtil.getConnection();
// 根据Connection创建PreparedStatement对象
PreparedStatement ps = connection.prepareStatement(sql);
// 该参数表示是第几个待传入的参数,在PreparedStatement类中设置参数对应值的方法的序号是从1开始的
int j = 1;
for (Field field : fields) {
field.setAccessible(true);
ps.setObject(j, field.get(t));
j++;
}
// 可以打印完整的SQL语句
System.out.println(ps);
// 执行SQL插入操作
return ps.executeUpdate();
}
// --------------------------------------更新操作------------------------------------------
/**
* 通过id字段更新记录
* SQL语句如:update user set username='王五' where id=6;
*
* @param t 待更新的信息,都是封装在实体类中的,包括id信息
* @return 返回受影响行数
*/
default int updateById(T t) throws SQLException, IllegalAccessException {
// 1.获取字段
// 获取t所表示类的Class对象
Class<?> tClass = t.getClass();
// 获取该类的所有属性
Field[] fields = tClass.getDeclaredFields();
// 过滤掉空值的字段
// 将Field数组转换成Field流
Stream<Field> stream = Arrays.stream(fields);
// 过滤掉空属性,因为待更新的字段必须是有值的属性
Stream<Field> fieldStream = stream.filter((field) -> {
field.setAccessible(true);
try {
// 只保留不为空的字段
return field.get(t) != null;
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return false;
});
// 2.组装SQL语句
StringBuilder sb = new StringBuilder();
sb.append("update ");
sb.append(tClass.getSimpleName().toLowerCase());// 表名
sb.append(" set ");
// 循环遍历要更新的字段
List<Field> fieldList = new ArrayList<>();
fieldStream.forEach((field -> {
// 将字段添加到List集合中
fieldList.add(field);
if (!"id".equals(field.getName())) {
sb.append(field.getName().toLowerCase());
sb.append("=");
sb.append("?");
sb.append(",");
}
}));
// 去除最后一个逗号","
String where = sb.substring(0, sb.length() - 1);
// 设置where后面的条件子句,即"where id=?;"
StringBuilder sql = new StringBuilder(where);
sql.append(" where ");
sql.append("id=?;");
String updateSql = sql.toString();
// 3.执行SQL语句返回结果
Connection connection = JDBCUtil.getConnection();
PreparedStatement ps = connection.prepareStatement(updateSql);
// 调用PreparedStatement类的setObject()方法的参数序号,从1开始
int parameterIndex = 1;
// id字段对应的值
Object id = -1;
for (Field field : fieldList) {
if (!"id".equals(field.getName())) {
field.setAccessible(true);
ps.setObject(parameterIndex, field.get(t));
parameterIndex++;
} else {
// 将id字段的值保存到局部变量中
id = field.get(t);
}
}
// 设置id字段的值,即最后一个问号的值
ps.setObject(parameterIndex, id);
System.out.println(ps);
// 执行更新操作,返回受影响行数
return ps.executeUpdate();
}
/**
* 通过条件查询更新记录。
* SQL语句如:update user set username='李四',password='abcd' where id=23 and username='王五' and email='10086@qq.com';
*
* @param t 待更新的信息
* @param conditions where子句后面的条件
* @return 返回受影响的行数
* @throws SQLException
* @throws IllegalAccessException
*/
default int update(T t, Map<String, Object> conditions) throws SQLException, IllegalAccessException {
// 1.获取字段
// 获取t所表示类的Class对象
Class<?> tClass = t.getClass();
// 获取该类的所有属性
Field[] fields = tClass.getDeclaredFields();
// 过滤掉空值的字段
// 将Field数组转换成Field流
Stream<Field> stream = Arrays.stream(fields);
// 过滤掉空属性,因为待更新的字段必须是有值的属性
Stream<Field> fieldStream = stream.filter((field) -> {
field.setAccessible(true);
try {
// 只保留不为空的字段
// 注意:如果是基本数据类型如int,那么会有一个默认值,会通过!=null判断,导致出现问题
// 所以在实体类中尽量使用引用数据类型,而不是基本数据类型
return field.get(t) != null;
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return false;
});
// 2.组装SQL语句
StringBuilder sb = new StringBuilder();
sb.append("update ");
sb.append(tClass.getSimpleName().toLowerCase());// 表名
sb.append(" set ");
// 循环遍历要更新的字段
List<Field> fieldList = new ArrayList<>();
fieldStream.forEach((field -> {
// 将字段添加到List集合中
fieldList.add(field);
sb.append(field.getName().toLowerCase());
sb.append("=");
sb.append("?");
sb.append(",");
}));
// 去除最后一个逗号","
String where = sb.substring(0, sb.length() - 1);
// 设置where后面的条件子句,即"where username='xxx' and password='xxx';"
StringBuilder sql = new StringBuilder(where);
sql.append(" where ");
for (String key : conditions.keySet()) {
sql.append(key);
sql.append("=?");
sql.append(" and ");
}
String updateSql = sql.substring(0, sql.lastIndexOf("and"));
// 3.执行SQL语句返回结果
Connection connection = JDBCUtil.getConnection();
PreparedStatement ps = connection.prepareStatement(updateSql);
// 调用PreparedStatement类的setObject()方法的参数序号,从1开始
int parameterIndex = 1;
// 设置set子句后面的参数
for (Field field : fieldList) {
field.setAccessible(true);
ps.setObject(parameterIndex, field.get(t));
parameterIndex++;
}
// 设置where子句后面的参数
for (String key : conditions.keySet()) {
ps.setObject(parameterIndex, conditions.get(key));
parameterIndex++;
}
System.out.println(ps);
// 执行更新操作,返回受影响行数
return ps.executeUpdate();
}
// --------------------------------------删除操作------------------------------------------
/**
* 通过id字段删除某条记录。
* SQL语句如:delete from user where id=2;
*
* @param clazz 实体类,如User.class
* @param id 待删除的id字段值
* @return 返回受影响行数
* @throws SQLException
*/
default int deleteById(Class<?> clazz, Serializable id) throws SQLException {
// 1.拼接SQL语句
StringBuilder sql = new StringBuilder();
sql.append("delete from ");
sql.append(clazz.getSimpleName().toLowerCase());
sql.append(" where ");
sql.append("id=?;");
String deleteSql = sql.toString();
// 2.执行SQL语句
Connection connection = JDBCUtil.getConnection();
PreparedStatement ps = connection.prepareStatement(deleteSql);
ps.setObject(1, id);
return ps.executeUpdate();
}
/**
* 多条件删除。
* SQL语句如:delete from user where username='zhangsan' and password='123456';
*
* @param clazz 实体类,如User.class
* @param conditions where子句后面跟着的条件
* @return 返回受影响行数
* @throws SQLException
*/
default int deleteByMap(Class<?> clazz, Map<String, Object> conditions) throws SQLException {
// 1.拼接SQL语句
StringBuilder sql = new StringBuilder();
sql.append("delete from ");
sql.append(clazz.getSimpleName().toLowerCase());
sql.append(" where ");
// 从conditions集合中读取条件参数
for (String key : conditions.keySet()) {
sql.append(key);
sql.append("=");
sql.append("?");
sql.append(" and ");
}
String deleteSql = sql.substring(0, sql.lastIndexOf("and"));
// 2.执行SQL语句
Connection connection = JDBCUtil.getConnection();
PreparedStatement ps = connection.prepareStatement(deleteSql);
int parameterIndex = 1;
for (String key : conditions.keySet()) {
ps.setObject(parameterIndex, conditions.get(key));
parameterIndex++;
}
return ps.executeUpdate();
}
/**
* 根据实体类中的字段进行条件删除。
* SQL语句如:delete from user where username='zhangsan' and password='123456';
*
* @param t 实体类对象
* @return 返回受影响行数
* @throws SQLException
* @throws IllegalAccessException
*/
default int delete(T t) throws SQLException, IllegalAccessException {
// 1.获取条件字段,过滤掉空字段
Field[] fields = t.getClass().getDeclaredFields();
// 使用Stream流进行初步过滤
Stream<Field> stream = Arrays.stream(fields);
Stream<Field> fieldStream = stream.filter((field -> {
field.setAccessible(true);
try {
// 只保留设置了值的字段
return field.get(t) != null;
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return false;
}));
// 2.组装SQL语句
StringBuilder sql = new StringBuilder();
sql.append("delete from ");
sql.append(t.getClass().getSimpleName().toLowerCase());
sql.append(" where ");
List<Field> fieldList = new ArrayList<>();
fieldStream.forEach((field -> {
fieldList.add(field);
field.setAccessible(true);
sql.append(field.getName().toLowerCase());
sql.append("=");
sql.append("?");
sql.append(" and ");
}));
String deleteSql = sql.substring(0, sql.lastIndexOf("and"));
// 3.执行SQL语句,返回删除结果
Connection connection = JDBCUtil.getConnection();
PreparedStatement ps = connection.prepareStatement(deleteSql);
int parameterIndex = 1;
for (Field field : fieldList) {
ps.setObject(parameterIndex, field.get(t));
parameterIndex++;
}
return ps.executeUpdate();
}
// --------------------------------------查询操作------------------------------------------
/**
* 通过id查询某条记录。
* SQL语句如:select * from user where id=2;
*
* @param clazz 实体类,如User.class
* @param id 主键id
* @return 返回查询结果
* @throws SQLException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
default T selectById(Class<?> clazz, Serializable id) throws SQLException, InstantiationException, IllegalAccessException, InvocationTargetException {
// 1.组装SQL语句
StringBuilder sql = new StringBuilder();
sql.append("select * from ");
sql.append(clazz.getSimpleName().toLowerCase());
sql.append(" where id=?");
String selectSql = sql.toString();
// 2.执行SQL语句获取查询结果集
Connection connection = JDBCUtil.getConnection();
PreparedStatement ps = connection.prepareStatement(selectSql);
ps.setObject(1, id);
ResultSet rs = ps.executeQuery();
// 3.封装查询结果集到实体类对象中并返回
// 利用反射创建实例对象
Object t = clazz.newInstance();
Method[] methods = t.getClass().getDeclaredMethods();
if (rs.next()) {
// 循环遍历方法数组,将数据封装到实体类对象中
for (Method method : methods) {
// 过滤setXXX方法,设置属性的值
if (method.getName().startsWith("set")) {
// 设置属性的值,通过rs.getObject(String columnLabel)方法获取指定列的值
method.invoke(t, rs.getObject(method.getName().substring(3)));
}
}
}
// 如果还有下一条记录,表示查询结果有多个,那么不应该
if (rs.next()) {
throw new IllegalArgumentException("查询结果有多个,请输入合法参数:" + id);
}
return (T) t;
}
/**
* 通过批量id查询多条记录。
* SQL语句如:select * from user where id in (1,2,3,4,5);
*
* @param clazz 实体类,如User.class
* @param idList 主键id列表
* @return 返回查询结果集
* @throws SQLException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
default List<T> selectBatchIds(Class<?> clazz, List<? extends Serializable> idList) throws SQLException, InstantiationException, IllegalAccessException, InvocationTargetException {
// 1.组装SQL语句
StringBuilder sql = new StringBuilder();
sql.append("select * from ");
sql.append(clazz.getSimpleName().toLowerCase());
sql.append(" where id in(");
for (int i = 0; i < idList.size(); i++) {
sql.append("?");
if (i != idList.size() - 1) {
sql.append(",");
}
}
sql.append(")");
String selectSql = sql.toString();
// 2.执行SQL语句获取查询结果集
Connection connection = JDBCUtil.getConnection();
PreparedStatement ps = connection.prepareStatement(selectSql);
int parameterIndex = 1;
for (Serializable id : idList) {
ps.setObject(parameterIndex, id);
parameterIndex++;
}
ResultSet rs = ps.executeQuery();
// 3.封装查询结果集到实体类对象中并返回
List<T> tList = new ArrayList<>();
while (rs.next()) {
// 利用反射创建实例对象
Object t = clazz.newInstance();
// 获取该类的所有声明的方法
Method[] methods = t.getClass().getDeclaredMethods();
// 循环遍历方法数组,将数据封装到实体类对象中
for (Method method : methods) {
// 过滤setXXX方法,设置属性的值
if (method.getName().startsWith("set")) {
// 设置属性的值,通过rs.getObject(String columnLabel)方法获取指定列的值
method.invoke(t, rs.getObject(method.getName().substring(3)));
}
}
tList.add((T) t);
}
return tList;
}
/**
* 多条件查询唯一一条记录。
* SQL语句如:select * from user where username='zhangsan' and password='123456';
*
* @param clazz 实体类,如User.class
* @param conditions where子句后面的条件集合
* @return 返回查询结果
* @throws SQLException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
default T selectOne(Class<?> clazz, Map<String, Object> conditions) throws SQLException, InstantiationException, IllegalAccessException, InvocationTargetException {
// 1.组装SQL语句
StringBuilder sql = new StringBuilder();
sql.append("select * from ");
sql.append(clazz.getSimpleName().toLowerCase());
// where子句后面的条件
sql.append(" where ");
for (String key : conditions.keySet()) {
sql.append(key);
sql.append("=");
sql.append("?");
sql.append(" and ");
}
String selectSql = sql.substring(0, sql.lastIndexOf("and"));
// 2.执行SQL语句获取查询结果集
Connection connection = JDBCUtil.getConnection();
PreparedStatement ps = connection.prepareStatement(selectSql);
int parameterIndex = 1;
for (String key : conditions.keySet()) {
ps.setObject(parameterIndex, conditions.get(key));
parameterIndex++;
}
ResultSet rs = ps.executeQuery();
// 3.封装查询结果集到实体类对象中并返回
// 利用反射创建实例对象
Object t = clazz.newInstance();
Method[] methods = t.getClass().getDeclaredMethods();
if (rs.next()) {
// 循环遍历方法数组,将数据封装到实体类对象中
for (Method method : methods) {
// 过滤setXXX方法,设置属性的值
if (method.getName().startsWith("set")) {
// 设置属性的值,通过rs.getObject(String columnLabel)方法获取指定列的值
method.invoke(t, rs.getObject(method.getName().substring(3)));
}
}
}
// 如果还有下一条记录,表示查询结果有多个,那么不应该
if (rs.next()) {
throw new IllegalArgumentException("查询结果有多个,请输入合法参数。");
}
return (T) t;
}
/**
* 指定条件下的记录总条数。
* SQL语句如:select count(*) from user where password='123456';
*
* @param clazz 实体类,如User.class
* @param conditions where子句后面的条件集合
* @return 返回记录总条数
* @throws SQLException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
default Integer selectCount(Class<?> clazz, Map<String, Object> conditions) throws SQLException, InstantiationException, IllegalAccessException, InvocationTargetException {
// 1.组装SQL语句
StringBuilder sql = new StringBuilder();
sql.append("select count(*) from ");
sql.append(clazz.getSimpleName().toLowerCase());
// where子句后面的条件
sql.append(" where ");
for (String key : conditions.keySet()) {
sql.append(key);
sql.append("=");
sql.append("?");
sql.append(" and ");
}
String selectSql = sql.substring(0, sql.lastIndexOf("and"));
// 2.执行SQL语句获取查询结果集
Connection connection = JDBCUtil.getConnection();
PreparedStatement ps = connection.prepareStatement(selectSql);
int parameterIndex = 1;
for (String key : conditions.keySet()) {
ps.setObject(parameterIndex, conditions.get(key));
parameterIndex++;
}
ResultSet rs = ps.executeQuery();
// 3.封装查询结果集到实体类对象中并返回
// 记录的总条数
int count = 0;
if (rs.next()) {
count = rs.getInt(1);
}
return count;
}
/**
* 多条件下查询多条记录。
* SQL语句如下:select * from user where username='zhangsan' and password='123456';
*
* @param clazz 实体类,如User.class
* @param conditions where子句后面的条件集合
* @return 返回查询结果集
* @throws SQLException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
default List<T> selectList(Class<?> clazz, Map<String, Object> conditions) throws SQLException, InstantiationException, IllegalAccessException, InvocationTargetException {
// 1.组装SQL语句
StringBuilder sql = new StringBuilder();
sql.append("select * from ");
sql.append(clazz.getSimpleName().toLowerCase());
// where子句后面的条件
sql.append(" where ");
for (String key : conditions.keySet()) {
sql.append(key);
sql.append("=");
sql.append("?");
sql.append(" and ");
}
String selectSql = sql.substring(0, sql.lastIndexOf("and"));
// 2.执行SQL语句获取查询结果集
Connection connection = JDBCUtil.getConnection();
PreparedStatement ps = connection.prepareStatement(selectSql);
int parameterIndex = 1;
for (String key : conditions.keySet()) {
ps.setObject(parameterIndex, conditions.get(key));
parameterIndex++;
}
ResultSet rs = ps.executeQuery();
// 3.封装查询结果集到实体类对象中并返回
List<T> tList = new ArrayList<>();
while (rs.next()) {
// 利用反射创建实例对象
Object t = clazz.newInstance();
Method[] methods = t.getClass().getDeclaredMethods();
// 循环遍历方法数组,将数据封装到实体类对象中
for (Method method : methods) {
// 过滤setXXX方法,设置属性的值
if (method.getName().startsWith("set")) {
// 设置属性的值,通过rs.getObject(String columnLabel)方法获取指定列的值
method.invoke(t, rs.getObject(method.getName().substring(3)));
}
}
tList.add((T) t);
}
return tList;
}
/**
* 多条件下分页查询多条记录。
* SQL语句如下:select * from user where username='zhangsan' limit 0,5;
*
* @param clazz 实体类,如User.class
* @param limit 分页查询中的起始索引,从0开始
* @param size 该页条数
* @param conditions where子句后面的条件集合
* @return 返回查询结果集
* @throws SQLException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
default List<T> selectPage(Class<?> clazz, int limit, int size, Map<String, Object> conditions) throws SQLException, InstantiationException, IllegalAccessException, InvocationTargetException {
// 1.组装SQL语句
StringBuilder sql = new StringBuilder();
sql.append("select * from ");
sql.append(clazz.getSimpleName().toLowerCase());
// where子句后面的条件,注意处理空条件的问题
sql.append(" where ");
for (String key : conditions.keySet()) {
sql.append(key);
sql.append("=");
sql.append("?");
sql.append(" and ");
}
String selectSql = sql.substring(0, sql.lastIndexOf("and"));
selectSql = selectSql + " limit " + limit + "," + size;
// 2.执行SQL语句获取查询结果集
Connection connection = JDBCUtil.getConnection();
PreparedStatement ps = connection.prepareStatement(selectSql);
int parameterIndex = 1;
for (String key : conditions.keySet()) {
ps.setObject(parameterIndex, conditions.get(key));
parameterIndex++;
}
ResultSet rs = ps.executeQuery();
// 3.封装查询结果集到实体类对象中并返回
List<T> tList = new ArrayList<>();
while (rs.next()) {
// 利用反射创建实例对象
Object t = clazz.newInstance();
Method[] methods = t.getClass().getDeclaredMethods();
// 循环遍历方法数组,将数据封装到实体类对象中
for (Method method : methods) {
// 过滤setXXX方法,设置属性的值
if (method.getName().startsWith("set")) {
// 设置属性的值,通过rs.getObject(String columnLabel)方法获取指定列的值
method.invoke(t, rs.getObject(method.getName().substring(3)));
}
}
tList.add((T) t);
}
return tList;
}
/**
* 查询该表的所有记录。
* SQL语句如下:select * from user;
*
* @param tClass 实体类,如User.class
* @return 返回查询结果集
* @throws SQLException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
default List<T> selectAll(Class<T> tClass) throws SQLException, InstantiationException, IllegalAccessException, InvocationTargetException {
// 设置查询所有记录的SQL语句
String sql = "select * from " + tClass.getSimpleName().toLowerCase();
// 创建存放结果的集合
List<T> lists = new ArrayList<>();
// 获取数据库连接并创建PreparedStatement对象,执行查询操作获取结果集
Connection connection = JDBCUtil.getConnection();
PreparedStatement ps = connection.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
// 根据实体类创建实例对象
T t = tClass.newInstance();
// 获取t所表示的实体类的所有方法,其实主要是获取setXXX方法,设置属性的值
Method[] methods = t.getClass().getDeclaredMethods();
// 循环遍历方法数组
for (Method method : methods) {
// 过滤setXXX方法,设置属性的值
if (method.getName().startsWith("set")) {
// 设置属性的值,通过rs.getObject(String columnLabel)方法获取指定列的值
method.invoke(t, rs.getObject(method.getName().substring(3)));
}
}
// 将设置成功的实例对象添加到集合中
lists.add(t);
}
return lists;
}
}
第三步,创建对应实体类。
创建对应的实体类,该类中的属性名和对应表中的字段名一一对应,注意属性名和字段名必须完全对应,不能将下划线转换成驼峰命名。
class User {
private Long id;
private String username;
private String password;
private String phone;
private String email;
private String memo;
private java.util.Date insert_time;
public User() {
}
public User(String username, String password, String phone, String email, String memo, java.util.Date insert_time) {
this.username = username;
this.password = password;
this.phone = phone;
this.email = email;
this.memo = memo;
this.insert_time = insert_time;
}
public User(Long id, String username, String password, String phone, String email, String memo, java.util.Date insert_time) {
this.id = id;
this.username = username;
this.password = password;
this.phone = phone;
this.email = email;
this.memo = memo;
this.insert_time = insert_time;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMemo() {
return memo;
}
public void setMemo(String memo) {
this.memo = memo;
}
public java.util.Date getInsert_time() {
return insert_time;
}
public void setInsert_time(Date insert_time) {
this.insert_time = insert_time;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\\'' +
", password='" + password + '\\'' +
", phone='" + phone + '\\'' +
", email='" + email + '\\'' +
", memo='" + memo + '\\'' +
", insert_time=" + insert_time +
'}';
}
}
第四步,创建UserMapper类实现BaseMapper<User>接口。
由于定义了默认方法,所以只需要实现BaseMapper接口,不需要自定义任何方法。
class UserMapper implements BaseMapper<User> {
}
第五步,测试方法。
class Test {
public static void main(String[] args) throws SQLException, IllegalAccessException, InvocationTargetException, InstantiationException {
UserMapper userMapper = new UserMapper();
Map<String, Object> map = new HashMap<>();
map.put("username", "张三");
map.put("password", "123456");
System.out.println(userMapper.selectPage(User.class, 2, 4, map));
}
}
存在的问题
上面封装的BaseMapper<T>接口实际上是存在很多问题的,很难在实际中使用。下面列举些常见的问题:
- 1.属性名和字段名必须一模一样。
- 2.主键id字段的插入字段存在问题。
- 3.conditions条件必须匹配,即至少存在一个条件。
- 4.只能处理相等的条件,不能处理更复杂的条件查询如大于条件等。
- 5.实体类中的属性名必须是使用引用数据类型,否则可能会引发异常。
参考链接:
以上是关于反射实例之封装对数据库的增删改查操作的主要内容,如果未能解决你的问题,请参考以下文章