转载

使用Spring Data JPA访问MySQL

在数据访问这章的第一篇文章《Spring中运用JdbcTemplate访问数据库》中,我们现已介绍了怎么运用SpringBoot中最根本的jdbc模块来完结联络型数据库的数据读写操作。那么结合Web开发一章的内容,我们就能够利用JDBC模块与Web模块的功用,综合着运用来完结一个适用于许多简略运用场景的后端运用了。

然而当我们有必定的开发经验之后,不难发现,在实践开发过程中,对数据库的操作大多能够归结为:“增修改查”。就最为普遍的单表操作而言,除了表和字段不同外,句子简直都是相似的,开发人员需求写许多相似而单调的句子来完结业务逻辑。

为了处理这些许多单调的数据操作句子,诞生了非常多的优异结构,比方:Hibernate。经过整合Hibernate,我们能够以操作Java实体的方法来完结对数据的操作,经过结构的协助,对Java实体的改动最终将自动地映射到数据库表中。

在Hibernate的协助下,Java实体映射到数据库表数据完结之后,再进一步处理笼统各个Java实体根本的“增修改查”操作,我们通常会以泛型的方法封装一个模板Dao来进行笼统简化,但是这样依然不是很便利,我们需求针对每个实体编写一个承继自泛型模板Dao的接口,再编写该接口的完结。尽管一些基础的数据访问现已能够得到很好的复用,但是在代码结构上针对每个实体都会有一堆Dao的接口和完结。

因为模板Dao的完结,使得这些具体实体的Dao层现已变的非常“薄”,有一些具体实体的Dao完结或许彻底便是对模板Dao的简略代理,而且往往这样的完结类或许会呈现在许多实体上。SpringDataJPA的呈现正能够让这样一个现已很“薄”的数据访问层变成仅仅一层接口的编写方法。比方,下面的比方:Java

publicinterfaceUserRepositoryextendsJpaRepository<User,Long>{UserfindByName(Stringname);@Query(“fromUseruwhereu.name=:name”)UserfindUser(@Param(“name”)Stringname);

}

我们只需求经过编写一个承继自JpaRepository的接口就能完结数据访问,下面以一个具体实例来体验SpringDataJPA给我们带来的强壮功用。

运用过程

因为SpringDataJPA依赖于Hibernate。假如您对Hibernate有必定了解,下面内容能够毫不费力的看懂并上手运用它。假如您还是Hibernate新手,您能够先按如下方法入门,再建议回头学习一下Hibernate以协助这部分的理解和进一步运用。

工程配备

在pom.xml中增加相关依赖,加入以下内容:

<dependency<groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-data-jpaartifactId>dependency>

在application.xml中配备:数据库衔接信息(如运用嵌入式数据库则不需求)、自动创建表结构的设置,例如运用mysql的状况如下:

spring.datasource.url=jdbc:mysql://localhost:3306/testspring.datasource.username=root

spring.datasource.password=

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop

spring.jpa.properties.hibernate.hbm2ddl.auto是hibernate的配备特色,其首要作用是:自动创建、更新、验证数据库表结构。该参数的几种配备如下:

create:每次加载hibernate时都会删去上一次的生成的表,然后根据你的model类再从头来生成新表,哪怕两次没有任何改动也要这样履行,这便是导致数据库表数据丢失的一个重要原因。

create-drop:每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删去。

update:最常用的特色,第一次加载hibernate时根据model类会自动树立起表的结构(条件是先树立好数据库),今后加载hibernate时根据model类自动更新表结构,即便表结构改动了但表中的行仍然存在不会删去曾经的行。要注意的是当布置到服务器后,表结构是不会被马上树立起来的,是要等运用第一次运转起来后才会。

validate:每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会刺进新值。

至此现已完结基础配备,假如您有在Spring下整合运用过它的话,相信你现已感受到SpringBoot的便利之处:JPA的传统配备在persistence.xml文件中,但是这儿我们不需求。当然,最好在构建项目时分按照之条件过的最佳实践的工程结构来安排,这样以确保各种配备都能被结构扫描到。

创建实体

创建一个User实体,包含id(主键)、name(名字)、age(年纪)特色,经过ORM结构其会被映射到数据库表中,因为配备了hibernate.hbm2ddl.auto,在运用发动的时分结构会自动去数据库中创建对应的表。

@Entity@Data@NoArgsConstructorpublicclassUser{@Id@GeneratedValueprivateLongid;privateStringname;privateIntegerage;publicUser(Stringname,Integerage){this.name=name;this.age=age;

}

}

@Entity注解标识了User类是一个耐久化的实体

@Data和@NoArgsConstructor是Lombok中的注解。用来自动生成各参数的Set、Get函数以及不带参数的结构函数。假如您对Lombok还不了解,能够看看这篇文章:Java开发神器Lombok的运用与原理

@Id和@GeneratedValue用来标识User对应对应数据库表中的主键

注意:除了这些注解之外,还有许多用来精细化配备映射联络的注解,这儿不做具体介绍。后续会出专门一篇来介绍常用注解。读者也能够自行阅览Hibernate的文档来学习这些注解的具体运用方法。

创建数据访问接口

