很长时间没有用过JAP,也是类似于MyBaits底层的一种持久层框架,后面发现网上的博客中对于JPA的使用规范介绍的都不一样,现在自己将自己对JPA的认识总结一下,为了避免后续的踩坑之路继续下去,在使用JPA的,过程中,导报和引入对应的额实体类和对应的XML就不简单的过多的去叙述太多了,都是一些繁文缛节的东西只要按照文档进行简单操作就可以了。
下面就是快速的简单的介绍一些JAP的历史和相关的详情信息,其实JAP和Hibernate都是一样的,需要进行控制操作
Spring Data JPA是Spring Data家族的一部分,可以轻松实现基于JPA的存储库。 此模块处理对基于JPA的数据访问层的增强支持。 它使构建使用数据访问技术的Spring驱动应用程序变得更加容易。
在相当长的一段时间内,实现应用程序的数据访问层一直很麻烦。 必须编写太多样板代码来执行简单查询以及执行分页和统计。 Spring Data JPA旨在通过减少实际需要的工作量来显著改善数据访问层的实现。 作为开发人员,编写repository接口,包括自定义查找器方法,Spring将自动提供实现
JPA是一套规范,内部是有接口和抽象类组成的。hibernate是一套成熟的ORM框架,而且Hibernate实现了JPA规范,所以也可以称hibernate为JPA的一种实现方式,我们使用JPA的API编程,意味着站在更高的角度上看待问题(面向接口编程)
Spring Data JPA是Spring提供的一套对JPA操作更加高级的封装,是在JPA规范下的专门用来进行数据持久化的解决方案。
总的来说JPA是ORM规范,Hibernate、TopLink等是JPA规范的具体实现,这样的好处是开发者可以面向JPA规范进行持久层的开发,而底层的实现则是可以切换的。Spring Data Jpa则是在JPA之上添加另一层抽象(Repository层的实现),极大地简化持久层开发及ORM框架切换的成本
后面的创建依赖这些其实都是一些非常简单的步骤,可以简单的看一下,当然如果特别的熟悉项目环境搭建的过程可以忽略过去,或者说有不需要的看的小伙伴可以自行略过,
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.6.RELEASE
com.lzx.spring-data
spring-data-jpa
0.0.1-SNAPSHOT
spring-data-jpa
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
runtime
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
org.apache.maven.plugins
maven-compiler-plugin
1.8
utf-8
2. 设置配置信息
#---------------------------------------
# db
#---------------------------------------
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/spider?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123
#---------------------------------------
# spring data jpa
#---------------------------------------
#设置打印sql语句
spring.jpa.show-sql=true
#设置数据库类型
spring.jpa.database=mysql
#设置打印ddl语句
spring.jpa.generate-ddl=true
#设置数据库表效验 update:每次运行程序,没有表时创建表,如果对象属性发生改变,会更新表结构,不会清空数据
spring.jpa.hibernate.ddl-auto=update
#设置命名策略
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
ddl-auto
create
:每次运行程序时,都会重新创建表,故而数据会丢失create-drop
:每次运行程序时会先创建表结构,然后待程序结束时清空表upadte
:每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新(推荐使用)validate
:运行程序会校验数据与数据库的字段类型是否相同,字段不同会报错none
: 禁用DDL处理3. 编写实体类,Repository接口
package com.lzx.springdata.springDataJpa.pojo;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "article")
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String title;
private String content;
private Date create_time;
private String user;
private Integer read_count;
@Override
public String toString() {
return "Article{" +
"id=" + id +
", title='" + title + '\'' +
", content='" + content + '\'' +
", create_time=" + create_time +
", user='" + user + '\'' +
", read_count=" + read_count +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getCreate_time() {
return create_time;
}
public void setCreate_time(Date create_time) {
this.create_time = create_time;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public Integer getRead_count() {
return read_count;
}
public void setRead_count(Integer read_count) {
this.read_count = read_count;
}
}
package com.lzx.springdata.springDataJpa.dao;
import com.lzx.springdata.springDataJpa.pojo.Article;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* JpaRepository<实体类类型,主键类型>:用来完成基本CRUD操作
* JpaSpecificationExecutor<实体类类型>:用于复杂查询(分页等查询操作)
*/
public interface ArticleRepository extends JpaRepository, JpaSpecificationExecutor {
}
4. 测试
package com.lzx.springdata.springDataJpa.controller;
import com.lzx.springdata.springDataJpa.dao.ArticleRepository;
import com.lzx.springdata.springDataJpa.pojo.Article;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
public class DemoController {
@Autowired
private ArticleRepository articleRepository;
@RequestMapping("/add")
public String demo1(){
Article article = new Article();
article.setContent("165161");
article.setCreate_time(new Date());
article.setUser("lzx");
article.setTitle("1");
article.setRead_count(0);
//保存该对象
articleRepository.save(article);
return "sucess";
}
/**
* 对于save方法,会先根据id进行查询 如果有该id 则进行更新操作 如果没有 则进行删除操作
* @return
*/
@RequestMapping("/update")
public String demo2(){
//根据id查询
Article article = articleRepository.getOne(1);
//修改标题
article.setTitle("111111111");
//更新数据库
articleRepository.save(article);
return "sucess";
}
@RequestMapping("/delete")
public String demo3(){
//根据id删除
articleRepository.deleteById(1);
return "sucess";
}
@RequestMapping("/query")
public String demo4(){
//根据id查询
Article one = articleRepository.getOne(1);
System.out.println(one);
return "sucess";
}
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.data.jpa.repository;
import java.util.List;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;
@NoRepositoryBean
public interface JpaRepository extends PagingAndSortingRepository, QueryByExampleExecutor {
List findAll();
List findAll(Sort var1);
List findAllById(Iterable var1);
List saveAll(Iterable var1);
void flush();
S saveAndFlush(S var1);
void deleteInBatch(Iterable var1);
void deleteAllInBatch();
T getOne(ID var1);
List findAll(Example var1);
List findAll(Example var1, Sort var2);
}
使用Spring Data JPA提供的查询方法已经可以解决大部分的应用场景,但是对于某些业务来说,我们还需要灵活的构造查询条件,这时就可以使用@Query注解,结合JPQL的语句方式完成查询
@Query 注解的使用非常简单,只需在方法上面标注该注解,同时提供一个JPQL查询语句即可
public interface ArticleRepository extends JpaRepository,JpaSpecificationExecutor {
//@Query 使用jpql的方式查询。
@Query(value="from Article")
public List findAllArticle();
//@Query 使用jpql的方式查询。?1代表参数的占位符,其中1对应方法中的参数索引
@Query(value="from Article where title = ?1")
public Customer findArticle(String title);
}
此外,也可以通过使用 @Query 来执行一个更新操作,为此,我们需要在使用 @Query 的同时,用 @Modifying 来将该操作标识为修改查询,这样框架最终会生成一个更新的操作,而非查询
@Query(value="update Article set title = ?1 where id = ?2")
@Modifying
public void updateArticle(String title,Integer Id);
Spring Data JPA同样也支持sql语句的查询,如下
/**
* nativeQuery : 使用本地sql的方式查询
*/
@Query(value="select * from article",nativeQuery=true)
public void findSql();
顾名思义,方法命名规则查询就是根据方法的名字,就能创建查询。只需要按照Spring Data JPA提供的方法命名规则定义方法的名称,就可以完成查询工作。Spring Data JPA在程序执行的时候会根据方法名称进行解析,并自动生成查询语句进行查询
按照Spring Data JPA 定义的规则,查询方法以findBy开头,涉及条件查询时,条件的属性用条件关键字连接,要注意的是:条件属性首字母需大写。框架在进行方法名解析时,会先把方法名多余的前缀截取掉,然后对剩下部分进行解析。
具体的关键字,使用方法和生产成SQL如下表所示
下面简单进行一个总结进行一下简单的概述以及需要特别注意和需要关注的点
SpringDataJpa基本使用相关的总结
@Entity 用来标注一个数据库对应的实体,数据库中创建的表名默认和类名一致
@Table(name="",catalog="",schema="") 用来标注一个数据库对应的实体,
主键需要加上注解 @Id注解
如果是自动生成需要设置生成柜子 @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "menu_name") 设置属性对应的数据库字段名称
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "sys_menu")
public class SysMenu {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "menu_id")
private long menuId;
@Column(name = "menu_name")
private String menuName;
@Column(name = "parent_id")
private long parentId;
@Column(name = "order_num")
private long orderNum;
@Column(name = "url")
private String url;
@Column(name = "is_delete")
private String isDelete;
@Column(name = "target")
private String target;
@Column(name = "menu_type")
private String menuType;
@Column(name = "visible")
private String visible;
@Column(name = "perms")
private String perms;
@Column(name = "icon")
private String icon;
@Column(name = "create_by")
private String createBy;
@Column(name = "create_time")
private Date createTime;
@Column(name = "update_by")
private String updateBy;
@Column(name = "update_time")
private Date updateTime;
@Column(name = "remark")
private String remark;
}
JpaRepository
,TD> 封装了简单的crud方法JpaSpecificationExecutor** 封装了高级查询方法
其中 T**是实体对象 TD**是主建类型
@Repository
public interface SysMenuDAO extends JpaRepository, JpaSpecificationExecutor {
}
上述就是关于SpringDataJpa的简单的概述和相关的方法介绍可以说是非常的好的一种持久层的数据库框架,非常利用对SQL语句的编写