Spring Data JPA 知识点总结

Spring Data JPA 知识点总结

使用Spring Data JPA时,我们需要继承至JpaRepository
继承之后,可以写HQL或者通过方法名自动生成SQL语句

方法名自动生成SQL 规则

生成SQL语句时JPA中的常用关键字

And --- 等价于 SQL 中的 and 关键字,
比如 findByUsernameAndPassword(String user, String pwd);

Or --- 等价于 SQL 中的 or 关键字,
比如 findByUsernameOrAddress(String user, String addr);

Between --- 等价于 SQL 中的 between 关键字,
比如 findBySalaryBetween(int max, int min);

LessThan --- 等价于 SQL 中的 "<",
比如 findBySalaryLessThan(int max);

GreaterThan --- 等价于 SQL 中的">",
比如 findBySalaryGreaterThan(int min);

IsNull --- 等价于 SQL 中的 "is null",比如 findByUsernameIsNull();

IsNotNull --- 等价于 SQL 中的 "is not null",
比如findByUsernameIsNotNull();

NotNull --- 与 IsNotNull 等价;

Like --- 等价于 SQL 中的 "like",
比如 findByUsernameLike(String user);

NotLike --- 等价于 SQL 中的 "not like",
比如 findByUsernameNotLike(String user);

OrderBy --- 等价于 SQL 中的 "order by",
比如 findByUsernameOrderBySalaryAsc(String user);

Not --- 等价于 SQL 中的 "! =",
比如 findByUsernameNot(String user);

