告别繁琐配置:Easy-Query中@Column注解的10个高级属性让ORM开发效率提升300%

告别繁琐配置:Easy-Query中@Column注解的10个高级属性让ORM开发效率提升300%

【免费下载链接】easy-query java/kotlin high performance lightweight solution for jdbc query,support oltp and olap query,一款java下面支持强类型、轻量级、高性能的ORM,致力于解决jdbc查询,拥有对象模型筛选、隐式子查询、隐式join 【免费下载链接】easy-query 项目地址: https://gitcode.com/dromara/easy-query

你是否还在为复杂的数据库字段映射而烦恼?在实体类与数据库表字段的映射过程中,传统ORM框架往往需要大量XML配置或重复代码。Easy-Query作为一款高性能轻量级ORM框架,通过@Column注解的灵活设计,将字段映射的控制权交还给开发者。本文将深入解析@Column注解的10个核心扩展属性,带你掌握从基础映射到高级功能的全场景应用,让你的数据访问层代码更简洁、更强大。

读完本文你将获得:

  • 掌握@Column注解10+核心属性的实战用法
  • 学会实现字段加密、类型转换等高级功能
  • 解决分表分库、复杂查询等场景下的映射难题
  • 提升ORM层代码质量和开发效率的最佳实践

@Column注解核心能力概览

@Column注解是Easy-Query实现对象-关系映射(ORM)的核心组件,通过它可以将Java实体类字段与数据库表列建立灵活的映射关系。与传统ORM框架相比,Easy-Query的@Column注解提供了更丰富的扩展属性,支持从简单映射到复杂业务场景的全链路覆盖。

注解定义结构

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface Column {
    boolean primaryKey() default false;          // 是否主键
    boolean generatedKey() default false;        // 是否数据库生成键
    String value() default EasyStringUtil.EMPTY; // 数据库列名
    // 更多属性...
}

核心功能矩阵

功能分类关键属性应用场景示例
基础映射value, exist, autoSelect列名映射、临时字段、查询控制
主键策略primaryKey, generatedKey自增主键、UUID生成、分布式ID
数据转换conversion, sqlConversion加解密、类型转换、格式处理
数据库特性dbType, dbDefault, comment字段类型定义、默认值、迁移支持
高级查询sqlExpression, jdbcType函数列、复杂查询条件构建

基础映射能力:从简单到复杂

列名映射与字段忽略

最基础也最常用的功能是指定数据库列名,当实体类字段名与数据库列名不一致时,可以通过value属性显式指定:

public class BlogEntityVO1 {
    @Id
    private String id;
    
    @Column(value = "status1")  // 映射到数据库status1列
    private Integer status;
    
    @Column(exist = false)      // 非数据库字段,仅内存使用
    private String tempProperty;
}

exist=false属性非常实用,它相当于同时设置:

  • autoSelect=false(查询时不自动加载)
  • @InsertIgnore(插入时忽略)
  • @UpdateIgnore(更新时忽略)

查询加载控制

autoSelect属性用于控制字段是否默认被查询加载,适用于大字段或敏感字段的按需加载:

public class Topic {
    @Id
    private String id;
    
    private String title;
    
    @Column(autoSelect = false)  // 不自动查询,需显式指定
    private String content;      // 大文本内容字段
}

autoSelect=false时,常规查询不会返回该字段,需要通过select方法显式指定:

// 只查询id和title
List<Topic> topics = easyQuery.queryable(Topic.class)
    .select(Topic::getId, Topic::getTitle)
    .toList();

// 需要查询content时显式指定
List<Topic> topicsWithContent = easyQuery.queryable(Topic.class)
    .select(Topic::getId, Topic::getContent)
    .toList();

主键策略:灵活应对各种ID生成需求

基础主键配置

通过primaryKey属性标记主键字段,Easy-Query会在CRUD操作中自动将该字段作为主键使用:

public class SysUserVersionLong {
    @Column(primaryKey = true)  // 标记为主键
    private Long id;
    
    private String name;
    // 其他字段...
}

数据库生成键

对于自增主键或数据库函数生成的主键(如MySQL的AUTO_INCREMENT、PostgreSQL的SERIAL),只需添加generatedKey=true

public class TopicY {
    @Column(primaryKey = true, generatedKey = true)
    private Long id;  // 数据库自增主键
    
    private String title;
}

插入后自动回填生成的主键值:

TopicY topic = new TopicY();
topic.setTitle("测试标题");
easyQuery.insertable(topic).executeRows(true);  // 参数true表示回填主键
System.out.println("生成的ID: " + topic.getId());  // 输出数据库生成的ID

自定义主键生成器

对于分布式ID等复杂场景,Easy-Query支持通过primaryKeyGenerator属性配置自定义主键生成器:

