使用Java注解将实体类转化为sql字符串

本文介绍如何利用Java注解将实体类转化为SQL字符串。通过定义类注解和方法注解,结合注解处理器,可以方便地将实体类的结构转换为对应的SQL语句。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先是定义一个实体类,如下

/*
 * 定义用户,通过注解映射到数据库
 */
@Table("user")
public class User {

	@Column("id")
	private int id;
	@Column("username")
	private String username;
	@Column("nickname")
	private String nickName;
	@Column("age")
	private int age;
	@Column("email")
	private String email;
	@Column("mobile")
	private String mobile;
	public User(){
		//
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getNickname() {
		return nickName;
	}
	public void setNickName(String nickName) {
		this.nickName = nickName;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getMobile() {
		return mobile;
	}
	public void setMobile(String mobile) {
		this.mobile = mobile;
	}
}


上面有类注解和方法注解,分别new一个Annotation,

其中注解里面只有一个值,因此直接用value()声明即可

Table.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*ElementType参数有
 * CONSTRUCTOR:构造器的声明
 * FIELD:域,属性的声明
 * LICAL_VARIABLE:局部变量的声明
 * PACKAGE:包声明
 * PARAMETER:参数声明
 * TYPE:类,接口(包括注解类型)或enum声明
 * */
@Target({ElementType.TYPE})
/*
 * 需要保存的级别
 * SOURCE:注解将被编译器丢掉
 * CLASS:注解在class文件中可以使用,会被VM丢掉
 * RUNTIME:VM将在运行时也保留注解,因此可以通过反射机制读取注释的信息
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String value();
}

Column.java

//定义一个描述用户表属性字段的注解

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 Column {

	String value();
}

然后是转换函数

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;



//将传入的用户信息转换为sql语句
public class ToSql {

	public static String query(Object u){
		StringBuilder sqlstr=new StringBuilder();
		//获取到class
		Class c=u.getClass();
		//  查看是否包含Table类型的注解
		if(!c.isAnnotationPresent(Table.class)){
			return null;
		}
		//如果包含,获取到Table类,并通过此获取到Table类注解
		Table table=(Table)c.getAnnotation(Table.class);
		String tableName=table.value();
		//先将sql语句的前半部分写入
		sqlstr.append("SELECT * FROM ").append(tableName).append(" WHERE 1=1");
		//获取所有自己声明的属性
		Field[] fields=c.getDeclaredFields();
		//遍历属性
		for (Field field : fields) {
			//通过注解中的值来获取属性名(注解中的值应该与属性名相等)
			String columnValue=field.getAnnotation(Column.class).value();
			//获取属性的get方法的方法名,方法名的写法一般为get+属性名(属性名的第一个字母大写)
			String getMethodName="get"+columnValue.substring(0, 1).toUpperCase()+columnValue.substring(1);
			//使用反射通过方法名获取方法,并调用invoke方法运行该方法,得到返回值
			Object fieldValue=null;
			try {
				Method getMethod=c.getMethod(getMethodName);
				fieldValue=getMethod.invoke(u);
			} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				// TODO Auto-generated catch block
				System.out.println("MethodName="+getMethodName);
				e.printStackTrace();
			}
			//因为是遍历所有的方法,所以有些方法是没有赋值的,也就是不需要查找,将其剔除
			if(fieldValue==null||((fieldValue instanceof Integer) &&((Integer)fieldValue==0))){
				continue;
			}
			sqlstr.append(" AND ").append(columnValue);
			//判断字符串,多个中满足任何一个用IN,并使用''
			if(fieldValue instanceof String){
				//感觉接口太神奇了
				if(((String)fieldValue).contains(",")){
					String[] values=((String)fieldValue).split(",");
					sqlstr.append(" IN(");
					for (String string : values) {
						sqlstr.append("'").append(string).append("'").append(",");
					}
					//删除最后一个","
					sqlstr.deleteCharAt(sqlstr.length()-1);
					sqlstr.append(")");
				}else{
					//字符串表示法
					sqlstr.append("=").append("'").append(fieldValue).append("'");
				}
			}else if (fieldValue instanceof Integer) {
				sqlstr.append("=").append(fieldValue);
			} 
		}
		return sqlstr.toString();
	}
}

Test.java测试类

public class Test {

	public static void main(String[] args) {
		User user=new User();
		user.setEmail("2378@134.com,2334@189.com");
		System.out.println(ToSql.query(user));
	}
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值