Spring Boot 之数据访问:JPA

本文介绍了Spring Boot中JPA的概念、由来,解释了JPA作为Java持久化规范的目标,并探讨了Spring Data JPA如何简化数据库访问。通过快速上手教程,展示了从配置、实体类创建到Repository的使用,以及核心功能如基本操作和复杂查询的实现,包括自定义查询和分页查询。
摘要由CSDN通过智能技术生成

相关概念

JPA由来

主要的原因是:其一,简化现有Java EE 和 Java SE 应用开发工作,其二,Sun希望整合ORM技术,实现统一的API调用接口。

JPA是什么?

JPA(Java Persistence API)是Sun 官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。它的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现有Hibernate、TopLink、JDO等ORM框架各自为营的局面。
注意:JPA是一套规范,不是一套产品,那么像Hibernate、TopLink、JDO它们是一套产品,如果说这些产品实现了这个JPA规范,那么我们就可以称他们为JPA的实现产品,其实就相当于JPA与Habernate这些产品的关系,就类似于类与对象的关系

Spring Data JPA

Spring Data是Spring的一个子项目,同于简化数据库访问,包括NoSQL非关系型数据库,另外还包括对关系型数据库的访问支持。SpringData使我们可以快速地使用简单地使用普通的数据访问技术及新的数据访问技术,Spring Data会让数据的访问变得更加方便。
Spring Data 让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它的实现。

快速上手

1.数据库表
先准备好一个User表
数据库中的User表
2.创建项目
这篇就不详细讲了,在上一篇博客中可以查看如何详细快速创建Spring Boot项目上篇博客传送门
但是要记得添加相关的依赖(Spring Data JPA , MySQL Driver)
项目需要的相关依赖
项目pom.xml文件如下:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.18</version>
</dependency>

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
</dependency>

3.application.properties添加配置信息

#配置数据源相关信息
#MySQL5.x版本的驱动
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/crm?useUnicode=true&characterEncoding=utf-8

#配置JPA相关信息
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

4.编写实体类:User.java

@Data
@Entity
@Table(name="sys_user")
public class User implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "usr_id")
    private Long usrId;
    @Column(name="usr_name")
    private String usrName;
    @Column(name="usr_password")
    private String usrPassword;
    @Column(name="usr_role_id")
    private Long usrRoleId;
    @Column(name="usr_flag")
    private Integer usrFlag;
}

注解描述
JPA注解详细说明如下:

  • @Entity(name=“EntityName”)必须,用来标注一个数据库表对应的实体,数据库中创建的表明默认和类名一致,其中,name可选,对应数据库中的一个表,使用此注解标记Pojo是一个JPA实体。
  • @Table(name="",catalog="",schema="")可选,用来标注一个数据库对应的实体类,数据库中创建的表明默认和类名一致,通常和@Entity配合使用,只能标注在实体的class定义处,表示实体对应的数据库表的信息
  • @Id必须,@Id定义了映射到据库表的主键的属性,一个实体只能有一个属性被映射为主键。

4.编写Repository(仓库)
创建UserRository.java

public interface UserRepository extends JpaRepository<User,Long>{
}

5.编写测试

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

   @Resource
   private UserRepository userRepository;
   
 @Test
   public void testInsert(){//测试新增
      User user=new User();
      user.setUsrName("哇哈哈哈哈哈hh");
      user.setUsrPassword("123456");
      userRepository.save(user);
      Assert.assertNotNull(user);
   }

   @Test
   public void testGet(){//测试按主键查询
      User user=userRepository.findById(2L).get();
      System.out.println("userName:"+user.getUsrName());
   }
}

核心功能

基本操作

我们可以将Spring Data JPA基本操作分为两种,一种是Spring Data JPA 默认实现的,另一种是需要根据查询的情况来自行构建。
1.预生成方法
在这里插入图片描述
2.自定义查询
Spring Data JPA 还可以根据接口方法来实现数据库操作,主要的语法是findXXBy、queryXXBy、countXXBy、getXXBy后面跟属性名称,利用这个功能仅需要在定义的Repository中添加对应的方法名即可,使用时Spring Boot会自动帮我们实现。
根据用户名查询用户:

public List<User> findByUsrName(String usrName);

基本上SQL体系中的关键字都可以使用,如Like、IgnoreCase、OrderBy:

public List<User> findByUsrNameLike(String usrName);

编写测试方法:

@Test
public void testFindByUerNameLike(){//自定义QL查询
    List<User> userList=userRepository.findByUsrNameLike("%哈%");
    userList.forEach(u-> System.out.println(u));
}

在这里插入图片描述

复杂操作

1.自定义QL查询
在Repository的查询方法上面使用@Query注解,在注解内写HQL来查询内容。

/*@Query("select u from User u where u.usrRoleId=?1")
public List<User> findByRoleId(Long roleId);*/

/*@Query(value="select * from sys_user where usr_role=?1",nativeQuery = true)
public List<User> findByRoleId(Long roleId);*/

@Query("select u from User u where u.usrRoleId=:roleId")
public List<User> findByRoleId(@Param("roleId") Long roleId);

@Transactional(timeout = 10)
@Modifying
@Query("update User u set u.usrName=?1 where u.usrId=?2")
public int modifyNameById(String usrName,Long usrId);

2.分页查询

@Test
public void testFindPageByUsrRoleId(){//简单分页查询
   int page=0,size=2;
   Sort sort=new Sort(Sort.Direction.DESC,"usrId");

   Pageable pageable= PageRequest.of(page,size,sort);
   Page<User> userPage=userRepository.findPageBuUsrRoleId(1L,pageable);

   userPage.forEach(user -> System.out.println(user));
}

3.复杂查询
定义UserRepository接口及实现类

public interface UserService {
    public Page<User> findPageByMap(Map param, Pageable pageable);
}

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserRepository userRepository;

    @Override
    public Page<User> findPageByMap(Map param, Pageable pageable) {
        return userRepository.findAll(new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if (param.get("usrName") != null) {
                    predicates.add(criteriaBuilder.like(root.get("usrName"), "%" + param.get("usrName") + "%"));
                }
                if (param.get("roleId") != null) {
                    predicates.add(criteriaBuilder.equal(root.get("usrRoleId"), param.get("roleId")));
                }
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
            }, pageable);
    }
}

测试类:

@Test
public void testFindPageByMap(){//复杂分页查询
   int page=0,size=2;
   Sort sort=new Sort(Sort.Direction.DESC,"usrId");

   Pageable pageable= PageRequest.of(page,size,sort);
   Map param=new HashMap();
   param.put("roleId",1L);
   Page<User> userPage=userService.findPageByMap(param,pageable);

   userPage.forEach(user -> System.out.println(user));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值