0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一文详谈Spring JPA

如意 来源:CSDN 作者:阿文 2020-06-30 17:29 次阅读

什么是 JPA

大家好,今天我和大家聊一下关于Spring JPA 的相关知识,我们先来了解下什么是 JPA ?

JPA (Java Persistence API) 是 Sun 官方提出的 Java 持久化规范。它为 Java 开发人员提供了一种对象/关联映射工具来管理 Java 应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合 ORM 技术,结束现在 Hibernate,TopLink,JDO 等 ORM 框架各自为营的凌乱局面。JPA 在充分吸收了现有 Hibernate,TopLink,JDO 等ORM框架的基础上发展而来的,具有易于使用,伸缩性强等优点。从上面的解释中我们可以了解到JPA 是一套规范,而类似 Hibernate,TopLink,JDO 这些产品是实现了 JPA 规范。

了解了什么是 JPA,我们来看看本文的主角——spring data jpa。

spring data jpa

Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套 JPA 应用框架,底层使用了 Hibernate 的 JPA 技术实现,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率。

什么意思呢?如果用过Hibernate或者MyBatis的话,就会知道对象关系映射(ORM)框架有多么方便。但是Spring Data JPA框架功能更进一步,为我们做了 一个数据持久层框架几乎能做的任何事情。以Springboot整合MyBatis为例,比如我们要向数据库中插入一些用户的数据,那么我们需要先定义用户的实体类,然后我们要定义一个UserDao:

@RepositorypublicclassUserDao{@Autowired JdbcTemplate jdbcTemplate;publicintaddUser(User user){return jdbcTemplate.update(“INSERT INTO t_user(username,jobs,phone) VALUE (?,?,?)”,user.getName(),user.getJobs(),user.getPhone()); }publicintupdateUser(User user){return jdbcTemplate.update(“UPDATE t_user SET username=?,jobs=?,phone=? WHERE id=?”, user.getName(),user.getJobs(),user.getPhone(),user.getId());}publicintdeleteUser(Integer id){return jdbcTemplate.update(“DELETE FROM t_user WHERE id=?”,id); }public User getUserById(Integer id){return jdbcTemplate.queryForObject(“SELECT * FROM t_user WHERE id =?”,new BeanPropertyRowMapper《》(User.class),id); }public List《User》 getAllUser(){return jdbcTemplate.query(“SELECT * FROM t_user”,new BeanPropertyRowMapper《》(User.class)); }}

以及UserService

@ServicepublicclassUserService{@Autowired UserDao userDao;publicintaddUser(User user){return userDao.addUser(user);}publicintupdateUser(User user){return userDao.updateUser(user);}publicintdeleteUser(Integer id){return userDao.deleteUser(id); }public User getUserById(Integer id){return userDao.getUserById(id); }public List《User》 getAllUser(){return userDao.getAllUser(); }}

最后,我们在去调用对应的service 中的方法。这是传统的方式,如果使用mapper,会稍微简单一些,比如我们要添加mapper

@MapperpublicinterfaceUserMapper{intaddUser(User user);intdeleteUser(int id);intupdateUser(User user);User getUserById(Integer id);List《User》 getAllUsers();}

然后定义一个UserMapper.xml ,添加对应的CURD SQL语句,做好映射,然后改造service,例如

@ServicepublicclassUserService{@Autowired UserMapper userMapper;publicintaddUser(User user){return userMapper.addUser(user);}publicintupdateUser(User user){return userMapper.updateUser(user);}publicintdeleteUser(Integer id){return userMapper.deleteUser(id); }public User getUserById(Integer id){return userMapper.getUserById(id); }public List《User》 getAllUser(){return userMapper.getAllUsers(); }}

发现什么问题了吗?如果我们要去实现多个表的操作,我们需要定义不同的实体类,然后实现对应的mapper,然后写同样的增删改查方法,最后调用。这也太麻烦了些,而Spring data jpa 则可以轻松的帮我们实现这些繁琐重复且没有技术含量的操作。我们一起看下吧!

案例演示

1.首先,我们需要配置pom.xml

《dependency》《groupId》mysql《/groupId》《artifactId》mysql-connector-java《/artifactId》《/dependency》《dependency》《groupId》org.springframework.boot《/groupId》《artifactId》spring-boot-starter-data-jpa《/artifactId》《/dependency》

2.然后是application.properties 的配置

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=truespring.datasource.username=rootspring.datasource.password=123456spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.jpa.properties.hibernate.hbm2ddl.auto=createspring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialectspring.jpa.show-sql=true

这里重点简单介绍下spring.jpa.properties.hibernate.hbm2ddl.auto有几种配置:

create:表示每次加载Hibernate时都会删除上一次生成的表(包括数据),然后重新生成新表,即使两次没有任何修改也会这样执行。适用于每次执行单测前清空数据库的场景。

create-drop:表示每次加载Hibernate时都会生成表,但当SessionFactory关闭时,所生成的表将自动删除。

update:最常用的属性值,第一次加载Hibernate时创建数据表(前提是需要先有数据库),以后加载Hibernate时不会删除上一次生成的表,会根据实体更新,只新增字段,不会删除字段(即使实体中已经删除)。

