利用反射如何动态生成sql
一.自定义注解 @UpdateWhere
@Target({ElementType.FIELD}) //作用于类
@Retention(RetentionPolicy.RUNTIME) //运行时有效
@Documented //可以出现在文档里
@Inherited
public @interface UpdateWhere {}
二.创建实体类接受
public class NameValuePair<Name, Value> implements Serializable {private static final long serialVersionUID = 1276809011610487148L;private Name name;private Value value;public NameValuePair() {super();}public NameValuePair(Name name, Value value) {super();this.name = name;this.value = value;}public Name getName() {return name;}public void setName(Name name) {this.name = name;}public Value getValue() {return value;}public void setValue(Value value) {this.value = value;}public NameValuePair<Name, Value> returnThis() {return this;}}
三.动态sql生成
throws ServiceException {try {Class<?> updateClazz = updateObject.getClass();// Table 是类上面是否有这个注解if (!Verify.isEmpty(id) || updateClazz == null || !updateClazz.isAnnotationPresent(Table.class)) {throw new ServiceException("参数异常!");}ArrayList<NameValuePair<String, Object>> whereList = new ArrayList<>(); // 条件listArrayList<Object> sqlParams = new ArrayList<>(); // 参数listStringBuilder sqlBuffer = new StringBuilder("update " + updateClazz.getSimpleName() + " set ");// 开始解析// getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段for (Field declaredField : updateClazz.getDeclaredFields()) {if (declaredField.isAnnotationPresent(Id.class)) {continue; // ID不参与更新}if (!declaredField.isAnnotationPresent(Column.class)) {continue;}declaredField.setAccessible(Boolean.TRUE);String declaredFieldName = declaredField.getName();Object declaredFieldValue = declaredField.get(updateObject);if (declaredFieldValue == null || declaredFieldValue.toString().trim().length() < 1) {continue;}if (declaredField.isAnnotationPresent(UpdateWhere.class)) {// whereList.add(new NameValuePair<>(declaredFieldName, declaredFieldValue));continue; // 更新的条件不参与更新}sqlBuffer.append(declaredFieldName).append("=?,");sqlParams.add(declaredFieldValue);declaredField.setAccessible(Boolean.FALSE);}if (!sqlBuffer.toString().endsWith(",")) {// LOGGER.info("未检测到更新参数, 已生成的SQL: " + sqlBuffer + " ; 参数: " + updateObject);}/** sqlBuffer.deleteCharAt(sqlBuffer.length() -* 1).append(" where 1=1, ");*/// if (whereList.size() < 1) {
// throw new ServiceException("未检测到更新条件1, 已生成的SQL: " + sqlBuffer + ", 参数: " + updateObject);
// }/** for (NameValuePair<String, Object> nameValuePair : whereList) {* sqlBuffer.append(nameValuePair.getName()).append("=?,");* sqlParams.add(nameValuePair.getValue()); }*//** if (!sqlBuffer.toString().endsWith(",")) { throw new* ServiceException("未检测到更新条件2, 已生成的SQL: " + sqlBuffer + ", 参数: " +* updateObject); }*/String sqlString = sqlBuffer.append("updateTime=? ").append(" where id= ?").toString();sqlParams.add(updateTime);sqlParams.add(id);return new NameValuePair<>(sqlString, sqlParams.toArray());} catch (Exception e) {throw new ServiceException("生成hibernate更新的SQL异常, 参数: " + updateObject, e);}}
四.获取
name:动态sql语句value;参数值