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 ages) … where x.age in ?1
NotIn not in() findByAgeNotIn(Collection ages) … 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的优点:

  1. JPA是标准的ORM框架,它提供了对象关系映射(ORM)和数据访问的通用API,可以在不同的实现之间切换。
  2. JPA有更高的抽象层次,不需要手动编写SQL语句,大部分的CRUD操作可以通过简单的API实现。
  3. JPA提供了一些高级功能,如缓存、延迟加载等。
  4. JPA框架提供了更多的自动化,比如自动生成DDL语句等。

JPA的缺点:

  1. JPA的学习成本比较高,需要了解一些复杂的概念和规则。
  2. JPA的性能相对较低,因为它提供的抽象层次较高,可能会产生额外的开销。
  3. JPA框架可能会产生一些意外的行为,如缓存、一级缓存等。

MyBatis

MyBatis的优点:

  1. MyBatis提供了更直接的SQL控制,可以手动编写SQL语句,从而更灵活地控制SQL执行的细节。
  2. MyBatis的学习成本相对较低,因为它不需要了解太多复杂的概念和规则。
  3. MyBatis的性能相对较高,因为它的抽象层次较低,可以更直接地控制SQL的执行细节。

MyBatis的缺点:

  1. MyBatis需要手动编写大量的SQL语句,需要更多的工作量和代码量。
  2. MyBatis不提供ORM功能,需要手动进行对象和数据库表的映射。
  3. MyBatis缺乏一些高级功能,如缓存、延迟加载等。

JPA中的概念和规则

  1. 实体类和实体管理器

    在JPA中,持久化的对象被称为实体。实体类必须使用@Entity注解进行标记,并且需要一个实体管理器(EntityManager)来执行操作。实体类中的每个属性都需要使用注解(如@Id、@Column、@JoinColumn)进行标记,以便JPA能够正确地映射实体属性到数据库表列。

    实体管理器是JPA的核心接口之一,它提供了各种实体操作方法,如persist(持久化)、remove(删除)、find(查找)等。实体管理器也是JPA的上下文,它负责跟踪实体对象的状态变化,并将这些变化同步到数据库中。

  2. 主键和ID生成策略

    在JPA中,每个实体类必须有一个主键。主键可以是简单类型(如整数或字符串)或复合类型(由多个属性组成)。主键需要使用@Id注解进行标记。

    JPA提供了多种ID生成策略,如自动递增、UUID等。可以使用@GeneratedValue注解来指定ID生成策略,如:

  3. 关系映射

    在JPA中,实体类之间的关系可以通过注解来映射。JPA提供了多种关系注解,如@OneToMany、@ManyToOne、@OneToOne和@ManyToMany。这些注解描述了实体类之间的关系及其属性。

    例如,下面是一个@OneToMany关系的例子:

    javaCopy code@Entity
    public class Order {
    @Id
    private Long id;
    @OneToMany(mappedBy = "order")
    private List<OrderItem> items;
    // ...
    }

    @Entity
    public class OrderItem {
    @Id
    private Long id;
    @ManyToOne
    private Order order;
    // ...
    }

    在这个例子中,Order和OrderItem是一对多关系。Order类有一个items属性,它标记了@OneToMany注解,并使用mappedBy属性指定了关联的OrderItem属性名。OrderItem类有一个order属性,它标记了@ManyToOne注解。

  4. 持久化上下文和实体状态

    JPA使用持久化上下文(Persistence Context)来管理实体的状态。持久化上下文是一个缓存,它保存了所有托管状态的实体对象。当一个实体被加载到持久化上下文中时,它处于托管状态。此时,实体对象的属性可以被修改,这些修改会自动同步到数据库中。

    JPA中有三种实体状态:托管状态、游离状态和删除状态。托管状态的实体对象被持久化上下文管理,游离状态的实体对象没有被持久化上下文管理,删除状态的实体对象已经被删除。

    当一个实体对象从数据库中被删除时,它会进入删除状态。删除状态的实体对象不能再被修改,也不能被重新插入到数据库中。

  5. 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();

    @Query("SELECT e FROM Employee e WHERE e.department.name = :departmentName")
    Employee getResultList(String departmentName);

    这个查询使用实体类Employee和属性department.name来查询属于IT部门的所有员工。

  6. 事务管理

    在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还有很多其他的特性,如缓存、锁等,但这些特性相对来说比较高级,需要更深入的了解和掌握。