validate:每次加载Hibernate时都会验证数据表结构,只会和已经存在的数据表进行比较,根据model修改表结构,但不会创建新表。

不配置此项,表示禁用自动建表功能

spring.jpa.show-sql=true 该配置当在执行数据库操作的时候会在控制台打印 sql 语句,方便我们检查排错等。

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect 这是数据库的方言配置。

3.接下来我们建立用户实体类

@EntitypublicclassUser{@Id@GeneratedValueprivatelong id;@Column(nullable = false, unique = true)private String userName;@Column(nullable = false)private String password;@Column(nullable = false)privateint age;}

这里的一些注解解释如下:

@Entity 是一个类注解,用来注解该类是一个实体类用来进行和数据库中的表建立关联关系,首次启动项目的时候,默认会在数据中生成一个同实体类相同名字的表(table),也可以通过注解中的 name 属性来修改表(table)名称, 如@Entity(name=“user”) , 这样数据库中表的名称则是 user 。该注解十分重要,如果没有该注解首次启动项目的时候你会发现数据库没有生成对应的表。

@Table 注解也是一个类注解,该注解可以用来修改表的名字,该注解完全可以忽略掉不用,@Entity 注解已具备该注解的功能。

@Id 类的属性注解,该注解表明该属性字段是一个主键,该属性必须具备,不可缺少。

@GeneratedValue 该注解通常和 @Id 主键注解一起使用,用来定义主键的呈现形式,该注解通常有多种使用策略,先总结如下:

@GeneratedValue(strategy= GenerationType.IDENTITY) 该注解由数据库自动生成,主键自增型,在 mysql 数据库中使用最频繁,oracle 不支持。

@GeneratedValue(strategy= GenerationType.AUTO) 主键由程序控制,默认的主键生成策略,oracle 默认是序列化的方式,mysql 默认是主键自增的方式。

@GeneratedValue(strategy= GenerationType.SEQUENCE) 根据底层数据库的序列来生成主键,条件是数据库支持序列,Oracle支持,Mysql不支持。

@GeneratedValue(strategy= GenerationType.TABLE) 使用一个特定的数据库表格来保存主键,较少使用。

上面这些主键生成策略中,以 mysql 为例, IDENTITY 和 AUTO 用的较多,二者当中 IDENTITY 用的多些,以下文章当中演示的 demo 主键均使用 @GeneratedValue(strategy= GenerationType.IDENTITY) 的生成策略。

@Column 是一个类的属性注解,该注解可以定义一个字段映射到数据库属性的具体特征,比如字段长度,映射到数据库时属性的具体名字等。

@Transient 是一个属性注解,该注解标注的字段不会被映射到数据库当中。

4. 声明 `UserRepository`接口,继承`JpaRepository`,如下所示

publicinterfaceUserRepositoryextendsJpaRepository《User, Long》 {}

这里的 JpaRepository继承了接口PagingAndSortingRepository和QueryByExampleExecutor。而,PagingAndSortingRepository又继承CrudRepository。

因此,JpaRepository接口同时拥有了基本CRUD功能以及分页功能。因此,这里我们可以继承JpaRepository,从而获得Spring为我们预先定义的多种基本数据操作方法。

5.然后我们定义一个测试类, 这里我们演示下添加操作, @Transactional 表示开启事务防止出现脏数据。

……@Autowiredprivate UserRepository userRepository;@Test@TransactionalpublicvoiduserAddTest(){ User user = new User(); user.setUserName(“吴彦祖”); user.setAge(30); user.setPassword(“123456”);userRepository.save(user); User item = userRepository.findByUserName(“wyk”);log.info(JsonUtils.toJson(item)); }

6.接下来我们说下查询,查询可以分为基本查询和自定义查询,一种是 spring data 默认已经实现,只需要要继承`JpaRepository`,一种是根据查询的方法来自动解析成 SQL。

@TestpublicvoidtestQuery()throws Exception { User user=new User();userRepository.findAll(); userRepository.findOne(1l); userRepository.save(user);userRepository.delete(user); userRepository.count(); userRepository.exists(1l); ……}

7.自定义的简单查询就是根据方法名来自动生成SQL,主要的语法是`findXXBy,readAXXBy,queryXXBy,countXXBy, getXXBy`后面跟属性名称,举几个例子:

User findByUserName(String userName);User findByUserNameOrEmail(String username, String email);Long deleteById(Long id);Long countByUserName(String userName);List《User》 findByEmailLike(String email);User findByUserNameIgnoreCase(String userName);List《User》 findByUserNameOrderByEmailDesc(String email);

8.接下来,我们说下复杂的查询,在实际的开发中我们需要用到分页、删选、连表等查询的时候就需要特殊的方法或者自定义 SQL,以分页查询为例,分页查询在实际使用中非常普遍了,spring data jpa已经帮我们实现了分页的功能,在查询的方法中,需要传入参数Pageable,当查询中有多个参数的时候Pageable建议做为最后一个参数传入。Pageable是 spring 封装的分页实现类,使用的时候需要传入页数、每页条数和排序规则

