概念
JPA(Java Persistence API)是 Sun 官方提出的 Java 持久化规范。Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的?套 JPA 应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用Spring Data JPA 可以极大提高开发效率!添加依赖org.Springframework.boot Spring-boot-starter-data-jpa mysql mysql-connector-java
添加配置文件
Spring.datasource.url=jdbc:mysql://localhost:3306/test Spring.datasource.username=root Spring.datasource.password=root Spring.datasource.driver-class-name=com.mysql.jdbc.Driver Spring.jpa.properties.hibernate.hbm2ddl.auto=update Spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect Spring.jpa.show-sql= true
其实这个 hibernate.hbm2ddl.auto 参数的作用主要用于:自动创建 | 更新 | 验证数据库表结构,有四个值:
create:每次加载 hibernate 时都会删除上一次的生成的表,然后根据 model 类再重新来生成新表,哪怕两次没有任何改 变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。 create-drop:每次加载 hibernate 时根据 model 类生成表,但是 sessionFactory 一关闭,表就自动删除。 update:最常用的属性,第一次加载 hibernate 时根据 model 类会自动建立起表的结构(前提是先建立好数据库),以后 加载 hibernate 时根据 model 类自动更新表结构,即使表结构改变了,但表中的行仍然存在,不会删除以前的行。要注意 的是当部署到服务器后,表结构是不会被马上建立起来的,是要等应用第一次运行起来后才会。 validate:每次加载 hibernate 时,验证创建数据库表结构,只会和数据库中的表进??较,不会创建新 表,但是会插?新值。 dialect:主要是指定生成表名的存储引擎为 InneoDB。 show-sql:是否打印出自动生产的SQL,?便调试的时候查看。添加实体类和 Dao@Entity public class User implements Serializable {private static final long serialVersionUID = 1L; @Id @GeneratedValue private Long id; @Column(nullable = false, unique = true) private String userName; @Column(nullable = false) private String passWord; @Column(nullable = false, unique = true) private String email; @Column(nullable = true, unique = true) private String nickName; @Column(nullable = false) private String regTime; //省略 getter settet ?法、构造?法 }
Dao只要继承 JpaRepository 类就可以,几乎可以不用写方法,还有一个特别有个性的功能非常赞,就是可以根据方法名来自动的
生产SQL,如 findByUserName 会自动生产一个以 userName 为参数的查询方法,如 findAll 自动会查询表里面的所有数据,如自动分页等等。 这块有点像我们目前正在使用的jeesite,父类以及实现了这些基本的方法。Entity 中不映射成列的字段得加 @Transient 注解,不加注解也会映射成列:public interface UserRepository extends JpaRepository{ User findByUserName(String userName); User findByUserNameOrEmail(String username, String email); }
基本查询
基本查询也分为两种,一种是 Spring Data 默认已经实现,一种是根据查询的方法来自动解析成 SQL。预先生成方法Spring Data JPA 默认预先生成了一些基本的 CURD 的方法,如增、删、改等。 继承 JpaRepository:public interface UserRepository extends JpaRepository<User, Long> { }使用默认方法:@Test public void testBaseQuery() { userRepository.findAll(); userRepository.findOne(1l); userRepository.save(user); userRepository.delete(user); userRepository.count(); userRepository.exists(1l); // ...}
自定义简单查询
自定义的简单查询就是根据方法名来自动生成 SQL,主要的语法是 findXXBy、readAXXBy、queryXXBy、 countXXBy、getXXBy 后面跟属性名称:User findByUserName(String userName);也可以加一些关键字 And、Or:User findByUserNameOrEmail(String username, String email);修改、删除、统计也是类似语法:Long deleteById(Long id);Long countByUserName(String userName);基本上 SQL 体系中的关键词都可以使?,如 LIKE、IgnoreCase、OrderBy。ListfindByEmailLike(String email);User findByUserNameIgnoreCase(String userName);List findByUserNameOrderByEmailDesc(String email);
复杂查询
在实际的开发中需要用到分页、筛选、连表等查询的时候就需要特殊的方法或者自定义 SQL。分页查询在实际使用中非常普遍了,Spring Data JPA 已经帮我们实现了分页的功能,在查询的方法中,需要传入参数 Pageable,当查询中有多个参数的时有多个参数的时候 Pageable 建议做为最后一个参数传入:@Query("select u from User u") PagefindALL(Pageable pageable);Page findByNickName(String nickName, Pageable pageable);Pageable 是 Spring 封装的分页实现类,使用的时候需要传页数、每页条数和排序规则。@Test public void testPageQuery(){ int page=1,size=10; Sort sort = new Sort(Direction.DESC, "id"); Pageable pageable = new PageRequest(page, size, sort); userRepository.findALL(pageable); userRepository.findByNickName("testName", pageable); }
限制查询
有时候我们只需要查询前 N 个元素,或者只取前一个实体。User findFirstByOrderByLastnameAsc(); User findTopByOrderByAgeDesc(); PagequeryFirst10ByLastname(String lastname, Pageable pageable); List findFirst10ByLastname(String lastname, Sort sort); List findTop10ByLastname(String lastname, Pageable pageable);
自定义 SQL 查询
使用 Spring Data 部分的 SQL 都可以根据方法名定义的方式来实现,但是由于某些原因我们想使自己定义 的 SQL 来查询,Spring Data 也可以完美支持;在 SQL 的查询的法上使用 @Query 注解,如涉及到删除 和修改需要加上 @Modifying,也可以根据需要添加 @Transactional 对事物的支持,查询超时的设置等。@Transactional(timeout = 10) @Modifying @Query("update User set userName = ?1 where id = ?2") int modifyById(String userName, Long id); @Transactional @Modifying @Query("delete from User where id = ?1") void deleteById(Long id); @Query("select u from User u where u.email = ?1") User findByEmail(String email);
多表查询
多表查询在 Spring Data JPA 中有两种实现方式,第一种是利用 hibernate 的级联查询来实现,第二种是创建 一个结果集来接收连表查询后的结果。个人觉得Hibernate挺麻烦,暂时不看。使用枚举使用枚举的时候,希望数据库中存储的是枚举对应的 String 类型,而不是枚举的索引值,需要在属性上面添加 @Enumerated(EnumType.STRING) 注解:@Enumerated(EnumType.STRING)@Column(nullable = true) private UserType type;
不需要和数据库映射的属性
正常情况下我们在实体类上加入注解 @Entity,就会让实体类和表相关连,如果其中某个属性不需要和数据 库来关联只是在展示的时候做计算,只需要加上 @Transient 属性即可。
这里目前主要用的是hibernate,关于Jpa与mybatis的整合,能不能整合,没有尝试,后面再研究