本篇主要是使用注解的方式使用JPA
JPA拥有哪些注解呢?
注解 | 解释 | |
@Entity | 声明类为实体或表 | |
@Table | 声明表名。 | |
@Basic | 指定非约束明确的各个字段。 | |
@Embedded | 指定类或它的值是一个可嵌入的类的实例的实体的属性。 | |
@Id | 指定的类的属性,用于识别(一个表中的主键)。 | |
@GeneratedValue | 指定如何标识属性可以被初始化,例如自动、手动、或从序列表中获得的值。 | |
@Transient | 指定的属性,它是不持久的,即:该值永远不会存储在数据库中。 | |
@Column | 指定持久属性栏属性。 | |
@SequenceGenerator | 指定在@GeneratedValue注解中指定的属性的值。它创建了一个序列。 | |
@TableGenerator | 指定在@GeneratedValue批注指定属性的值发生器。它创造了的值生成的表。 | |
@AccessType | 这种类型的注释用于设置访问类型。如果设置@AccessType(FIELD),则可以直接访问变量并且不需要getter和setter,但必须为public。如果设置@AccessType(PROPERTY),通过getter和setter方法访问Entity的变量。 | |
@JoinColumn | 指定一个实体组织或实体的集合。这是用在多对一和一对多关联。 | |
| 指定的字段和用于主要或辅助表的唯一约束。 | |
@ColumnResult | 参考使用select子句的SQL查询中的列名。 | |
@ManyToMany | 定义了连接表之间的多对多一对多的关系。 | |
@ManyToOne | 定义了连接表之间的多对一的关系。 | |
@OneToMany | 定义了连接表之间存在一个一对多的关系。 | |
@OneToOne | 定义了连接表之间有一个一对一的关系。 | |
@NamedQueries | 指定命名查询的列表。 | |
@NamedQuery | 指定使用静态名称的查询。 |
那么JPA是通过什么规则来根据方法名生成sql语句查询的呢?
其实JPA在这里遵循Convention over configuration(约定大约配置)的原则,遵循spring 以及JPQL定义的方法命名。Spring提供了一套可以通过命名规则进行查询构建的机制。这套机制会把方法名首先过滤一些关键字,比如 find…By, read…By, query…By, count…By 和 get…By 。系统会根据关键字将命名解析成2个子语句,第一个 By 是区分这两个子语句的关键词。这个 By 之前的子语句是查询子语句(指明返回要查询的对象),后面的部分是条件子语句。如果直接就是 findBy… 返回的就是定义Respository时指定的领域对象集合,同时JPQL中也定义了丰富的关键字:and、or、Between等等,下面我们来看一下JPQL中有哪些关键字:
Keyword | Sample | JPQL snippet |
---|---|---|
And | findByLastnameAndFirstname | … where x.lastname = ?1 and |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age ⇐ ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull | findByAgeIsNull | … where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection age) | … where x.age not in ?1 |
TRUE | findByActiveTrue() | … where x.active = true |
FALSE | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
@Column 注解的源码如下:
public @interface Column {
String name() default "";
boolean unique() default false;
boolean nullable() default true;
boolean insertable() default true;
boolean updatable() default true;
String columnDefinition() default "";
String table() default "";
int length() default 255;
int precision() default 0;
int scale() default 0;
}
从定义可以看出,@Column注解一共有10个属性,这10个属性均为可选属性,各属性含义分别如下:
name
name属性定义了被标注字段在数据库表中所对应字段的名称;
unique
unique属性表示该字段是否为唯一标识,默认为false。如果表中有一个字段需要唯一标识,则既可以使用该标记,也可以使用@Table标记中的@UniqueConstraint。
nullable
nullable属性表示该字段是否可以为null值,默认为true。
insertable
insertable属性表示在使用“INSERT”脚本插入数据时,是否需要插入该字段的值。
updatable
updatable属性表示在使用“UPDATE”脚本插入数据时,是否需要更新该字段的值。insertable和updatable属性一般多用于只读的属性,例如主键和外键等。这些字段的值通常是自动生成的。
columnDefinition
columnDefinition属性表示创建表时,该字段创建的SQL语句,一般用于通过Entity生成表定义时使用。(也就是说,如果DB中表已经建好,该属性没有必要使用。)
table
table属性定义了包含当前字段的表名。
length
length属性表示字段的长度,当字段的类型为varchar时,该属性才有效,默认为255个字符。
precision和scale
precision属性和scale属性表示精度,当字段类型为double时,precision表示数值的总长度,scale表示小数点所占的位数。