核心思路是递归获取继承链中所有非静态、非transient字段并扁平化映射为单表列:一、用getDeclaredFields()逐级向上遍历+setAccessible(true)突破限制,LinkedHashSet按名去重且子类优先;二、字段命名统一小驼峰,基础类型直映MySQL类型,自定义对象支持一级展开;三、PreparedStatement动态构建SQL或扩展MyBatis/JPA;四、注意字段隐藏、泛型擦除、空值转换及元信息缓存。

Java 中通过反射解析多层继承实体类并扁平化存入 MySQL 单表,核心思路是:**递归获取所有非静态、非 transient 的字段(含父类),忽略重复字段名,统一映射为单表列**。关键在于正确处理字段可见性、重名冲突、类型兼容性与空值策略。
一、反射遍历全继承链获取全部有效字段
使用 Class#getDeclaredFields() 逐级向上获取字段,跳过 Object.class,并过滤掉静态、瞬态、合成字段:
- 用
Field.setAccessible(true)突破 private 限制 - 用
LinkedHashSet保持声明顺序且去重(按字段名去重,优先保留子类定义的同名字段) - 递归调用
getSuperclass()直到为null
二、字段扁平化命名与类型适配
MySQL 单表不能有同名列,需对继承字段做语义化命名(非简单拼接):
- 推荐策略:统一用小驼峰,避免前缀(如不强制加
base_或user_),仅在语义冲突时人工干预 - 基础类型(
int,boolean,LocalDateTime等)直接映射对应 MySQL 类型(INT,TINYINT(1),DATETIME) - 自定义对象字段(如
Address address)需拆解:支持一级展开(address_province,address_city),但需标注@Embedded或约定命名规则
三、生成 INSERT/UPDATE SQL 或对接 ORM
不建议手写长 SQL 拼接,推荐结合轻量工具或标准 ORM 扩展:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 用
PreparedStatement动态构建参数列表:字段名列表 + 值列表,按反射顺序一一对应 - 若用 MyBatis,可写通用
@SelectProvider方法,根据 Class 动态生成<insert>SQL 片段 - JPA 场景下,可配合
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)+@DiscriminatorColumn,但注意它不自动扁平化嵌套对象,仍需额外处理
四、注意事项与避坑点
实际落地时容易忽略这些细节:
- 字段覆盖判断:子类定义同名字段会隐藏父类字段(field hiding),反射中两者都会被获取,需按“子类优先”原则保留后者
-
泛型擦除影响:
List<String>反射只能拿到List,需结合Field.getGenericType()解析真实元素类型(用于 JSON 序列化存储等场景) -
空值安全:数据库列设为
NULL,Java 字段为基本类型(如int)时需转成包装类(Integer)或预设默认值 -
性能缓存:反射开销大,务必对每个 Class 缓存其扁平化字段元信息(如
Map<Class, List<FlatField>>)
不复杂但容易忽略。

















