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

猜你喜欢

转载自blog.csdn.net/forever_insist/article/details/80414639