@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) // 默认是RetentionPolicy.CLASS。注解保留到class文件,jvm加载class后,遗弃注解。RetentionPolicy.RUNTIME直到jvm加载class,注解一致保留。
public @interface FieldName{
String name();
}
public class Student{
@FeldName(name = "STU_NAME"); // 加注解,对应数据库字段
private String name;
@FieldName(name = "STU_ID");
private String id;
}
public interface StudentDao{
int addStudent(Strudent student);
}
// 数据库操作
public class StudentDoaImpl() implements StudentDao{
private Conntction connection;
public StudentDaoImpl(Connection connetcion){
this.connection = connection;
}
@Override
public int addStudent(Student student){
// 首先获取student各个属性值。以及属性名。
StringBuilder sql = new StringBulider("INSRT INTO student_t(") // 根据student的属性注解决定给哪个字段赋值。字段写死sql语句会依赖于student的字段,不方便修改,插入字段动态获取,把sql语句与student的字段进行解耦,插入字段修改,sql不必改变。
StringBuilder fieldName = new StringBuilder();
StringBuilder fieldValue = new StringBuilder();
DeclaredField[] declaredFileds = student.getClass.getDeclaredFields();
try{
for(Field field: declaredFileds){
field.setAccessible(true);
FieldName annotation = field.getAnnotation(FieldName.class);
String name = annotation.name(); // 获取注解值
fieldName.append(name + ",");
fieldValue.append("?,"); // 对插入值的处理交给JDBC。
}
}catch(Exception e){
e.peintStackTrace();
return 0;
}
// 删除最后一个‘,’
fieldName.delete(fieldName.lastIndexOf(","), fieldName.length());
fieldValue.delete(fieldName.lastIndexOF("'"), fieldValue.length());
sql.append(fieldName)
.append(")"
.append("VALUES(")
.append(fieldValue)
.append(")");
// sql准备完毕,进行预编译,然后给占位符赋值
try{
PreparedStatement prepareStatement = connection.preparedStatement(sql.toString());
int i = 1;
// declaredFiled数组顺序与准备sql是的declaredFileds的数组顺序一致
// 赋值时可直接通过索引进行赋值
for(Field field: declaredFileds){
field.setAccessible(true);
Object value = "";
value = field.get(student);
preparedStatement.setObject(i,value);
i++;
}
return preparedStatement.executeUpdate();
}catch(Excetion e){
e.printStackTrace();
return 0;
}
}
}
// 以下是抽象工厂模式的实例
// 抽象工厂
public abstract DaoFactory{
// 通过抽象工厂获取具体工厂
public static final int MYSQL = 1;
public static final int SQLSERVER = 2;
public static getDaoFactory(int flag){
switch(flag){
case: MYSQL
return new MySQLFactory;
case: SQLSERVER
return new SqlServerFactory;
}
public abstract StudentDao getStudentDao();
}
// 具体工厂MySQLFactory
public class MySQLFactory extends DaoFactory{
private final String driverName="";
private final String url = "";
private final String user = "";
private final String password = ";
@Override
public StuedntDao getStudentDao(){
try{
Class.forName(driverName);
Connection connection = DriverManger.getConnection(url, user, password);
return new StudentDaoImpl(connection)
}catch(Exception e){
e.printStackTrace();
return null;
}
}
}
// 具体工厂SqlServerFactory
public class SqlServerFactory extends DaoFactory{
private final String driverName="";
private final String url = "";
private final String user = "";
private final String password = ";
@Override
public StuedntDao getStudentDao(){
try{
Class.forName(driverName);
Connection connection = DriverManger.getConnection(url, user, password);
return new StudentDaoImpl(connection)
}catch(Exception e){
e.printStackTrace();
return null;
]
}
}
// 优化,把getStudentDao()的逻辑写在DaoFactory中,MySQLFactory/SqlServerFactory只对四个属性进行赋值。
// 使用
public class Client{
psvm(){
Student student = new Student(1, "test");
DaoFactory factory = DaoFactory.getDaoFactory(DaoFactory.MySQL); // 获取具体工厂
StudentDao studentDao = factory.getStudentDao(); // 具体工厂返回”产品“对象
int x = studentDao.addStudent(student);
}
}
设计模式之工厂模式----抽象工厂实例:解决系统依赖于单一数据库的问题
最新推荐文章于 2021-09-17 15:04:51 发布