使用自定义注解简单实习orm框架的sql生成

背景

orm 框架怎么生成的sql,我们给他一个实体对象如何生成sql,这个大家有没有想过,今天我们使用自定义注解来实现一把

代码

直接上代码了就用一个简单的实体对象吧

@Data
public class User {

    private String name;
    private String password;
    private Integer age;

    public User(String name, String password, Integer age) {
        this.name = name;
        this.password = password;
        this.age = age;
    }
}

我们先把架子搭出来

public class UserDao {

    public void getUser(User user){
        //这个地方我们只模仿生成sql即可,有了sql再用jdbc即可
        //但是如果生成sql,我们想要的就是 select * from user where name = "" and age = 13
        //我们去封装一个获取sql的方法
        String createsql = SqlUtil.createsql(user);
        System.out.println(createsql);
    }

    public static void main(String[] args) {
        User u = new User();
        new UserDao().getUser(u);
    }
}

说吧了就是想要一个这样的效果,比较简单,方便大家理解自定义注解的使用

自定义注解: table注解

package com.wfg.annotation;

//自定义注解 表示表

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//表示注解可以加在哪
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {

    public String value() default "";
}

user实体类增加
@Table(value = “t_user”)

工具类

package com.wfg.dao;

import com.wfg.annotation.Table;

/**
 * @author wufagang
 * @description
 * @date 2021年04月18日 8:33 上午
 */
public class SqlUtil {

    //获取一个查询sql
    public static String createsql(Object object){
        //step1 : 获取运行类型
        Class<?> clazz = object.getClass();
        //step1 判断是否加了这个注解
        StringBuffer sb = new StringBuffer("select * from ");
        if(clazz.isAnnotationPresent(Table.class)){
            //step2 得到注解
            Table annotation = clazz.getAnnotation(Table.class);
            String value = annotation.value();
            sb.append(value);
        }

        return sb.toString();
    }
}

此时我们一节可以获取
select * from t_user

同理我们可以自定义字段和

这里整理一个工作中条件查询使用的自定义注解,部分敏感代码我会替换的

查询条件使用自定义注解实现

package com.jd.cjg.businessidentity.common.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Query {

    // 基本对象的属性名
    String propName() default "";
    //  查询方式
    Type type() default Type.EQUAL;

    /**
     * 连接查询的属性名,如User类中的dept
     */
    String joinName() default "";

    /**
     * 默认左连接
     */
    Join join() default Join.LEFT;

    /**
     * 多字段模糊搜索,仅支持String类型字段,多个用逗号隔开, 如@Query(blurry = "email,username")
     */
    String blurry() default "";

    enum Type {
        // 相等
        EQUAL
        // 大于等于
        , GREATER_THAN
        //  小于等于
        , LESS_THAN
        //  中模糊查询
        , INNER_LIKE
        //  左模糊查询
        , LEFT_LIKE
        //  右模糊查询
        , RIGHT_LIKE
        //  小于
        , LESS_THAN_NQ
        //  包含
        , IN
        , NOT_IN
        // 不等于
        ,NOT_EQUAL
        // between
        ,BETWEEN
        // 不为空
        ,NOT_NULL
        // 为空
        ,IS_NULL
    }

    /**
     * 适用于简单连接查询,复杂的请自定义该注解,或者使用sql查询
     */
    enum Join {
        LEFT, RIGHT, INNER
    }

}


query注解工具类

@Slf4j
public class QueryHelper {

	public static <Q> List<Example.Criteria> createCriteria(Example example, Q condition) {
		if(condition == null){
			return example.getOredCriteria();
		}


		Example.Criteria criteria = example.createCriteria();

		List<Example.Criteria> list = new ArrayList<>();
		try {
			List<Field> fields = getAllFields(condition.getClass(), new ArrayList<>());
			for (Field field : fields) {
				boolean accessible = field.isAccessible();
				// 设置对象的访问权限,保证对private的属性的访
				field.setAccessible(true);
				Query q = field.getAnnotation(Query.class);
				if (q != null) {
					String propName = q.propName();
					String joinName = q.joinName();
					String blurry = q.blurry();
					String attributeName = isBlank(propName) ? field.getName() : propName;
					Class<?> fieldType = field.getType();
					Object val = field.get(condition);
					if (Objects.isNull(val) || "".equals(val)) {
						continue;
					}
					Join join = null;
					
					switch (q.type()) {
						case EQUAL:
							list.add(criteria.andEqualTo(attributeName, val));
							break;
						case GREATER_THAN:
							list.add(criteria.andGreaterThanOrEqualTo(attributeName, val));
							break;
						case LESS_THAN:
							list.add(criteria.andLessThanOrEqualTo(attributeName, val));
							break;
						case LESS_THAN_NQ:
							list.add(criteria.andLessThan(attributeName, val));
							break;
						case INNER_LIKE:
							list.add(criteria.andLike(attributeName, "%" + val.toString() + "%"));
							break;
						case LEFT_LIKE:
							list.add(criteria.andLike(attributeName, "%" + val.toString()));
							break;
						case RIGHT_LIKE:
							list.add(criteria.andLike(attributeName, val.toString() + "%"));
							break;
						case IN:
							if (CollectionUtils.isNotEmpty((Collection<Object>)val)) {
								list.add(criteria.andIn(attributeName, (Collection<Object>)val));
							}
							break;
						case NOT_IN:
							if (CollectionUtils.isNotEmpty((Collection<Object>)val)) {
								list.add(criteria.andNotIn(attributeName, (Collection<Object>)val));
							}
							break;
						case NOT_EQUAL:
							list.add(criteria.andNotEqualTo(attributeName, val));
							break;
						case NOT_NULL:
							list.add(criteria.andIsNotNull(attributeName));
							break;
						case IS_NULL:
							list.add(criteria.andIsNull(attributeName));
							break;
						case BETWEEN:
							List<Object> between = new ArrayList<>((List<Object>)val);
							list.add(criteria.andBetween(attributeName, between.get(0), between.get(1)));
							break;
						default: break;
					}
				}
				field.setAccessible(accessible);
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		return list;
	}

	private static boolean isBlank(final CharSequence cs) {
		int strLen;
		if (cs == null || (strLen = cs.length()) == 0) {
			return true;
		}
		for (int i = 0; i < strLen; i++) {
			if (!Character.isWhitespace(cs.charAt(i))) {
				return false;
			}
		}
		return true;
	}

	public static List<Field> getAllFields(Class clazz, List<Field> fields) {
		if (clazz != null) {
			fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
			getAllFields(clazz.getSuperclass(), fields);
		}
		return fields;
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值