在休眠映射中使用包装器 Integer 类或 int 基元

2022-08-31 22:32:00

在我工作的公司中,我们进行了一次重大讨论,讨论是否应该更好地对基元(java.lang.Integer,java.lang.Long)使用包装类,或者是否直接在将实体映射到Hibernate中的表的POJO中使用基元类型。

我们的想法是,我们希望这些值在数据库中不为 null。

支持使用基元的论据:

  • 将这些值作为 int 处理意味着它们永远不可能为 null,这样就不可能无意中获取字段上的 null 引用。
  • int=32/64 位内存。整数 = 16 字节的内存,并且速度也较慢

支持使用包装器对象的参数:

  • 我们可以在数据库级别添加约束,以始终防止空值到达那里
  • 我们最终可能会得到误导性的数据,每当用户没有设置值时,我们可以在数据库中使用0而不是null,而错误的数据是一个困难的陷阱。
  • 对象比基元具有更强的表现力。我们有空值和整数值,因此我们可以使用注释更轻松地验证它们(javax.validation.constraints.NotNull)。

答案 1

使用包装纸,让你的生活变得简单。

您的数据模型应该决定这一点。无论如何,您都应该在数据库中强制实施可空性。

如果它们在数据库中为 null,则使用包装器。如果它们不可为 null,并且您使用包装器,那么如果您尝试将 null 插入到数据库中,则会收到异常。

如果你的数据模型没有规定它,那么去约定,一直使用包装器。这样,人们就不必思考或决定值为 0 表示 null。

我还会质疑你关于它性能会降低的断言。你测量过吗?我是说真的测量过了吗?当您与数据库交谈时,比16位和32位之间的区别有更多的考虑因素。

只需使用简单、一致的解决方案即可。到处使用包装器,除非有人给你一个很好的理由(有准确的测量统计数据)来做其他事情。


答案 2

认为应该提到:

在持久类中使用非基元属性的休眠建议(第 4.1.2 节)实际上是指标识符属性

4.1.2. 提供标识符属性

Cat 有一个名为 id 的属性。此属性映射到数据库表的主键列。该属性可能已被调用任何内容,其类型可能是任何基元类型,任何基元“包装器”类型,java.lang.String或java.util.Date。

...

我们建议您在持久类上声明一致命名的标识符属性,并使用可为 null(即非基元)的类型。

尽管如此,基元的优势并不强:

  1. 在属性中具有不一致的非空值比 NullPointerException 更糟糕,因为潜伏的 bug 更难跟踪:由于编写代码,直到检测到问题并且它可能显示在与其源完全不同的代码上下文中,因此需要花费更多时间。
  2. 关于性能:在测试代码之前 - 这通常是一个过早的考虑。安全应该是第一位的。

推荐