一、自定义Annotation
Annotation分为两种:预定义的和自定义的
定义一个Annotation需要说明的信息:
1、@Retention:需要保留多久;Clss,Source,Runtime
2、@Target:目标;Type,Field,Constructor
3、Annotation属性
Annotation属性定义:
1、属性定义的格式:数据类型 属性名() [default 值]
2、每个Annotation包含多个属性 value是默认属性(传参时可以不明确指定属性名)
3、自定义Annotation分为两种:第一种是标识的Annotation(有属性),第二种为可添加属性的Annotation
二、AnnotationDao的设计
定义一个主键的Annotation(Identity),该注解还增加了是否返回主键的属性
基本思路:
1、先获得属性,并设置sql语句
2、同时判断主键且是否需要返回主键,并把主键赋给keyField变量,sql语句是当是主键列的时候设为null,否则是?
3、执行sql,因为主键列不一定在第一列,所以单独定义一个变量a来完成这项操作,然后获取主键值并将类中的主键属性赋值
先将数据插入数据库(表名与类同名(也可不同名,加注解),列名与属性同名),再从数据库中把记录各字段的值读出来,并给该类的属性赋值,并判断是否需要获取主键Identity:
package com.oracle.vo;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(java.lang.annotation.ElementType.FIELD)
public @interface Identity {
boolean value() default false;//是否需要返回主键,默认为不需要
}
Table
package com.oracle.vo;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(java.lang.annotation.ElementType.TYPE)
public @interface Table {
String value();
}
测试类Books
package com.oracle.vo;
@Table("books")
public class Books {
@Identity(true)
private Integer bookid;
private String bookname;
int price;
BaseDao
package com.oracle.test;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.oracle.vo.Identity;
public class BaseDao<T> {
public Connection getconnection() {
Connection conn=null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/oracle","root","tiger");
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
public void close(AutoCloseable auto) {
if(auto!=null) {
try {
auto.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public <T>void save(T obj) {
boolean isIdentity=false;//获取是否需要返回主键
Class<?> c=obj.getClass();
Field[] fs=c.getDeclaredFields();
Field keyField=null;
StringBuffer sql=new StringBuffer("insert into "+c.getSimpleName()+"(");
StringBuffer sql1=new StringBuffer("values(");
for(int i=0;i<fs.length;i++) {
Field f=fs[i];
sql.append(f.getName());
if(f.isAnnotationPresent(Identity.class)) {
isIdentity=f.getAnnotation(Identity.class).value();
keyField=f;
sql1.append("null");
}else {
sql1.append("?");
}
if(i!=fs.length-1) {
sql.append(",");
sql1.append(",");
}else {
sql.append(")");
sql1.append(")");
}
}
sql.append(sql1);
System.out.println(sql);
Connection conn=getconnection();
PreparedStatement ps=null;
ResultSet rs=null;
try {
if(isIdentity) {
ps=conn.prepareStatement(sql.toString(),Statement.RETURN_GENERATED_KEYS);
}else {
ps=conn.prepareStatement(sql.toString());
}
int a=1;//判断是否为主键
for(int i=0;i<fs.length;i++) {
fs[i].setAccessible(true);
if(!fs[i].isAnnotationPresent(Identity.class)) {
ps.setObject(a++, fs[i].get(obj));
}
}
ps.execute();
if(isIdentity) {
rs=ps.getGeneratedKeys();
rs.next();
Object key=rs.getInt(1);//获得主键,并设置给属性
keyField.set(obj, key);
}
}catch(Exception e) {
e.printStackTrace();
}finally {
close(ps);
close(conn);
}
}
}
测试程序
package com.oracle.test;
import com.oracle.vo.Books;
public class TestBaseDao {
public static void main(String[] args) {
BaseDao<Books> dao=new BaseDao<Books>();
Books b=new Books("世界之大",34);
dao.save(b);
System.out.println(b.getBookid());
}
}
结果