springboot集成jpa

一、搭建jpa环境

1、首先引入jpa的依赖包

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

2、配置数据库及jpa

spring:
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
  datasource:
    username: root
    password: beishang886
    url: jdbc:mysql://localhost:3306/jpa
    driver-class-name: com.mysql.cj.jdbc.Driver

3、创建简单实体类

package cn.wh.springjpaTest.entity;


import lombok.Data;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Data
@Entity(name = "t_user")
public class User {

    @Id   // 表明id
    @GeneratedValue   //  自动生成
    private Integer userId;
    private String userName;
    @Column(name = "password")
    private String passwd;
    private String role;
}

解释:

@Data:是lombak携带的升生成getset等方法。
@Entity:标识是个实体类,如果不用指定名字,则默认跟类名一样。
@Id :该表主键
@GeneratedValue:自增长
@Column(name = "password"):列名映射,如果名称一样则可以不写。

启动springboot项目后可以看到日志创建了序列当做自增并且列名一一对应。

 

 

 到数据库查看,可以看到不是我们想要的那种MySQL自动增长模式。

所以在id主键后面添加

strategy= GenerationType.IDENTITY

GenerationType的四种类型

TABLE:使用一个特定的数据库表格来保存主键。 
SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。 
IDENTITY:主键由数据库自动生成(主要是自动增长型) 
AUTO:主键由程序控制。

删除之前生成的表,重新启动代码,可以看到日志只创建了表而没创建序列。

 

 

 到数据库查看,使我们想要的那种MySQL自动增长。

 

 

 

 

二、初试JPA

1、创建userDao

创建userDao并集成JpaRepository接口

 

 该接口已经实现了很多常用的方法,我们可以直接调取使用

 

 

 

 

2、创建Service以及创建Controller进行调用

我现在写了两个方法,一个查询一个添加

@RequestMapping("/findAll")
    private List<User> findAll(){
        return userService.findAll();
    }
    @RequestMapping("/save")
    private User save(User user){
        return userService.save(user);
    }

 

3、测试调用

先进行保存调用,然后查询

 

 

 

 测试完成。成功调用

四、Jpa提供的四个接口

1、Repository接口
2、CrudRepository接口
3、PagingAndSortingRepository接口
4、JpaRepository接口
5、JPASpecificationExecutor接口

上面我们使用的第四个,现在依次使用

1、Repository 

 

 可以看到该接口没有方法。所以我们要在userDao中写需要的抽象方法

改造后的UserDao如下:

package cn.wh.springjpaTest.dao;

import cn.wh.springjpaTest.entity.User;
import org.springframework.data.repository.Repository;


public interface UserDao extends Repository<User,Integer> {

    User findAllByUserName(String userName);

    User findUserByRoleAndUserName(String role,String userName);
}

去测试类里面测试结果如下:

 

 2、CrudRepository

可以看到该接口继承了Repository,主要是一些增删操作

 

 测试如下:

 

 

3、PagingAndSortingRepository

该接口继承了CrudRepository接口,主要用于分页和排序,如下图所示:

 

 测试如下:

 

 

 测试如上,至于为什么page.getContent 未定位出来。如果有知道原因的,麻烦说下

4、JpaRepository

这个接口也是上面使用过的接口,该接口继承了PagingAndSortingRepository。对继承的父接口中方法的返回值进行适配。

 依次继承关系:   

JpaRepository --> PagingAndSortingRepository  -->  CrudRepository  -->  Repository

相当于该接口包含上面所有的。

此处不再演示。

5、JpaSpecificationExecutor

该接口是独立存在的,跟其他四个接口没有联系,该接口主要是提供了多条件查询的支持,并且可以在查询中添加排序与分页。

 

 

 

 

 然后测试类进行调用:

5.1 单条件查询

Specification<User> specification = new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root,
                                         CriteriaQuery<?> criteriaQuery,
                                         CriteriaBuilder criteriaBuilder) {
                return criteriaBuilder.equal(root.get("role"),"admin");
            }
        };
        System.out.println(userDao.findAll(specification));

 

 

 

 

 5.2 多条件查询如下

