SpringBoot开发详解(九) -- 使用JPA访问数据库上篇

来源:互联网 发布:经典名著改编电影知乎 编辑:程序博客网 时间:2024/05/29 17:32

更优雅的访问数据库JPA

JPA访问数据库的优点:

通常我们访问数据库归根结底无非就是增删改查,作为开发人员,我们会写大量的SQL,而这些SQL有大多是重复且枯燥的。无非就是库名,表名的不同。为了提高开发效率,我们通常会使用ORM框架,而其中最著名的就是Hibernate。

Hibernate以对象编程闻名,抛弃了面向过程的SQL语言,以类为对象作为查询的依据。并且以HQL语言作为辅助,大大简化了我们编写SQL的难度,将我们从无穷无尽的SQL编写中解放了出来。在SpringBoot中,我们使用JPA来访问数据库,JPA依赖于Hibernate,如果你熟悉Hibernate,那JPA你能够很快上手。如果你不了解Hibernate,那可能你的学习周期稍长。不过没关系,希望我的这篇文章能快速的带你使用JPA。

首先,我们需要引入JPA的依赖,请在pom.xml中添加JPA依赖:

<!--jpa依赖,问问数据库ORM框架--><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-data-jpa</artifactId></dependency>

之后我们在application.xml中添加下配置:

spring:  datasource:    url: jdbc:mysql://localhost:3306/blog    username: root    password: 123    driver-class-name: com.mysql.jdbc.Driver    type: com.alibaba.druid.pool.DruidDataSource  jpa:    properties:      hibernate:        hbm2ddl:          auto: update        dialect: org.hibernate.dialect.MySQL5InnoDBDialect    show-sql: true

其中hbm2ddl.auto是对于数据库表结构的配置,一般有四种配置:

  • create:每次加载hibernate都会建一次表,不推荐使用,会丢失表数据。
  • create-drop:每次加载建立表,当SessionFactory关闭则自动删除。
  • update:第一次会自动创建表,之后只更新数据。即使之后表结构改变,也不会删除之前的数据。也是我们最常用的一种属性。
  • valiate:验证数据库中的表进行比较,不创建新表,只插入新值。

接下来我们可以创建我们的实体类了,这里我创建了一个地址类Address:

@Entity@Table(name = "tp_address")public class Address {    @Id    @GeneratedValue(strategy = GenerationType.AUTO)    private Long addressId;    @Column(name = "user_id",nullable = false)    private Long userId;    @Column(name = "add_info",nullable = false)    private String addressInfo;    /** 省略set get方法以及构造器 */}

我们可以使用@Table来指定表的一些属性,这里我设定了表名。
使用@Id来指明主键,@GeneratedValue来设定自增长。
使用@Column可以设定列的属性,包括非空,名称,唯一,默认值等等。

接下来我们创建一个接口实现JpaRepository或者调用entitymanage的类方法,这一篇我先实现第一种方法来给大家演示,下一篇我们再说后一种方法。

public interface AddressRepository extends JpaRepository<Address,Long> {    List<Address> findByUserId(Long userId);    Address findByAddressIdAndUserId(Long addressId,Long userId);    @Query(value = "select  t from Address t where t.addressInfo = :addressInfo")    Address findAddress(@Param("addressInfo") String addressInfo);}

其中,JPA已经把我们常用的一些增(save),删(delete),改(update),查(find)已经做了一定的封装,我们直接拿来使用就可以了。
其次,我们一可以通过解析方法名创建查询,例如我代码中的第一第二个方法一样,这样就不需要我们添加任何SQL语句。
最后,我们还可以通过@Query来添加注解查询,要注意的是,这里语句并不是SQL语句,而是JPQL语句,如同HQL,代码中Address指的是Address这个类
另外,参数重@param请一定使用org.springframework.data.jpa.repository.Query,千万别引入ibatis的注解哦。

完成这些,我们的数据库编写其实已经结束了,我们使用测试用例来验证下我们的代码是否可用(也可以写完controller,service后使用postman,我是太懒了,哈哈哈(^-^))。

@RunWith(SpringRunner.class)@SpringBootTestpublic class Round1ApplicationTests {    @Test    public void contextLoads() {    }    @Autowired    private AddressRepository addressRepository;    @Test    public void jpaTest() throws Exception{//      插入10条记录        addressRepository.save(new Address(Long.valueOf(3),"SH"));        addressRepository.save(new Address(Long.valueOf(4),"XA"));        addressRepository.save(new Address(Long.valueOf(5),"BJ"));        addressRepository.save(new Address(Long.valueOf(6),"GZ"));        addressRepository.save(new Address(Long.valueOf(7),"WX"));        addressRepository.save(new Address(Long.valueOf(14),"NC"));        addressRepository.save(new Address(Long.valueOf(15),"HLJ"));        addressRepository.save(new Address(Long.valueOf(15),"XJ"));        addressRepository.save(new Address(Long.valueOf(15),"DL"));        addressRepository.save(new Address(Long.valueOf(16),"M78"));//      测试查询所有记录        Assert.assertEquals(10,addressRepository.findAll().size());//      测试查询UserId为7,addressID为5的记录是不是WX        Assert.assertEquals("WX",addressRepository.findByAddressIdAndUserId(Long.valueOf(5),Long.valueOf(7)).getAddressInfo());//      测试查询15号用户是否是三条记录        Assert.assertEquals(3,addressRepository.findByUserId(Long.valueOf(15)).size());//      测试查询SH内容用户是不是3号用户        Assert.assertEquals(3,addressRepository.findAddress("SH").getUserId().longValue());//      测试删除内容是M78的记录        addressRepository.delete(addressRepository.findAddress("M78"));//      测试查询记录,看删除是否成功        Assert.assertEquals(9,addressRepository.findAll().size());    }}

测试结果通过,并且数据库中建立了tp_address表。

这里写图片描述

这里写图片描述

我们可以看到我们之前配置的打印SQL也已经生效了。

今天的文章就写到这,我要去吃粽子了,下一篇我们来探讨下使用entitymanage的类方法完成JPA的工作,还有JPA中如何分页的问题。这次应该不用等一周的时间了,也希望大家对比下,看看使用Mybatis和JPA哪一种更好呢?

以上所有的代码我已经上传到GitHub

round1-springboot

如果心急的小伙伴也可以去clone我已经完成的项目,这个项目中把一些常用功能都写了,并且都写注释啦!!!

MySpringBoot

原创粉丝点击