SpringBoot开发详解(十) -- 使用JPA访问数据库下篇及使用Page进行数据分页

原文链接:http://blog.csdn.net/qq_31001665

如有侵权,请联系博主删除博客,谢谢

JPA调用EntityManageer实现

JPA调用EntityManageer:

我们在上篇中使用过JPA其中一种方案来访问数据库,就是继承JpaRepository接口,今天我们使用另一种方案来实现JPA的访问数据库。所需要引用的依赖和上篇是一致的,包括实体类的创建在这就不写第二遍了,我们直接看DAO层如何实现.

首先,我们先写一个接口定义查询方法:

public interface JpaEntity {

    List<Address> findAll();

    Address findAddress(Long addressId);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

然后我们再写一个实现类来实现这个接口:

@Repository
public class JpaEntityImpl implements JpaEntity {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<Address> findAll() {
        return this.entityManager.createQuery("select t from Address t",Address.class)
                .getResultList();
    }

    @Override
    public Address findAddress(Long addressId) {
        return this.entityManager.createQuery("select t from Address t where t.addressId = ?",Address.class)
                .setParameter(1,addressId)
                .getSingleResult();
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

之后我们先给实体类重写toString方法,便于后面结果的查看:

    @Override
    public String toString() {
        return "Address{" +
                "addressId=" + addressId +
                ", userId=" + userId +
                ", addressInfo='" + addressInfo + '\'' +
                '}';
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

然后我们依旧通过单元测试来验证刚才写的代码的通过性:

@RunWith(SpringRunner.class)
@SpringBootTest
public class JpaEntityImplTest {

    @Autowired
    private JpaEntityImpl jpaEntity;

    @Test
    public void findAll() throws Exception {

        List<Address> list = jpaEntity.findAll();
        System.out.println(list.size());
        for (Address address : list){
            System.out.println(address.toString());
        }
    }

    @Test
    public void findAddress() throws Exception {
        Address address = jpaEntity.findAddress(Long.valueOf(9));
        System.out.println(address.toString());
    }

}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

通过测试大家可以看到,我们通过EntityManager访问数据库也是没问题的。

这里写图片描述

这里写图片描述

大家通过控制台的输出可以看到,其实hibernate在查询数据库时,会自动生成所需要查询的SQL语句。

JPA分页实现

JPA使用Page实现分页: 
不知道大家之前实现分页是如何实现的,一般的思路有两种,一个是数据库控制,也就是通过SQL语句,像Mysql的limit啊,SQLserver的Top啊(oracle的分页太复杂不举例了……),还有就是通过代码实现,一般我平时的话会使用PageHelper来实现。当然在SpringBoot中PageHelper也是支持的。

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>4.0.0</version>
</dependency>

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.1.0</version>
</dependency>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

不过其实SpringBoot已经有了一个比较强大的分页插件,就是Page,那让我们看看Page在JPA中是如何使用的。 
首先,我们在继承JpaRepository写一个findAllAddress方法,传入参数为Pageable,而返回不再是List,而是Page。

Page<Address> findAllAddress(Pageable pageable);
 
 
  • 1

这里Pageable是指需要传入的分页信息,而Page则是分页后的数据内容。我们继续使用测试用例来测试我们的代码。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Round1Application.class)
public class AddressRepositoryTest {

    @Autowired
    private AddressRepository addressRepository;

    @Test
    public void findAllAddress() throws Exception {

        int page = 0,size = 10;
        Sort sort = new Sort(Sort.Direction.DESC,"addressId");
        Pageable pageable = new PageRequest(page,size,sort);
        Page<Address> a = findAllAddress(pageable);
        System.out.println(a.getTotalPages());
        System.out.println(a.getTotalElements());
        List<Address> aa = a.getContent();
        for (Address u : aa){
            System.out.println(u.toString());
        }
    }

}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

这里我们使用Sort来定义根据那一个字段进行排序,起始页一定要注意是从0开始的,而不是从1开始,我们规定每页包含10条内容,为了方便测试,我们在数据库中再加入一些内容:

这里写图片描述

好了,我们开始测试我们的代码,发现竟然报错了!!

这里写图片描述

我们写错什么了呢?看似我们什么也没写错,其实,使用Page来分页在JPA中是有严格的方法名匹配的,如果像这里我们想获得所有数据信息,就必须使用findAll()来作为方法名。我们把之前写的findAll()给注释了,并且将findAllAddress方法改为findAll后再进行测试,法相已经可以通过了,并且分页也为我们按照10条一页进行了划分。

这里写图片描述

以上就是使用JPA的分页进行数据分页,其实不得不说,JPA其实是一个比较大的坑,如果不是熟练使用的话,很容易犯错,而且各种错都比较难以排查,比如这种命名规范的错误。所以大家如果使用分页的话,还是暂时先继续PageHelper吧,希望Spring之后能将Page封装的更为完美和易用。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值