多条件查询一、

Specification<User> specification = new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root,
                                         CriteriaQuery<?> criteriaQuery,
                                         CriteriaBuilder criteriaBuilder) {
                // role=admin  or (user_name=wanghao and role=user )
                return criteriaBuilder.or(criteriaBuilder.equal(root.get("role"),"admin"),
                        criteriaBuilder.and(criteriaBuilder.equal(root.get("userName"),"王浩"),criteriaBuilder.equal(root.get("role"),"user")));
            }
        };
        System.out.println(userDao.findAll(specification));

 

多条件查询二、

Specification<User> specification = new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root,
                                         CriteriaQuery<?> criteriaQuery,
                                         CriteriaBuilder criteriaBuilder) {
                List<Predicate> list=new ArrayList<>();
                list.add(criteriaBuilder.equal(root.get("userName"),"王浩"));
                list.add(criteriaBuilder.equal(root.get("role"),"admin"));
                Predicate[] arr=new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(arr));
            }
        };
        System.out.println(userDao.findAll(specification));

 

 

 备注(未测试):

方法名sql中的符号
between between and
equal =
gt >
ge <
lt  
le  
like like

-eq :equal(相等)
-ne :not equal(不等)
-gt :greater than(大于)
-ge :greater than or equal(大于或等于)
-lt :less than(小于)
-le :less than or equal(小于或等于)

 

 五、jpa多表查询

1、Hibernate注解实现多表查询

1.2 多对一查询 

使用注解:@ManyToOne

属性 必须 说明
cascade  


默认值:CascadeType 的空数组。

默认情况下,JPA 不会将任何持续性操作层叠到关联的目标。

如果希望某些或所有持续性操作层叠到关联的目标,请将 cascade 设置为一个或多个 CascadeType 实例,其中包括:

· ALL — 针对拥有实体执行的任何持续性操作均层叠到关联的目标。

· MERGE — 如果合并了拥有实体,则将 merge 层叠到关联的目标。

· PERSIST — 如果持久保存拥有实体,则将 persist 层叠到关联的目标。

· REFRESH — 如果刷新了拥有实体,则 refresh 为关联的层叠目标。

· REMOVE — 如果删除了拥有实体,则还删除关联的目标。

fetch  

默认值:FetchType.EAGER。

默认情况下,JPA 持续性提供程序使用获取类型 EAGER:这将要求持续性提供程序运行时必须迫切获取数据。

如果这不适合于应用程序或特定的持久字段,请将 fetch 设置为 FetchType.LAZY:这将提示持续性提供程序在首次访问数据(如果可以)时应不急于获取数据。

optional  

默认值:true。

默认情况下,JPA 持续性提供程序假设所有(非基元)字段和属性的值可以为空。

如果这并不适合于您的应用程序,请将 optional 设置为 false。

targetEntity  

默认值:JPA 持续性提供程序从被引用的对象类型推断出关联的目标实体

如果持续性提供程序无法推断出目标实体的类型,则将关联拥有方上的 targetEntity 元素设置为作为关系目标的实体的 Class。

 

备注:optional=true 相当于 left join 允许返回NULL, optional=false 相当于 inner join

 摘自:https://blog.csdn.net/qq_34042441/article/details/80281654 表格

下面一个测试案例,现在有用户和角色两张表。一个用户对应一个觉得,一个角色对应多个用户

首先编写Role角色实体了:

package cn.wh.springjpaTest.entity;


import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Data
@Entity(name = "t_role")
public class Role {


    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer Id;
    private String name;

}

然后编写dao

package cn.wh.springjpaTest.dao;

import cn.wh.springjpaTest.entity.Role;
import cn.wh.springjpaTest.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;


public interface RoleDao extends JpaRepository<Role,Integer>,JpaSpecificationExecutor<Role> {


}

 

 

 

 

 

 

 

 

 

参考:https://blog.csdn.net/qq_39086296/article/details/90485645
https://blog.csdn.net/qq_34042441/article/details/80281654
posted @ 2020-06-08 08:54  苦心明  阅读(785)  评论(0)    收藏  举报