下面针对User实体创建对应的Repository接口完结对该实体的数据访问,如下代码:

publicinterfaceUserRepositoryextendsJpaRepository<User,Long>{UserfindByName(Stringname);UserfindByNameAndAge(Stringname,Integerage);@Query(“fromUseruwhereu.name=:name”)UserfindUser(@Param(“name”)Stringname);

}

在SpringDataJPA中,只需求编写相似上面这样的接口就可完结数据访问。不再像我们以往编写了接口时分还需求自己编写接口完结类,直接减少了我们的文件清单。

下面对上面的UserRepository做一些解释,该接口承继自JpaRepository,经过查看JpaRepository接口的API文档,能够看到该接口本身现已完结了创建(save)、更新(save)、删去(delete)、查询(findAll、findOne)等根本操作的函数,因此关于这些基础操作的数据访问就不需求开发者再自己定义。

在我们实践开发中,JpaRepository接口定义的接口往往还不行或许功能不行优化,我们需求进一步完结更杂乱一些的查询或操作。因为本文重点在SpringBoot中整合spring-data-jpa,在这儿先抛砖引玉简略介绍一下spring-data-jpa中让我们兴奋的功用,后续再单独开篇讲一下spring-data-jpa中的常见运用。

在上例中,我们能够看到下面两个函数:

UserfindByName(Stringname)

UserfindByNameAndAge(Stringname,Integerage)

它们分别完结了按name查询User实体和按name和age查询User实体,能够看到我们这儿没有任何类SQL句子就完结了两个条件查询方法。这便是Spring-data-jpa的一大特性:经过解析方法名创建查询。

除了经过解析方法名来创建查询外,它也提供经过运用@Query注解来创建查询,您只需求编写JPQL句子,并经过相似“:name”来映射@Param指定的参数,就像比方中的第三个findUser函数相同。

SpringDataJPA的能力远不止本文说到的这些,因为本文首要以整合介绍为主,关于SpringDataJPA的运用仅仅介绍了常见的运用方法。比方@Modifying操作、分页排序、原生SQL支持以及与SpringMVC的结合运用等等内容就不在本文中具体打开,这儿先挖个坑,后续再补文章填坑,如您对这些感兴趣能够重视我博客或简书,同样欢迎大家留言沟通想法。

单元测验

在完结了上面的数据访问接口之后,按照常规便是编写对应的单元测验来验证编写的内容是否正确。这儿就不多做介绍,首要经过数据操作和查询来反复验证操作的正确性。

@RunWith(SpringRunner.class)@SpringBootTestpublicclassApplicationTests{@AutowiredprivateUserRepositoryuserRepository;@Testpublicvoidtest()throwsException{//创建10条记载userRepository.save(newUser(“AAA”,10));

userRepository.save(newUser(“BBB”,20));

userRepository.save(newUser(“CCC”,30));

userRepository.save(newUser(“DDD”,40));

userRepository.save(newUser(“EEE”,50));

userRepository.save(newUser(“FFF”,60));

userRepository.save(newUser(“GGG”,70));

userRepository.save(newUser(“HHH”,80));

userRepository.save(newUser(“III”,90));

userRepository.save(newUser(“JJJ”,100));//测验findAll,查询一切记载Assert.assertEquals(10,userRepository.findAll().size());//测验findByName,查询名字为FFF的UserAssert.assertEquals(60,userRepository.findByName(“FFF”).getAge().longValue());//测验findUser,查询名字为FFF的UserAssert.assertEquals(60,userRepository.findUser(“FFF”).getAge().longValue());//测验findByNameAndAge,查询名字为FFF而且年纪为60的UserAssert.assertEquals(“FFF”,userRepository.findByNameAndAge(“FFF”,60).getName());//测验删去名字为AAA的UseruserRepository.delete(userRepository.findByName(“AAA”));//测验findAll,查询一切记载,验证上面的删去是否成功Assert.assertEquals(9,userRepository.findAll().size());

}

}

拓宽阅览:关于SpringData

SpringDataJPA在Spring家族中实践上是一个二级项目,它隶属于SpringData这个尖端项目。读者能够看一下关于这个项目的介绍,它除了涵盖对联络型数据库的笼统之外,其实还有许多对其他数据存储中间件的完结,比方我们常用的Redis、MongoDB、Elasticsearch等。

假如再找几个项目看一下它们的简略示例,你会发现:不管你是要访问什么数据存储产品,它们的编码方法简直都是相同的!这便是SpringData这个项目充满魅力的地方!经过对数据访问操作的笼统来屏蔽细节,用不同子项目的方法去完结细节。让开发者只需求学会运用SpringData,就能便利方便的学会对各种数据存储的操作。所以,关于SpringData,我是强烈推荐Java开发者们能够学、甚至读一下源码的重要结构。尽管,现在来说许多大型互联网公司并不会选择它(功能考量居多,能真正用好它的人不多)作为首要的开发结构,但是其背后的笼统思想对错常值得我们学习的。而且,在做一些非高并发项目的时分,这简直便是一个方便开发神器,它能够协助我们少写非常多的代码!

原文  https://segmentfault.com/a/1190000023160155
正文到此结束
Loading...