使用Java注解开发自动生成SQL

Posted iwideal

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Java注解开发自动生成SQL相关的知识,希望对你有一定的参考价值。

使用注解开发的好处就是减少配置文件的使用。在实际过程中,随着项目越来越复杂,功能越来越多,会产生非常多的配置文件。但是,当配置文件过多,实际维护过程中产生的问题就不容易定位,这样就会徒劳的增加工作量。而使用注解开发,可以减少配置文件的使用,方便代码的维护,同时,在开发速度上也有大幅提升,因此,学会使用注解开发,是有必要掌握的一项技能。

下面为各位展示下使用注解开发自动生成SQL语句的过程。

首先先定义一个实体类,用于和数据库字段进行映射,为了方便,数据库字段名称和实体类变量名称保持一致。

package com.huawei.andrid.net.annotation;

@Table("person")
public class Person
{
	@Column("name")
	private String name;

	@Column("sex")
	private String sex;

	@Column("id")
	private int id;

	@Column("age")
	private int age;

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getSex()
	{
		return sex;
	}

	public void setSex(String sex)
	{
		this.sex = sex;
	}

	public int getId()
	{
		return id;
	}

	public void setId(int id)
	{
		this.id = id;
	}

	public int getAge()
	{
		return age;
	}

	public void setAge(int age)
	{
		this.age = age;
	}

}

  下面我们要为这个实体类定义注解,包含@Table和@Column两个注解。

package com.huawei.andrid.net.annotation;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Documented
@Retention(RUNTIME)
@Target(TYPE)
public @interface Table
{
	public String value();
}

  元注解:

@Documented  生成javadoc时,支持注解
@Retention(RUNTIME)  注解的生命周期
@Target(TYPE)  注解的在类上

 

package com.huawei.andrid.net.annotation;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Documented
@Retention(RUNTIME)
@Target(FIELD)
public @interface Column
{
	public String value();
}

  最后,我们需要解析注解,使用java的反射机制。

private static String query(Object p) throws NoSuchMethodException, SecurityException, IllegalAccessException,
			IllegalArgumentException, InvocationTargetException
	{
		StringBuilder str = new StringBuilder();
		//通过反射获取Class对象,以便获取注解的值
		Class<? extends Object> obj = p.getClass();
		//判断该对象的类上有没有注解@Table
		boolean isExistsTable = obj.isAnnotationPresent(Table.class);
		if (!isExistsTable)
		{
			return null;
		}
		//获取Table注解,并获取注解的值,即表名
		Table table = (Table) obj.getAnnotation(Table.class);
		String tableName = table.value();
		//拼装sql
		str.append("select * from ").append(tableName).append(" where 1=1 ");
		//获取所有的成员变量,并遍历出来成员变量上的注解值
		Field[] fields = obj.getDeclaredFields();
		for (Field field : fields)
		{
			Boolean isExistColumn = field.isAnnotationPresent(Column.class);
			if (!isExistColumn)
			{
				continue;
			}
			//获取成员变量上的注解值
			Column column = field.getAnnotation(Column.class);
			String columnName = column.value();
			//获取成员变量的get方法名
			String methodName = "get" + columnName.substring(0, 1).toUpperCase() + columnName.substring(1);
			//获取成员变量的get方法
			Method method = obj.getMethod(methodName);
			//执行成员变量的get方法,参数为该对象
			Object value = method.invoke(p);
			//过滤掉成员变量中的null值,以及0
			if (null == value || (value instanceof Integer && (Integer) value == 0))
			{
				continue;
			}
			str.append(" and ").append(columnName).append("=").append(value);
		}

		return str.toString();
	}

  测试:

public static void main(String[] args)
	{
		Person p = new Person();
		p.setName("wanglu");
		p.setAge(25);
		String querySQL = null;
		try
		{
			querySQL = query(p);
		}
		catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
				| InvocationTargetException e)
		{
			e.printStackTrace();
		}
		System.out.println(querySQL);
	}

  



以上是关于使用Java注解开发自动生成SQL的主要内容,如果未能解决你的问题,请参考以下文章

Java注解项目实战即模拟Hibenernate生成sql语句

java反射与注解结合使用(根据传入对象输出查询sql)

推荐学java——MyBatis高级

推荐学java——MyBatis高级

推荐学java——MyBatis高级

推荐学java——MyBatis高级