JPA的命名规范
JPA的命名规范
Spring Data JPA是个非常强大的ORM持久化解决方案,免去了mybatis或spring jdbcTemplate的开发人员编写脚本的无趣工作。
通过简单明了地约定好接口方法的规则,来自动生成相应的JPQL语句,映射成PO对象,能大幅节省开发人员的编码量。
接口方法的命名规则也很简单,明白And、Or、Is、Equal、Greater、StartingWith等英文单词的含义,就可以写接口方法了。
以下是从Spring Data JPA官方网站上的docs整理而来,网上其他有些文章写的有的是错的。
关键词 | SQL符号 | 样例 | 对应的JPQL语句片段 |
---|---|---|---|
And | and | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | = | findByFirstname,findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
Between | between xxx and xxx | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | < | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | <= | findByAgeLessThanEqual | … where x.age <= ?1 |
LessThan | < | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | <= | findByAgeLessThanEqual | … where x.age <= ?1 |
After | > | findByStartDateAfter | … where x.startDate > ?1 |
Before | < | findByStartDateBefore | … where x.startDate < ?1 |
IsNull | is null | findByAgeIsNull | … where x.age is null |
IsNotNull,NotNull | is not null | findByAge(Is)NotNull | … where x.age not null |
Like | like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | not like | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | like ‘xxx%’ | findByFirstnameStartingWith | … where x.firstname like ?1(parameter bound with appended %) |
EndingWith | like ‘xxx%’ | findByFirstnameEndingWith | … where x.firstname like ?1(parameter bound with prepended %) |
Containing | like ‘%xxx%’ | findByFirstnameContaining | … where x.firstname like ?1(parameter bound wrapped in %) |
OrderBy | order by | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | <> | findByLastnameNot | … where x.lastname <> ?1 |
In | in() | findByAgeIn(Collection |
… where x.age in ?1 |
NotIn | not in() | findByAgeNotIn(Collection |
… where x.age not in ?1 |
TRUE | =true | findByActiveTrue() | … where x.active = true |
FALSE | =false | findByActiveFalse() | … where x.active = false |
IgnoreCase | upper(xxx)=upper(yyyy) | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
JPA和mybatis的优缺点比较
JPA
JPA的优点:
- JPA是标准的ORM框架,它提供了对象关系映射(ORM)和数据访问的通用API,可以在不同的实现之间切换。
- JPA有更高的抽象层次,不需要手动编写SQL语句,大部分的CRUD操作可以通过简单的API实现。
- JPA提供了一些高级功能,如缓存、延迟加载等。
- JPA框架提供了更多的自动化,比如自动生成DDL语句等。
JPA的缺点:
- JPA的学习成本比较高,需要了解一些复杂的概念和规则。
- JPA的性能相对较低,因为它提供的抽象层次较高,可能会产生额外的开销。
- JPA框架可能会产生一些意外的行为,如缓存、一级缓存等。
MyBatis
MyBatis的优点:
- MyBatis提供了更直接的SQL控制,可以手动编写SQL语句,从而更灵活地控制SQL执行的细节。
- MyBatis的学习成本相对较低,因为它不需要了解太多复杂的概念和规则。
- MyBatis的性能相对较高,因为它的抽象层次较低,可以更直接地控制SQL的执行细节。
MyBatis的缺点:
- MyBatis需要手动编写大量的SQL语句,需要更多的工作量和代码量。
- MyBatis不提供ORM功能,需要手动进行对象和数据库表的映射。
- MyBatis缺乏一些高级功能,如缓存、延迟加载等。
JPA中的概念和规则
实体类和实体管理器
在JPA中,持久化的对象被称为实体。实体类必须使用@Entity注解进行标记,并且需要一个实体管理器(EntityManager)来执行操作。实体类中的每个属性都需要使用注解(如@Id、@Column、@JoinColumn)进行标记,以便JPA能够正确地映射实体属性到数据库表列。
实体管理器是JPA的核心接口之一,它提供了各种实体操作方法,如persist(持久化)、remove(删除)、find(查找)等。实体管理器也是JPA的上下文,它负责跟踪实体对象的状态变化,并将这些变化同步到数据库中。
主键和ID生成策略
在JPA中,每个实体类必须有一个主键。主键可以是简单类型(如整数或字符串)或复合类型(由多个属性组成)。主键需要使用@Id注解进行标记。
JPA提供了多种ID生成策略,如自动递增、UUID等。可以使用@GeneratedValue注解来指定ID生成策略,如:
关系映射
在JPA中,实体类之间的关系可以通过注解来映射。JPA提供了多种关系注解,如@OneToMany、@ManyToOne、@OneToOne和@ManyToMany。这些注解描述了实体类之间的关系及其属性。
例如,下面是一个@OneToMany关系的例子:
javaCopy code
public class Order {
private Long id;
private List<OrderItem> items;
// ...
}
public class OrderItem {
private Long id;
private Order order;
// ...
}在这个例子中,Order和OrderItem是一对多关系。Order类有一个items属性,它标记了@OneToMany注解,并使用mappedBy属性指定了关联的OrderItem属性名。OrderItem类有一个order属性,它标记了@ManyToOne注解。
持久化上下文和实体状态
JPA使用持久化上下文(Persistence Context)来管理实体的状态。持久化上下文是一个缓存,它保存了所有托管状态的实体对象。当一个实体被加载到持久化上下文中时,它处于托管状态。此时,实体对象的属性可以被修改,这些修改会自动同步到数据库中。
JPA中有三种实体状态:托管状态、游离状态和删除状态。托管状态的实体对象被持久化上下文管理,游离状态的实体对象没有被持久化上下文管理,删除状态的实体对象已经被删除。
当一个实体对象从数据库中被删除时,它会进入删除状态。删除状态的实体对象不能再被修改,也不能被重新插入到数据库中。
JPQL查询语言
JPA提供了一种面向对象的查询语言,称为JPQL(Java Persistence Query Language)。JPQL类似于SQL,但是它使用实体类和属性名而不是表和列名来查询数据。
例如,下面是一个简单的JPQL查询:
javaCopy codeQuery query = entityManager.createQuery(
"SELECT e FROM Employee e WHERE e.department.name = :departmentName");
query.setParameter("departmentName", "IT");
List<Employee> employees = query.getResultList();
Employee getResultList(String departmentName);这个查询使用实体类Employee和属性department.name来查询属于IT部门的所有员工。
事务管理
在JPA中,所有数据库操作都必须在事务中进行。事务是一组数据库操作,它们要么全部成功,要么全部失败。JPA提供了两种方式来管理事务:编程式事务和声明式事务。
编程式事务需要使用EntityManager来手动启动和提交事务,如下面的例子:
javaCopy codeEntityManager entityManager = ...;
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
// 执行数据库操作
transaction.commit();声明式事务则使用注解来管理事务,如下面的例子:
javaCopy code@Service
@Transactional
public class EmployeeService {
@Autowired
private EntityManager entityManager;
public void updateEmployee(Employee employee) {
// 执行数据库操作
}
}在这个例子中,使用@Transactional注解标记了updateEmployee方法,表示这个方法应该在事务中执行。
这些就是JPA中一些比较重要的概念和规则。当然,JPA还有很多其他的特性,如缓存、锁等,但这些特性相对来说比较高级,需要更深入的了解和掌握。