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

更优雅的访问数据库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)
@SpringBootTest
public 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

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值