1. 程式人生 > >java 註解 動態生成sql

java 註解 動態生成sql

合理的利用java 註解 可以有效的解決動態sql 的問題 下面直接上我的原始碼

1 自定義的註解類 Column 和 Table

/**
 * 實體類的屬性註解-跟@table 配合使用
 * @author zhangh
 * @date 2018年5月22日下午2:59:18
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    String value();
    boolean lookUp() default false;//模糊查詢標識 預設是false
}
/**
 * 實體類 的表名註解
 * @author zhangh
 * @date 2018年5月22日下午2:58:07
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
    String value();
}

實體類

/**
 * 對外暴露的介面實體類
 * @author zhangh
 * @date 2018年5月22日下午2:31:39
 */
@Table("clouds_open_api")
public class OpenApi
extends BaseObject implements Serializable{
/** * */ private static final long serialVersionUID = 1490626332112676475L; @Column(value="id" ) private Integer id;//主鍵 @Column(value="api_name",lookUp=true) private String api_name;//介面名稱 @Column(value="api_address") private
String api_address;//介面訪問地址 @Column(value="api_type") private String api_type;//介面訪問型別 @Column(value="api_param") private String api_param;//介面引數 @Column(value="api_result") private String api_result;//介面返回資料 @Column(value="api_status") private String api_status;//介面狀態 1 可用 0禁用 @Column(value="api_charge") private String api_charge;//是否收費(1收費 0免費)預設是免費 public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getApi_name() { return api_name; } public void setApi_name(String api_name) { this.api_name = api_name; } public String getApi_address() { return api_address; } public void setApi_address(String api_address) { this.api_address = api_address; } public String getApi_type() { return api_type; } public void setApi_type(String api_type) { this.api_type = api_type; } public String getApi_param() { return api_param; } public void setApi_param(String api_param) { this.api_param = api_param; } public String getApi_result() { return api_result; } public void setApi_result(String api_result) { this.api_result = api_result; } public String getApi_status() { return api_status; } public void setApi_status(String api_status) { this.api_status = api_status; } public String getApi_charge() { return api_charge; } public void setApi_charge(String api_charge) { this.api_charge = api_charge; } public OpenApi() { super(); } public OpenApi(String api_name) { super(); this.api_name = api_name; } }

dao 層

public class OpenApiDAO extends BaseDAO<OpenApi> {

    public List<Map<String, Object>> findList(OpenApi openApi) {
        return getJdbcTemplate().queryForList(querySQL(openApi));
    }

    /**
     * 根據反射動態生成sql
     * @author zhangh
     * @date 2018年5月22日下午6:14:37
     * @param object 具體的domain 
     * @return
     */
    private static String querySQL(Object object) {
        StringBuilder sb = new StringBuilder();
        Class<?> mClass = object.getClass();
        boolean isExist = mClass.isAnnotationPresent(Table.class);
        if (!isExist)
            return null;
        Table table = (Table) mClass.getAnnotation(Table.class);
        String tabName = table.value();
        Field[] fields = mClass.getDeclaredFields();
        // 拼裝SQL表名
        sb.append("select "+getSelect(fields)+" from ").append(tabName).append(" where 1=1");
        // 獲取類的所有欄位
        sb.append(getWhere(object));
        return sb.toString();
    }

    /**
     * 獲取註解中的value 組裝成sql 的select 物件 不要使用select * 查詢 提高效率
     * @author zhangh
     * @date 2018年5月23日上午8:37:37
     * @param fields
     * @return
     */
    public static String getSelect(Field[] fields){
        StringBuilder sb = new StringBuilder("");
        for (Field f : fields) {
            boolean isFExist = f.isAnnotationPresent(Column.class);
            if (!isFExist) {
                continue;
            }
            sb.append(f.getAnnotation(Column.class).value()).append(",");
        }
        if(sb.equals("")){
            return " 1 ";
        }else{
            return sb.toString().substring(0, sb.toString().length()-1);
        }
    }

    /**
     * 動態獲取sql 的where 條件
     * @author zhangh
     * @date 2018年5月23日上午8:48:55
     * @param object
     * @return
     */
    public static String getWhere(Object object){
        StringBuilder sb = new StringBuilder();
        for (Field f : object.getClass().getDeclaredFields()) {
            // 下面程式碼獲取欄位註解
            boolean isFExist = f.isAnnotationPresent(Column.class);
            if (!isFExist) {
                continue;
            }
            String columnName = f.getAnnotation(Column.class).value();
            boolean lookup = f.getAnnotation(Column.class).lookUp();//模糊查詢標識
            // 下面程式碼獲取欄位值
            Object filedValue = null;
            try {
                PropertyDescriptor pd = new PropertyDescriptor(f.getName(), object.getClass());// PropertyDescriptor 類表示JavaBean類通過儲存器匯出一個屬性
                Method method = pd.getReadMethod();// getReadMethod() 獲得用於讀取屬性值的方法,即getter方法
                filedValue = method.invoke(object);// 通過反射呼叫getter方法
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 拼裝SQL條件
            if (filedValue == null) {
                continue;
            }
            sb.append(" and ").append(columnName);
            if (filedValue instanceof String) {
                // 包含多段
                if (((String) filedValue).contains(",")) {
                    String[] arr = ((String) filedValue).split(",");
                    sb.append(" in(");
                    for (String str : arr) {
                        sb.append("'").append(str).append("'").append(",");
                    }
                    sb.deleteCharAt(sb.length() - 1).append(")");
                } else {
                    if(lookup){//api_name 需要模糊查詢
                        sb.append(" like ").append("'").append(filedValue).append("%'");
                    }else{                      
                        sb.append("=").append("'").append(filedValue).append("'");
                    }
                }
            } else if (filedValue instanceof Boolean) {
                sb.append("=").append("'").append(filedValue).append("'");
            } else if (filedValue instanceof Integer) {
                sb.append("=").append(filedValue);
            }
        }
        return sb.toString();
    }
}

service 層以及實現層

@Service
public class OpenApiServiceImpl implements OpenApiService{

    @Autowired
    private OpenApiDAO openApiDAO;

    public OpenApi findById(Integer id){
        return openApiDAO.findById(id);
    }
    public List<Map<String, Object>> findList(OpenApi openApi){
        return openApiDAO.findList(openApi);
    }
}

public interface OpenApiService {
    public OpenApi findById(Integer id);

    public List<Map<String, Object>> findList(OpenApi openApi);
}

controller 核心程式碼

    @RequestMapping(value="/getRegisterOpenApi1",method=RequestMethod.POST)
    @ResponseBody
    public List<Map<String, Object>> getRegisteOpenApi1(@RequestBody(required=false) OpenApi openApi) throws Exception{
        return openApiService.findList(null==openApi?new OpenApi():openApi);
    }

請求結果
引數一:{“api_name”:”so”,”api_address”:”http://localhost:8080/store/api/fingById/1“}
列印sql:select id,api_name,api_address,api_type,api_param,api_result,api_status,api_charge from clouds_open_api where 1=1 and api_name like ‘so%’ and api_address=’http://localhost:8080/store/api/fingById/1