Page《User》 findALL(Pageable pageable);Page《User》 findByUserName(String userName,Pageable pageable);

9.我们看下下面的测试用例

@TestpublicvoidtestPageQuery()throws Exception {int page=1,size=5; Sort sort = new Sort(Direction.DESC, “id”); Pageable pageable = new PageRequest(page, size, sort); userRepository.findALL(pageable);userRepository.findByUserName(“testName”, pageable);}

10. Spring data 大部分的 SQL 都可以根据方法名定义的方式来实现,但是由于某些原因我们想使用自定义的 SQL 来查询,spring data 也是完美支持的,如下所示:

@Modifying@Query(“update User u set u.userName = ?1 where c.id = ?2”)int modifyByIdAndUserId(String userName, Long id);@Transactional@Modifying@Query(“delete from User where id = ?1”)void deleteByUserId(Long id);@Transactional(timeout = 10)@Query(“select u from User u where u.emailAddress = ?1”)User findByEmailAddress(String emailAddress);

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • JAVA
    +关注

    关注

    19

    文章

    2903

    浏览量

    102978
  • spring
    +关注

    关注

    0

    文章

    332

    浏览量

    14153
  • JAVA开发
    +关注

    关注

    0

    文章

    12

    浏览量

    7523
收藏 人收藏

    评论

    相关推荐

    Spring事务失效的十种常见场景

    Spring针对Java Transaction API (JTA)、JDBC、Hibernate和Java Persistence API(JPA)等事务 API,实现了一致的编程模型
    的头像 发表于 12-11 15:03 498次阅读

    java spring教程

    java spring教程理解Spring 实现原理掌握Spring IOC,AOP掌握Spring的基础配置和用法熟练使用SSH开发项目Sprin
    发表于 09-11 11:09

    什么是java spring

    什么是java springSpring是个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成
    发表于 09-11 11:16

    如何用ACM简化你的Spring Cloud微服务环境配置管理

    摘要: 本文我们就如何使用阿里云ACM这样的配置管理产品在Spring Cloud中替代Spring Cloud Config帮助简化环境配置管理做个简单的示例,帮助你理解基于ACM来简化微服
    发表于 02-02 14:18

    使用阿里云ACM简化你的Spring Cloud微服务环境配置管理

    创建了个标准的jpa应用(类似Spring官网的样例工程 Accessing data with MySQL,我们的工程结构如下图所示:引入JPA、MySQL、连接池HikariCP
    发表于 07-04 17:16

    Spring框架的设计理念

    Spring作为现在最优秀的框架之,已被广泛的使用,51CTO也曾经针对Spring框架中的hqC应用做过报道。本文将从另外个视角试图剖析出Sp
    发表于 07-15 08:17

    JPA分页查询的常用方法

    JPA分页查询与条件分页查询
    发表于 10-23 17:10

    使用jpa和thymeleaf做增删改查示例

    【本人秃顶程序员】springboot专辑:springboot+jpa+thymeleaf增删改查示例
    发表于 04-01 11:49

    springboot spring data jpa使用总结

    【本人秃顶程序员】springboot专辑:spring data jpa的使用
    发表于 04-15 11:38

    解析Spring框架

    Spring框架详解 - 03
    发表于 06-17 17:15

    Spring认证_什么是Spring GraphQL

    Spring GraphQL 为构建在 GraphQL Java 上的 Spring 应用程序提供支持。两个团队之间的联合联合。我们的共同理念是少固执己见,更专注于全面和广泛的支持。 Spring
    的头像 发表于 08-06 14:30 511次阅读
    <b class='flag-5'>Spring</b>认证_什么是<b class='flag-5'>Spring</b> GraphQL

    Spring认证_什么是Spring GraphQL?

    Spring Data支持 QuerydslPredicateExecutor JPA、MongoDB和LDAP。 Spring GraphQL 存储库中的 webmvc-http 示例使
    的头像 发表于 08-09 11:31 461次阅读
    <b class='flag-5'>Spring</b>认证_什么是<b class='flag-5'>Spring</b> GraphQL?

    Spring认证_什么是Spring GraphQL?

    Spring Data支持 QuerydslPredicateExecutor JPA、MongoDB和LDAP。 Spring GraphQL 存储库中的 webmvc-http 示例使
    的头像 发表于 08-09 11:31 431次阅读
    <b class='flag-5'>Spring</b>认证_什么是<b class='flag-5'>Spring</b> GraphQL?

    使用JPA访问数据的过程

    本指南将引导您完成构建应用程序的过程,该应用程序使用#spring# #spring认证# Spring Data JPA 在关系数据库中存储和检索数据。
    的头像 发表于 09-06 15:48 483次阅读

    JPA基础概念

    相信大部分java小伙伴在日常开发过程中,在存储操作层都会选择更容易上手的jpa,各种封装,通过注解等方式,简化了大量的代码内容,同时提升了开发效率,但是(敲黑板,永远都躲不开的但是...)相应
    的头像 发表于 10-08 14:36 390次阅读
    <b class='flag-5'>JPA</b>基础概念