注解:
所谓注解就是,给你的某个包、类、字段、方法、局部变量、方法参数等加个标记,这样我们可以在不方便或者不能直接对包,类,字段等等操作时,选择通过注解来简洁进行操作
泛型:
泛型的本质是参数化类型,所操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
反射:
反射是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部信息。 应用:1.决定一个对象的类型 2.可以得到这个类的修饰符、字段、方法、构造器和父类的信息 3.找出一个接口中定义的常量和方法 4.创建一个运行时才得知名称的类的实例 5.获取和设置对象的字段值,即使字段名称直到运行程序时才得知名称 6.调用一个运行时才知道方法名称的对象的方法 7.创建一个新的数组,其大小和元素的类型直到运行时才知到,然后再修改数组中的元素
看完上面的总结,如果对注解,泛型,反射认识还是有些模糊,那么下面的例子,定能让你豁然开朗,理解都在注释中。
例子:
根据所提供的javabean,自动生成相应的增删改查SQL语句
JavaBean(这里是ProductBean)
package yanda.demo7_28;
import com.java.base.annotation.PrimaryKey;
@Table(
"product")
public class ProductBean {
@PrimaryKey(
"id")
private int id;
private String name;
private float price;
@Column(
"id")
public int getId() {
return id;
}
public void setId(
int id) {
this.id = id;
}
@Column(
"name")
public String
getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(
"price")
public float getPrice() {
return price;
}
public void setPrice(
float price) {
this.price = price;
}
}
Table注解:
package yanda
.demo7_28
import java
.lang.annotation.ElementType
import java
.lang.annotation.Retention
import java
.lang.annotation.RetentionPolicy
import java
.lang.annotation.Target
@Target(value=ElementType
.TYPE)
// 用于指定数据库表名称
@Retention(RetentionPolicy
.RUNTIME)
public @interface Table {
String value()
}
PrimaryKey注解:
package yanda
.demo7_28
import java
.lang.annotation.ElementType
import java
.lang.annotation.Retention
import java
.lang.annotation.RetentionPolicy
import java
.lang.annotation.Target
@Target(value=ElementType
.FIELD)
//用于指定数据库的主键
@Retention(RetentionPolicy
.RUNTIME)
public @interface PrimaryKey {
String value()
}
Column注解:
package
com.java.base.annotation
import java
.lang.annotation.ElementType
import java
.lang.annotation.Retention
import java
.lang.annotation.RetentionPolicy
import java
.lang.annotation.Target
@Target(value=ElementType
.METHOD)
// 用于指定数据表的列名称
@Retention(RetentionPolicy
.RUNTIME)
public @interface Column {
String value()
}
Dao文件(BaseDao):
package yanda
.demo7_28
import java
.lang.reflect.Field
import java
.lang.reflect.InvocationTargetException
import java
.lang.reflect.Method
import java
.util.ArrayList
import java
.util.HashMap
import java
.util.List
import java
.util.Map
import java
.util.Set
import java
.util.Map.Entry
import
com.java.base.annotation.PrimaryKey
//定义一个泛型类
public class BaseDao<T> {
public boolean
add(T t) {
Class clazz = t
.getClass()
Table table = (Table) clazz
.getDeclaredAnnotation(Table
.class)
String tableName = table
.value()
System
.out.println(tableName)
Map<Object, Object> columnAndValue = getColumnAndValue(clazz, t)
//获取指定行视图和指定列中的单元格的值
Set<Entry<Object, Object>>
set = columnAndValue
.entrySet()
List<Object> primaryKey = getPrimaryKey(clazz)
String keys =
""
String values =
""
for (Entry<Object, Object> entry :
set) {
if(keys
.length()>
0) {
keys +=
","
}
if(values
.length()>
0) {
values +=
","
}
keys += entry
.getKey()
values +=
"'"+entry
.getValue()+
"'"
System
.out.println(entry
.getKey()+
","+entry
.getValue())
}
String sql =
"insert into "+tableName+
"("+keys+
") values("+values+
")"
System
.out.println(sql)
return true
}
public boolean delete(T t) {
Class clazz = t
.getClass()
//获得Bean
//获取表名称
Table table = (Table) clazz
.getDeclaredAnnotation(Table
.class)
//getDeclaredAnnotation()返回直接存在于此元素上的所有注释
String tableName = table
.value()
System
.out.println(tableName)
Map<Object, Object> columnAndValue = getColumnAndValue(clazz, t)
//获取指定行视图和制定列中的单元格的值
Set<Entry<Object, Object>>
set = columnAndValue
.entrySet()
List<Object> primaryKey = getPrimaryKey(clazz)
String keysAndvalues =
""
for (Entry<Object, Object> entry :
set) {
//上面这个是我没有用PrimaryKey注解时的写法,这个写过于鸡肋,因为如果主键的name不是id就不行了
if(primaryKey
.contains(entry
.getKey())){
keysAndvalues += entry
.getKey() +
" = " + entry
.getValue()
}
}
String sql =
"delete from "+tableName+
" where "+keysAndvalues
System
.out.println(sql)
return true
}
public boolean update(T t) {
Class clazz = t
.getClass()
Table table = (Table) clazz
.getDeclaredAnnotation(Table
.class)
//getDeclaredAnnotation()返回直接存在于此元素上的所有注释
String tableName = table
.value()
System
.out.println(tableName)
Map<Object, Object> columnAndValue = getColumnAndValue(clazz, t)
//获取指定行视图和制定列中的单元格的值
Set<Entry<Object, Object>>
set = columnAndValue
.entrySet()
List<Object> primaryKey = getPrimaryKey(clazz)
String keysAndvalues =
""
String FkeysAndvalues =
""
int i =
1
for(Entry<Object, Object> entry :
set){
if(primaryKey
.contains(entry
.getKey())){
FkeysAndvalues +=
" " + entry
.getKey() +
" = " + entry
.getValue()
i++
}
else{
if(
1<i&&i <
set.size()){
keysAndvalues +=
" and "
keysAndvalues += entry
.getKey() +
" = " + entry
.getValue()
}
else{
keysAndvalues += entry
.getKey() +
" = " + entry
.getValue()
i++
}
}
}
String sql =
"updata "+tableName+
" set "+keysAndvalues+
" where"+FkeysAndvalues
System
.out.println(sql)
return true
}
public boolean selete(T t) {
Class clazz = t
.getClass()
//获得Bean
//获取表名称
Table table = (Table) clazz
.getDeclaredAnnotation(Table
.class)
//getDeclaredAnnotation()返回直接存在于此元素上的所有注释
String tableName = table
.value()
System
.out.println(tableName)
Map<Object, Object> columnAndValue = getColumnAndValue(clazz, t)
//获取指定行视图和制定列中的单元格的值
Set<Entry<Object, Object>>
set = columnAndValue
.entrySet()
String keysAndvalues =
""
for (Entry<Object, Object> entry :
set) {
if(keysAndvalues
.length()>
0) {
keysAndvalues +=
" and "
}
keysAndvalues += entry
.getKey() +
" = " + entry
.getValue()
}
String sql =
"selete* from "+tableName+
" where "+keysAndvalues
System
.out.println(sql)
return true
}
//按照<列明,属性>的格式输出所有的单元格
private Map<Object, Object> getColumnAndValue(Class<? extends T> clazz, T t) {
//首先声明了一个map键值对
Map<Object, Object> map = new HashMap<>()
//获取clazz类的所有方法
Method[] methods = clazz
.getDeclaredMethods()
//获取的是类自身声明的所有方法,包含public、protected和private方法
for (Method method : methods) {
String methodName = method
.getName()
if(methodName
.startsWith(
"get")) {
//获得所有的get方法
Column column = method
.getDeclaredAnnotation(Column
.class)
getDeclaredAnnotation()返回直接存在于此元素上的所有注释
//这个方法里放有参数时,返回指定类型的注解。如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
try {
map
.put(column
.value(), method
.invoke(t))
//invoke执行方法
} catch (IllegalAccessException e) {
e
.printStackTrace()
} catch (IllegalArgumentException e) {
e
.printStackTrace()
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e
.printStackTrace()
}
}
}
return map
}
private List<Object> getPrimaryKey(Class<? extends T> clazz){
List<Object> list = new ArrayList<>()
Field[] fields = clazz
.getDeclaredFields()
//获得某个类的所有声明字段(id,name,price)
for (Field field : fields) {
if(field
.isAnnotationPresent(PrimaryKey
.class)) {
//Package
.isAnnotationPresent()如果指定类型的注释存在于此元素上,则返回true;否则flase
PrimaryKey primaryKey = field
.getDeclaredAnnotation(PrimaryKey
.class)
try {
list
.add(primaryKey
.value())
} catch (IllegalArgumentException e) {
e
.printStackTrace()
}
}
}
return list
}
}
主函数(main):
package yanda.demo7_28;
public class Demo7_28_9 {
public static void main(String[] args)
throws Exception {
ProductBean productBean =
new ProductBean();
productBean.setId(
1);
productBean.setName(
"iphone");
productBean.setPrice(
5000);
ProductDao productDao =
new ProductDao();
productDao.add(productBean);
productDao.delete(productBean);
productDao.update(productBean);
productDao.selete(productBean);
}
}
输出结果: