1. 程式人生 > 其它 >jdbc操作mysql(三):利用註解封裝

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語句

  • 拼接: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();
}