java 註解 動態生成sql
阿新 • • 發佈:2019-01-30
合理的利用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’