In --- 等价于 SQL 中的 "in",
比如 findByUsernameIn(Collection userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;

NotIn --- 等价于 SQL 中的 "not in",
比如 findByUsernameNotIn(Collection st) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;

JPA 常用注解

基本注解

@Entity
@Table:映射数据表的表名
@Id: 映射主键
@GeneratedValue: 指定生成主键的策略
@Basic: 基本注解,默认的
@Column: 显式指定表的字段名和字段长度

@Transient: 不需要映射为数据表的一列
@Temporal: 指定Date类型的精度

主键生成策略

1.根据某张表来生成主键
2.根据数据库自增机制
3.自定义

父类注解

@EmbeddedId
使复合主键类成为由实体拥有的嵌入类
使用 @EmbeddedId 批注指定一个由实体拥有的可嵌入复合主键类(通常由两个或更多基元类型或 JDK 对象类型组成)。从原有数据库映射时(此时数据库键由多列组成),通常将出现复合主键。
@idClass
使复合主键类成为非嵌入类,使用 @IdClass 批注为实体指定一个复合主键类(通常由两个或更多基元类型或 JDK 对象类型组成)。从原有数据库映射时(此时数据库键由多列组成),通常将出现复合主键。
@MappedSuperclass
这个注解表示在父类上面的,用来标识父类。
基于代码复用和模型分离的思想,在项目开发中使用JPA的@MappedSuperclass注解将实体类的多个属性分别封装到不同的非实体类中。例如,数据库表中都需要id来表示编号,id是这些映射实体类的通用的属性,交给jpa统一生成主键id编号,那么使用一个父类来封装这些通用属性,并用@MappedSuperclas标识。
注意:
1.标注为@MappedSuperclass的类将不是一个完整的实体类,他将不会映射到数据库表,但是他的属性都将映射到其子类的数据库字段中。
2.标注为@MappedSuperclass的类不能再标注@Entity或@Table注解,也无需实现序列化接口。

复合主键

复合主键类具有下列特征:

  • 它是一个普通的旧式 Java 对象 (POJO) 类。
  • 它必须为 public,并且必须有一个 public 无参数构造函数。
  • 如果使用基于属性的访问,则主键类的属性必须为 public 或 protected。
  • 它必须是可序列化的。
  • 它必须定义 equals 和 hashCode 方法。这些方法的值相等性的语义必须与键映射到的数据库类型的数据库相等性一致。
动态SQL

@DynamicInsert
属性:设置为true,设置为true,表示insert对象的时候,生成动态的insert语句,如果这个字段的值是null就不会加入到insert语句当中.默认false。
比如希望数据库插入日期或时间戳字段时,在对象字段为空的情况下,表字段能自动填写当前的sysdate。
@DynamicUpdate
属性:设置为true,设置为true,表示update对象的时候,生成动态的update语句,如果这个字段的值是null就不会被加入到update语句中,默认false。

乐观锁

@Version
 JPA提供的乐观锁,指定实体中的字段或属性作为乐观锁的version,该version用于确保并发操作的正确性。每个实体只能使用一个version属性或字段。version支持(int, Integer, short, Short, long, Long, java.sql.Timestamp)类型的属性或字段。

@Access(AccessType.FIELD)

https://www.logicbig.com/tutorials/java-ee-tutorial/jpa/access-type.html
AccessType.FIELD 通过字段来获取或设置实体的状态,getter和setter方法可能存在或不存在
AccessType.PROPERTY 持久化属性必须有getter和setter方法,属性的类型由getter方法的返回类型决定,同时必须与传递到setter方法的单个参数的类型相同。

EntityManager

EntityManager的四个方法

EntityManager#find
EntityManager#getReference lazy load
EntityManager#persist
EntityManager#remove

对象的四种状态

EntityManager#merge
1.传入临时对象,创建一个新的对象,将临时对象的属性复制到临时对象中去,进行insert 操作
2.传入游离对象,判断缓存中和数据库中有没有,执行对应操作

EntityManager#flush
EntityManager#refresh

JpaRepository 复杂查询

  1. 使用EntityManager
    EntityManager#createQuery
    EntityManager#createNamedQuery
    EntityManager#createNativeQuery

order by / group by
关联查询
子查询
JPQL支持一些字符串处理函数、算术函数、日期函数

2.继承接口 JpaSpecificationExecutor

JpaSpecificationExecutor方法列表
Optional<T> findOne(@Nullable Specification<T> var1);
List<T> findAll(@Nullable Specification<T> var1);
Page<T> findAll(@Nullable Specification<T> var1, Pageable var2);
List<T> findAll(@Nullable Specification<T> var1, Sort var2);
long count(@Nullable Specification<T> var1);
JpaSpecificationExecutor的详细使用案例
//定义实体类
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table(schema = "test",name = "biz_dept")
public class BizDept implements Serializable {
    private static final long serialVersionUID = 1556429047277146957L;
    @Id
    @Column(name = "dept_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer deptId;

    @Column(name = "dept_name")
    private String deptName;

    @Column(name = "description")
    private String description;

    @Column(name = "create_date")
    private LocalDateTime createDate;

    @Column(name = "create_by")
    private Integer createBy;

    @Column(name = "delete_date")
    private LocalDateTime deleteDate;

    @Column(name = "delete_by")
    private Integer deleteBy;
}

//自定义Repository
public interface BizDeptRepository extends JpaRepository<BizDept, Integer>, JpaSpecificationExecutor<BizDept> {
}

//测试Specification查询方法
@SpringBootTest
@RunWith(SpringRunner.class)
public class JpaRepositoryTest {
    private static final Logger LOGGER = LoggerFactory.getLogger(JpaRepositoryTest.class);
    @Autowired
    private BizDeptRepository bizDeptRepository;

    @Test
    public void testDeptIdIn() {
        List<Integer> ids = Arrays.asList(9, 5, 2, 7);
        List<BizDept> list = bizDeptRepository.findAll((Specification<BizDept>) (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            //in查询写法
            Expression<Integer> expression = root.get("deptId").as(Integer.class);
            predicates.add(expression.in(ids));
            //某字段条件为NULL
            predicates.add(root.get("deleteBy").as(Integer.class).isNull());
            //某字段匹配
            Predicate predicate = criteriaBuilder.equal(root.get("deptName").as(String.class), "测试部门930");
            Predicate end = criteriaBuilder.or(predicate);
            Predicate and = criteriaBuilder.and(predicates.toArray(new Predicate[]{}));
            return criteriaBuilder.or(new Predicate[]{and, end});
        });
        list = list.stream().sorted(Comparator.comparing(BizDept::getDeptId)).collect(Collectors.toList());
        list.forEach(e -> LOGGER.info("获取元素:" + e));
    }
}

Rootroot:代表了可以查询和操作的实体对象的根。
CriteriaQuery<?>query:代表一个specific的顶层查询对象,它包含着查询的各个部分,比如:select、from、where、group by、order by等
CriteriaBuilder cb:用来构建CritiaQuery的构建器对象,其实就相当于条件或者是条件组合,以谓语即Predicate的形式返回。

spring data jpa常用的 jpa 的配置

spring boot 项目关于 jpa 的常用配置 application.properties 配置如下

#项目端口的常用配置
server.port=8081

# 数据库连接的配置
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

#数据库连接池的配置,hikari 连接池的配置
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.connection-timeout=10000
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.auto-commit=true

#通过 jpa 自动生成数据库中的表
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect

实体类其他注解,非JPA

序列化注解
注解@JsonIgnore的使用方法及其效果
作用:在json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响。
使用方法:一般标记在属性或者方法上,返回的json数据即不包含该属性。

字段类型映射

java数据类型与sql数据类型对照
java中 的char、java.lang.Character
对应sql数据库中的CHAR(1)类型,应该把string换成Character;
如果是char里面是保存的Y/N这种,则可以用boolean。

posted @ 2021-06-12 17:10  crazy-zz5536  阅读(399)  评论(0编辑  收藏  举报