java 实体类中属性增删查改的泛型写法
时间: 2023-06-10 20:09:04 浏览: 60
Java 实体类中属性增删查改的泛型写法可以使用 Java 的反射机制来实现。具体实现步骤如下:
1. 定义一个通用的泛型 DAO 接口,包含增删查改的方法:
```java
public interface BaseDao<T> {
boolean insert(T entity);
boolean delete(T entity);
boolean update(T entity);
T findById(Serializable id);
List<T> findAll();
}
```
2. 实现这个接口,并使用反射机制实现增删查改的方法:
```java
public class BaseDaoImpl<T> implements BaseDao<T> {
private Class<T> entityClass;
private String tableName;
public BaseDaoImpl(Class<T> entityClass) {
this.entityClass = entityClass;
this.tableName = entityClass.getSimpleName();
}
@Override
public boolean insert(T entity) {
// 使用反射机制获取实体类的属性列表
Field[] fields = entityClass.getDeclaredFields();
StringBuilder sb = new StringBuilder();
sb.append("INSERT INTO ").append(tableName).append("(");
// 构建 SQL 语句
for (Field field : fields) {
sb.append(field.getName()).append(",");
}
sb.deleteCharAt(sb.length() - 1);
sb.append(") VALUES (");
for (int i = 0; i < fields.length; i++) {
sb.append("?,");
}
sb.deleteCharAt(sb.length() - 1);
sb.append(")");
// 执行 SQL 语句
try (Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sb.toString())) {
for (int i = 0; i < fields.length; i++) {
fields[i].setAccessible(true);
ps.setObject(i + 1, fields[i].get(entity));
}
return ps.executeUpdate() > 0;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
public boolean delete(T entity) {
// 使用反射机制获取实体类的主键属性
Field idField = getIdField();
StringBuilder sb = new StringBuilder();
sb.append("DELETE FROM ").append(tableName).append(" WHERE ")
.append(idField.getName()).append(" = ?");
// 执行 SQL 语句
try (Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sb.toString())) {
idField.setAccessible(true);
ps.setObject(1, idField.get(entity));
return ps.executeUpdate() > 0;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
public boolean update(T entity) {
// 使用反射机制获取实体类的属性列表和主键属性
Field[] fields = entityClass.getDeclaredFields();
Field idField = getIdField();
StringBuilder sb = new StringBuilder();
sb.append("UPDATE ").append(tableName).append(" SET ");
// 构建 SQL 语句
for (Field field : fields) {
if (!field.equals(idField)) {
sb.append(field.getName()).append(" = ?,");
}
}
sb.deleteCharAt(sb.length() - 1);
sb.append(" WHERE ").append(idField.getName()).append(" = ?");
// 执行 SQL 语句
try (Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sb.toString())) {
int paramIndex = 1;
for (Field field : fields) {
if (!field.equals(idField)) {
field.setAccessible(true);
ps.setObject(paramIndex++, field.get(entity));
}
}
idField.setAccessible(true);
ps.setObject(paramIndex, idField.get(entity));
return ps.executeUpdate() > 0;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
public T findById(Serializable id) {
// 使用反射机制获取实体类的主键属性
Field idField = getIdField();
StringBuilder sb = new StringBuilder();
sb.append("SELECT * FROM ").append(tableName)
.append(" WHERE ").append(idField.getName()).append(" = ?");
// 执行 SQL 语句
try (Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sb.toString())) {
ps.setObject(1, id);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
// 创建实体类对象
T entity = entityClass.newInstance();
// 给实体类对象的属性赋值
for (Field field : entityClass.getDeclaredFields()) {
field.setAccessible(true);
field.set(entity, rs.getObject(field.getName()));
}
return entity;
} else {
return null;
}
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
public List<T> findAll() {
StringBuilder sb = new StringBuilder();
sb.append("SELECT * FROM ").append(tableName);
// 执行 SQL 语句
try (Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sb.toString())) {
try (ResultSet rs = ps.executeQuery()) {
List<T> list = new ArrayList<>();
while (rs.next()) {
// 创建实体类对象
T entity = entityClass.newInstance();
// 给实体类对象的属性赋值
for (Field field : entityClass.getDeclaredFields()) {
field.setAccessible(true);
field.set(entity, rs.getObject(field.getName()));
}
list.add(entity);
}
return list;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取实体类的主键属性
*/
private Field getIdField() {
for (Field field : entityClass.getDeclaredFields()) {
if (field.isAnnotationPresent(Id.class)) {
return field;
}
}
throw new RuntimeException("No @Id field found in " + entityClass.getName());
}
/**
* 获取数据库连接
*/
private Connection getConnection() throws SQLException {
return DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");
}
}
```
3. 在实体类中使用注解来标识主键属性:
```java
public class User {
@Id
private Long id;
private String name;
private Integer age;
// 省略 getter 和 setter 方法
}
```
这样,我们就可以通过一个通用的 DAO 接口来实现实体类属性的增删查改,而不需要针对每个实体类都实现一遍 CRUD 操作。