面试题答案
一键面试整体设计架构
- 数据库表结构读取:通过JDBC获取数据库元数据,解析表结构信息,包括表名、列名、数据类型等。
- 注解定义:定义自定义注解,用于标记需要生成DAO的实体类和DAO接口等。
- 注解处理器:编写注解处理器,根据注解标记和数据库表结构信息,生成Java实体类、DAO接口及其实现类。
- 代码生成:使用代码生成技术,如JavaPoet或Velocity等,将生成的代码写入文件。
技术选型
- JDBC:用于获取数据库元数据。
- Java注解:自定义注解标记相关类。
- Java注解处理器:基于JDK的注解处理工具,在编译期处理注解。
- JavaPoet:用于生成Java代码,简洁高效。
核心代码示例及说明
- 定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface GenerateDAO {
}
说明:GenerateDAO
注解用于标记需要生成DAO的实体类。
- 注解处理器
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
@SupportedAnnotationTypes("GenerateDAO")
public class DAOProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (Element element : roundEnv.getElementsAnnotatedWith(GenerateDAO.class)) {
String className = element.getSimpleName().toString();
List<FieldSpec> fields = getTableColumns(className);
generateEntityClass(className, fields);
generateDAOInterface(className);
generateDAOImplementation(className);
}
return true;
}
private List<FieldSpec> getTableColumns(String tableName) {
List<FieldSpec> fields = new ArrayList<>();
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/yourdb", "user", "password");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("DESCRIBE " + tableName)) {
while (rs.next()) {
String columnName = rs.getString("Field");
String type = rs.getString("Type");
FieldSpec field = FieldSpec.builder(ClassName.get("java.lang", getJavaType(type)), columnName, Modifier.PRIVATE).build();
fields.add(field);
}
} catch (Exception e) {
e.printStackTrace();
}
return fields;
}
private void generateEntityClass(String className, List<FieldSpec> fields) {
TypeSpec entityClass = TypeSpec.classBuilder(className)
.addModifiers(Modifier.PUBLIC)
.addFields(fields)
.build();
JavaFile javaFile = JavaFile.builder("com.example.entity", entityClass)
.build();
try {
javaFile.writeTo(System.out);
} catch (IOException e) {
e.printStackTrace();
}
}
private void generateDAOInterface(String className) {
MethodSpec findByIdMethod = MethodSpec.methodBuilder("findById")
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
.returns(ClassName.get("com.example.entity", className))
.addParameter(ClassName.get("java.lang", "Integer"), "id")
.build();
TypeSpec daoInterface = TypeSpec.interfaceBuilder(className + "DAO")
.addModifiers(Modifier.PUBLIC)
.addMethod(findByIdMethod)
.build();
JavaFile javaFile = JavaFile.builder("com.example.dao", daoInterface)
.build();
try {
javaFile.writeTo(System.out);
} catch (IOException e) {
e.printStackTrace();
}
}
private void generateDAOImplementation(String className) {
MethodSpec findByIdMethod = MethodSpec.methodBuilder("findById")
.addModifiers(Modifier.PUBLIC)
.returns(ClassName.get("com.example.entity", className))
.addParameter(ClassName.get("java.lang", "Integer"), "id")
.addStatement("$T result = null", ClassName.get("com.example.entity", className))
.addStatement("return result")
.build();
TypeSpec daoImplementation = TypeSpec.classBuilder(className + "DAOImpl")
.addModifiers(Modifier.PUBLIC)
.addSuperinterface(ClassName.get("com.example.dao", className + "DAO"))
.addMethod(findByIdMethod)
.build();
JavaFile javaFile = JavaFile.builder("com.example.dao.impl", daoImplementation)
.build();
try {
javaFile.writeTo(System.out);
} catch (IOException e) {
e.printStackTrace();
}
}
private String getJavaType(String sqlType) {
// 简单类型映射
if (sqlType.startsWith("varchar") || sqlType.startsWith("char")) {
return "String";
} else if (sqlType.startsWith("int")) {
return "Integer";
} else if (sqlType.startsWith("double")) {
return "Double";
}
return "Object";
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
}
说明:
GenerateDAO
注解处理器在编译期处理标记了GenerateDAO
注解的类。getTableColumns
方法通过JDBC获取表的列信息,并映射为Java字段。generateEntityClass
方法生成Java实体类。generateDAOInterface
方法生成DAO接口。generateDAOImplementation
方法生成DAO接口的实现类。
以上代码仅是示例,实际应用中需根据具体需求完善,如数据库连接配置、异常处理、更多数据库类型映射等。