使用自定义注解简单实习orm框架的sql生成
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用自定义注解简单实习orm框架的sql生成相关的知识,希望对你有一定的参考价值。
使用自定义注解简单实习orm框架的sql生成
- 背景
- 代码
- 我们先把架子搭出来
- 自定义注解: table注解
- 工具类
- 查询条件使用自定义注解实现
背景
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;
以上是关于使用自定义注解简单实习orm框架的sql生成的主要内容,如果未能解决你的问题,请参考以下文章