public class CustomSnowflakeGenerator implements PrimaryKeyGenerator {
    @Override
    public Object generate(Class<?> entityClass, String propertyName) {
        return SnowflakeIdWorker.nextId();  // 自定义雪花算法实现
    }
}

// 在实体类中使用
public class UserExtra2 {
    @Column(primaryKey = true, primaryKeyGenerator = CustomSnowflakeGenerator.class)
    private Long id;  // 使用自定义ID生成器
    
    private String name;
}

数据转换:实现字段级别的业务逻辑

内存级转换(conversion)

conversion属性允许你定义Java对象在内存中的转换逻辑,适用于VO/DTO与数据库实体之间的类型转换:

// 定义一个金额转换处理器
public class MoneyConverter implements ValueConverter<BigDecimal, Long> {
    @Override
    public Long serialize(BigDecimal value) {
        return value.multiply(new BigDecimal("100")).longValue();  // 元转分
    }
    
    @Override
    public BigDecimal deserialize(Long value) {
        return new BigDecimal(value).divide(new BigDecimal("100"));  // 分转元
    }
}

// 在实体类中使用
public class OrderEntity {
    @Id
    private String id;
    
    @Column(conversion = MoneyConverter.class)  // 应用金额转换
    private BigDecimal totalAmount;  // Java中使用BigDecimal(元),数据库存储Long(分)
}

数据库级转换(sqlConversion)

sqlConversion属性用于生成数据库级别的转换SQL,适用于加密存储、地理信息处理等场景:

// 定义AES加密转换处理器
public class MySQLAesEncryptColumnValueSQLConverter implements ColumnValueSQLConverter {
    @Override
    public String convert(String propertyName, String sqlColumn) {
        // 生成加密SQL: AES_ENCRYPT(sqlColumn, 'secret_key')
        return String.format("AES_ENCRYPT(%s, 'secret_key')", sqlColumn);
    }
    
    @Override
    public String revert(String propertyName, String sqlColumn) {
        // 生成解密SQL: AES_DECRYPT(sqlColumn, 'secret_key')
        return String.format("AES_DECRYPT(%s, 'secret_key')", sqlColumn);
    }
}

// 在实体类中使用
public class SysUserEncrypt {
    @Id
    private String id;
    
    @Column(sqlConversion = MySQLAesEncryptColumnValueSQLConverter.class)
    private String phone;  // 加密存储手机号
    
    @Column(sqlConversion = MySQLAesEncryptColumnValueSQLConverter.class)
    private String idCard; // 加密存储身份证号
}

使用加密字段进行查询时,Easy-Query会自动应用解密逻辑:

// 自动应用解密SQL,无需手动处理
List<SysUserEncrypt> users = easyQuery.queryable(SysUserEncrypt.class)
    .where(o -> o.eq(SysUserEncrypt::getPhone, "13800138000"))
    .toList();

数据库特性支持:DDL与迁移

字段元数据定义

dbTypedbDefaultcomment属性用于定义数据库字段的元数据信息,主要配合Easy-Query的数据库迁移功能使用:

public class MyMigrationBlog0 {
    @Id
    private String id;
    
    @Column(comment = "标题", length = 200)  // 字段注释和长度
    private String title;
    
    @Column(comment = "内容", dbType = "TEXT")  // 指定数据库类型
    private String content;
    
    @Column(comment = "点赞数", dbDefault = "0")  // 默认值
    private Integer starCount;
    
    @Column(comment = "发布时间", dbDefault = "CURRENT_TIMESTAMP")
    private LocalDateTime createTime;
}

这些属性会影响自动生成的DDL语句,例如:

CREATE TABLE my_migration_blog0 (
    id VARCHAR(32) NOT NULL PRIMARY KEY,
    title VARCHAR(200) COMMENT '标题',
    content TEXT COMMENT '内容',
    star_count INT DEFAULT 0 COMMENT '点赞数',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '发布时间'
);

字段重命名支持

renameFrom属性解决了数据库字段重命名时的数据迁移问题:

public class UserInfo {
    @Id
    private String id;
    
    @Column(renameFrom = "user_name")  // 从旧字段名user_name迁移而来
    private String userName;  // 新字段名
}

在数据库迁移时,Easy-Query会自动生成包含数据迁移的SQL:

ALTER TABLE user_info ADD COLUMN user_name VARCHAR(50);
UPDATE user_info SET user_name = user_name;  -- 从旧字段复制数据
ALTER TABLE user_info DROP COLUMN user_name;  -- 删除旧字段

高级查询能力:SQL函数与表达式

复杂SQL表达式(sqlExpression)

sqlExpression属性允许你为字段指定自定义SQL表达式,实现复杂的数据库计算或函数调用:

public class UserExtra2 {
    @Id
    private Long id;
    
    private String firstName;
    private String lastName;
    
