Java 在j2ee应用程序中建模isbn号的正确方法

Java 在j2ee应用程序中建模isbn号的正确方法,java,jakarta-ee,isbn,Java,Jakarta Ee,Isbn,我正在试用一个使用servlet和JSP的web应用程序,需要在我的类和hibernate映射中对一个项目的isbn号进行建模。 哪个应该是isbn号码的类型?长还是字符串?我曾遇到过许多使用这两种方法的教程。。 isbn应该是一个10位的标识符。有时你会遇到像0-85131-041-9这样的数字,它不能是长的。有些例子使用没有连字符的数字 那么,应该是哪种类型?有什么建议吗 谢谢 标记我将它存储在Long属性中,并使用格式化程序/解析器(本质上是转换器)。当您要显示它时,转换器应该只将Long

我正在试用一个使用servlet和JSP的web应用程序,需要在我的类和hibernate映射中对一个项目的isbn号进行建模。 哪个应该是isbn号码的类型?长还是字符串?我曾遇到过许多使用这两种方法的教程。。 isbn应该是一个10位的标识符。有时你会遇到像0-85131-041-9这样的数字,它不能是长的。有些例子使用没有连字符的数字

那么,应该是哪种类型?有什么建议吗

谢谢


标记我将它存储在
Long
属性中,并使用格式化程序/解析器(本质上是转换器)。当您要显示它时,转换器应该只将
Long
属性转换为在正确位置使用连字符的人类表示。当您要验证/保留它时,转换器应该从提交的值中删除所有连字符,并将其放入
Long
属性中

基本上,这与使用
Date
字段的想法相同,您可以借助
SimpleDateFormat
在人工表示中格式化/解析该字段。唯一的区别是标准JavaSEAPI不提供ISBN格式化程序/解析器。你需要自己写一个或者采用一个第三方的(虽然现在还没有)。最后,此转换器可以用作JSP标记(如JSTL的
)或独立Java类,由EL函数调用,或者在使用JSF时用作
@FacesConverter

由于ISBN编号的复杂性,它实际上更多地存储为
字符串
,因此开发人员不需要担心有效的模式。这是好是坏是你必须问自己和你的团队的问题。

ISBN有13位数字(请参阅)。我将使用一个类来检查给定
字符串的有效性。比如:

class ISBN {
  private String isbn;
  public ISBN(String isbn) throws ISBNFormatException {
    // you might want to filter hyphens first, before the check
    if(ISBN.isValid(isbn)) this.isbn = isbn;
    else throw new ISBNFormatException(isbn);
  }
  public static boolean isValid(String s) {
   // validate number here, see wiki
  }
}
当然,这可能有点过分。如果你的应用程序非常简单,你可以选择
String
很好


编辑连字号将数字分成若干组(语言、出版商等)。但是,对于数字的唯一性,连字符(或空格分隔)不起作用。

这个问题实际上与J2EE无关,而只是与Java数据类型以及数据库引擎上的数据类型有关

如果要在任何输出中包含连字符,则必须将其存储为字符串。除非您想编写代码来计算连字符的位置,但其背后的规则相当复杂,具体取决于数字开头的数字值。(如果你正在使用一个分配ISBN或将其拆分并处理碎片的系统,也许你想这样做。如果你只是想让用户输入并记住它,这听起来太麻烦了。)

我想如果你不在乎连字符,你可以使用字符串或长字符。尽管如此,长字符还是会带来额外的痛苦,因为您必须确定何时显示前导零


简短回答:我不认为将其存储为数字有任何好处。使用字符串。

实际上,ISBN不是10位数字,而是12位数字+一个检查。检查可以是一个X

确定ISBN校验位的方法是加权系数为10到1的模数11。罗马数字X代替10,其中10将作为校验数字出现

如果您存储的是用户输入的信息,那么您应该包含校验位,因此它必须是字符串

如果您正在存储实际的ISBN,那么您可以忽略检查,因为您可以计算它。但是,如果使用新的12位数字,则数字大于一个long可以容纳的数字,如果使用旧的10位数字,则它可以容纳在一个long中,但您必须记住,可能需要将前导0加回去。因此,在本例中,我会将其保存在一个字符串中,删除所有非数字数据,例如连字符

另外,看看常见问题,可能有理由将ISBn分开存储,以便按部分进行搜索

ISBN的五个部分如下:
1.当前ISBN-13的前缀为“978”
2.标识国家或地理出版集团的集团或国家标识符
3.发布者标识符,用于标识组中的特定发布者
4.标识特定标题或标题版本的标题标识符
5.校验位是ISBN末尾的单个数字,用于验证ISBN


5不需要保存,因为它可以计算出来,但需要从用户那里捕获以验证输入。

我通常反对“人们为了节省一些字节而做的聪明事情”,所以我也有点反对。ISBN是前10位数字,然后他们发布了ISBN-13。下一步是什么?更多的数字,甚至是字母数字?ISBN不适合一个长的(12位数)@Mark:你显然不是Java开发人员。Java
long
的最大值为
9223372036854775807
,为19位。也许你把
int
2147483647
混淆了,后者的最大值是10位数字。“将长代码转换为在正确位置使用连字符的人类表示法”说起来容易做起来难。它不像(美国)电话号码,连字符之间有固定数字。使用ISBN时,连字符的位置会有所不同。在13位ISBN中,第一组始终为3位,最后一组(校验位)始终为1位,但第二组(语言/地区)可以是1到5,第三组(出版商)可以是1到6,第四组(序列号)可以是1到6。后面几组中允许有多少位取决于前面几组中的值。ISBN-10不使用long的另一个原因是,检查“digit”是以11为基数的,因此不仅可以有0-9的值,还可以有代表“10”的字母“X”。这不是一个i