展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

jdbc操作mysql(三):利用注解封装

案例五:利用注解封装

重复步骤

  • 我们使用jdbc操作mysql时发现,操作不同表中数据,所写的方法基本相同;比如我们根据id向用户表添加数据,根据id删除商品表的数据,或者查询所有数据并用list集合接收
int add(int id);
	
int del(int id);

List<Blog> getAll();

List<User> getAll();

解决思路

  • 我们发现实现这些方法的sql语句基本上是相同的,操作不同表中的数据时,需要的表名和字段不同;那么我们是否可以将共有的sql语句提取出来,获取表名和字段后,动态拼接sql语句
  • 所要解决的问题是:获取将要操作的表的表名和字段,这里我们通过自定义注解获取
  • 思路:通过自定义注解保存实体类对应的表的信息,获取表的表名和字段,最后拼接sql语句

实践操作

自定义注解

  • 注解到类头,用于设置表对应的实体类的默认值
@Target(ElementType.TYPE)  // 表示注解用于什么地方
@Retention(RetentionPolicy.RUNTIME)  // 表示需要在什么级别保存注解信息
public @interface Table {
	// 自定义注解元素的写法:基本数据类型|String|枚举  方法名()  [default] 默认值;
	public String name() default "";
}

  • 注解到属性上,用来设置字段对应的属性的默认值
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Cloumn {
	// 默认值为空
	public String value() default "";
}

编写实体类

/**
 * 使用自定义注解,设置默认值
 */
@Table(name = "t_user")
public class User {

	private Integer id;
	private Integer age;
	@Cloumn(value = "user_name")
	private String userName;
	private String sex;
	private Date birthday;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", age=" + age + ", userName=" + userName + ", sex=" + sex + ", birthday=" + birthday
				+ "]";
	}
}

封装工具类

public class AnnotationUtil {
	/**
	 * 获取实体类映射的表名
	 */
	public static String getTable(Class<?> clazz) {
		Table table = clazz.getAnnotation(Table.class);  // 通过getAnnotation获取@table的注释内容
		if(table != null) {
			String name = table.name();
			if(name != null && name.trim().length() > 0) {
				return name;
			}
		}
		// 如果实体类上没有@Table,则默认tablename = className,getSimpleName方法返回实体类的类名
		return clazz.getSimpleName();
	}
	
	/**
	 * 获取实体类映射的字段
	 */
	public static List<String> getFields(Class<?> clazz) {
		Field[] fields = clazz.getDeclaredFields();  // 利用反射获得某个类的所有声明的字段
		List<String> list = new ArrayList<String>();  // 将数组中的值遍历进list集合
		for(Field field : fields) {
			// 获取@Cloumn的注解内容
			Cloumn cloumn = field.getAnnotation(Cloumn.class);
			//使用了@Cloumn注解,则向list集合添加注解内容value,没有使用注解,则向list集合添加字段
			if(cloumn != null) {
				String value = cloumn.value();
				if(value != null && value.trim().length() > 0) {
					list.add(value);
				}
			} else {
				list.add(field.getName());
			}
		}
		return list;
	}
}

拼接sql语句

/**
 * 例如操作t_user表中的数据:select id, age, user_name, sex, birthday from t_user;
 */
public String getAll(Class<?> clazz) {
    SQL sql = new SQL();  // new一个对象存放sql语句
    List<String> fields = AnnotationUtil.getFields(clazz);  // 获取字段
    StringBuilder sb = new StringBuilder();
    fields.forEach(f -> sb.append(f + ","));  // 拼接上逗号
    String str = sb.substring(0, sb.length()-1);
    sql.SELECT(str);
    sql.FROM(AnnotationUtil.getTable(clazz)); // select 字段 from 表名
    System.out.println("sql:" + sql.toString());
    return sql.toString();
}

posted @ 2021-06-17 21:10  DogLeftover  阅读(115)  评论(0编辑  收藏  举报