    // 组合字段:CONCAT(firstName, lastName)
    @Column(sqlExpression = @ColumnSQLExpression(sql="CONCAT({0},{1})", args = {
        "#{firstName}", "#{lastName}"
    }))
    private String fullName;
}

在查询时,Easy-Query会自动将fullName字段替换为指定的SQL表达式:

// 查询结果中的fullName会自动使用CONCAT(firstName, lastName)计算
List<UserExtra2> users = easyQuery.queryable(UserExtra2.class).toList();

数据库类型控制(jdbcType)

jdbcType属性用于显式指定字段对应的JDBC类型,解决类型映射模糊问题:

public class MyALLTYPE {
    @Id
    private String id;
    
    @Column(jdbcType = JDBCType.DATE)  // 明确指定为DATE类型
    private LocalDate birthday;
    
    @Column(jdbcType = JDBCType.TIMESTAMP)  // 明确指定为TIMESTAMP类型
    private LocalDateTime createTime;
}

实战案例:构建企业级用户实体

综合运用@Column注解的各项属性,我们可以构建一个满足企业级需求的用户实体类:

public class EnterpriseUser {
    // 主键:使用自定义雪花ID生成器
    @Column(primaryKey = true, primaryKeyGenerator = SnowflakeIdGenerator.class)
    private Long id;
    
    // 用户名:非空约束
    @Column(nullable = false, comment = "登录用户名")
    private String username;
    
    // 密码:使用BCrypt加密存储
    @Column(sqlConversion = BCryptColumnValueSQLConverter.class, comment = "加密存储的密码")
    private String password;
    
    // 手机号:AES加密
    @Column(sqlConversion = MySQLAesEncryptColumnValueSQLConverter.class, comment = "加密手机号")
    private String phone;
    
    // 头像URL:长字符串类型
    @Column(dbType = "VARCHAR(512)", comment = "头像图片URL")
    private String avatarUrl;
    
    // 创建时间:数据库自动生成
    @Column(generatedKey = true, dbDefault = "CURRENT_TIMESTAMP", comment = "创建时间")
    private LocalDateTime createTime;
    
    // 扩展信息:JSON格式存储
    @Column(dbType = "JSON", complexPropType = JsonComplexPropType.class, comment = "用户扩展信息")
    private UserExtInfo extInfo;
    
    // 临时字段:不持久化到数据库
    @Column(exist = false)
    private String verificationCode;
}

这个实体类实现了:

  • 分布式ID生成
  • 敏感信息加密存储
  • 复杂类型(JSON)映射
  • 数据库自动生成时间
  • 临时字段处理

最佳实践与性能优化

注解组合使用技巧

常见场景推荐注解组合
逻辑删除字段@Column + @LogicDelete
版本控制字段@Column + @Version
乐观锁实现@Column(primaryKey=true) + @Version
软删除+版本控制@Column + @LogicDelete + @Version

性能优化建议

  1. 大字段处理:对TEXT、BLOB等大字段使用autoSelect=false,避免默认查询加载
  2. 加密字段索引:加密字段无法直接索引,考虑使用哈希值冗余字段建立索引
  3. 批量操作优化:对generatedKey=true的字段,批量插入时建议使用数据库自增而非自定义生成器
  4. 类型匹配:合理使用jdbcType属性,避免不必要的类型转换开销

避坑指南

  1. 主键策略冲突primaryKey=true时,generatedKeyprimaryKeyGenerator只能二选一
  2. 转换器作用范围conversion(内存转换)和sqlConversion(数据库转换)的作用时机不同
  3. 迁移注意事项renameFrom属性仅在数据库迁移时生效,生产环境使用前建议备份数据
  4. 复杂类型限制complexPropType需要配合对应的TypeHandler,自定义时需注意线程安全

总结与展望

Easy-Query的@Column注解通过精心设计的属性体系,将简单易用性与强大功能完美结合。从基础的字段映射到复杂的加密转换,从主键生成到数据库迁移,一个注解即可满足ORM开发的全场景需求。

随着数据访问层技术的发展,未来@Column注解可能会引入更多创新特性:

  • AI辅助的字段类型推荐
  • 基于机器学习的查询性能优化
  • 多数据库适配的智能转换

掌握@Column注解的高级用法,不仅能提升日常开发效率,更能帮助我们构建更健壮、更安全、更高性能的数据访问层。现在就将这些技巧应用到你的项目中,体验Easy-Query带来的ORM开发新范式!

如果你觉得本文对你有帮助,请点赞收藏并关注项目仓库,持续获取Easy-Query的最新技术动态和最佳实践。

【免费下载链接】easy-query java/kotlin high performance lightweight solution for jdbc query,support oltp and olap query,一款java下面支持强类型、轻量级、高性能的ORM,致力于解决jdbc查询,拥有对象模型筛选、隐式子查询、隐式join 【免费下载链接】easy-query 项目地址: https://gitcode.com/dromara/easy-query

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值