前言:
最近看到一个项目有用到, Spring Data JPA, 今天就简单了解一下, jpa简单使用
这个是和Mybatis的一点对比:
简介:
Spring Data JPA 是Spring Data框架下的一个基于JPA标准操作数据的模块,简化了操作持久层的代码,只需要编写接口就可以。如果你是第一次使用 Spring Data JPA ,你一定会惊呼这东西简直就是神器,几乎不需要写什么关于数据库访问的代码一个基本的 CURD 的功能就出来了。使用非常简单方便,下面我们就来讲述 JPA 使用的基本操作。
之前有学Mybatis数据库ORM框架(Object Relational Mapping),也介绍了使用Spring Boot 的jdbcTemplate 操作数据库。其实Spring Boot 还有一个非常实用的数据操作框架:Spring Data JPA。
JPA (Java Persistence API), Java持久层 API的简称,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中,JPA是一个基于O/R映射的标准规范。
JPA 是 Spring Boot 官方推荐的数据库访问组件,其充分体现了面向对象编程思想,有点像 asp.net 的 EFCore。JPA 也是众多 ORM 的抽象。
JPA的总体思想和现有Hibernate、TopLink、JDO等ORM框架大体一致。主要包括括以下3方面的技术:
- ORM映射元数据 将实体对象持久化到数据库表中
- API,用来操作实体对象,执行CRUD操作
- 查询语言,通过面向对象,而非面向数据库的查询语言查询数据
Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率。
SpringData:其实Spring Data 就是Spring提供了一个操作数据的框架。而Spring Data JPA只是Spring Data框架下的一个基于JPA标准操作数据的模块。
我们先来个小demo整合一下SpringBoot和SpringDataJPA
SpringBoot整合SpringDataJPA
依赖:
<dependencies>
<!--还是那句话, 包不要导重复了, 有些有包含关系-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--jpa配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--正常web启动类-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--lombok包-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0.1</version>
</dependency>
</dependencies>
application.yaml
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/jpa
username: root
password: #数据库密码
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
database: MYSQL
database-platform: org.hibernate.dialect.MySQL57Dialect
show-sql: true
hibernate:
# ddl-auto: create
ddl-auto: update
open-in-view: false
# jackson:
# property-naming-strategy: CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES
上面的属性一些小解释:
jpa.hibernate.ddl-auto是hibernate的配置属性,其主要作用是:自动创建、更新、验证数据库表结构。该参数的几种配置如下:
·create:每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
·create-drop:每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
·update:最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等应用第一次运行起来后才会。
·validate:每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
以上我们完成了基本的配置工作,记下来看一下如何进行表与实体的映射,以及数据访问接口。
实体类Person
package com.feng.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
/**
* @return null
* @author Ladidol
* @description
* @date 2022/4/13 19:42
*/
@Entity(name = "person")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
@Id//这里id不要导错了, import javax.persistence.Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", nullable = true, length = 20)
private String name;
@Column(name = "age", nullable = true, length = 4)
private int age;
}
PersonRepository.java
package com.feng.Repository;
import com.feng.pojo.Person;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface PersonRepository extends JpaRepository<Person, Long> {
Person findByName(String name);
}
controller:
package com.feng.controller;
import com.feng.Repository.PersonRepository;
import com.feng.pojo.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.Query;
import org.springframework.web.bind.annotation.*;
import javax.ws.rs.QueryParam;
@RestController
@RequestMapping(value = "person")
public class PerconController {
@Autowired
private PersonRepository personRepository;
@PostMapping(path = "addPerson")
public void addPerson(@RequestBody Person person) {
personRepository.save(person);
}
@DeleteMapping(path = "deletePerson")
public void deletePerson(Long id) {
personRepository.deleteById(id);
}
}
数据库中原有数据:
结果图:
添加用户:
删除id等于1的ladidol
上面使用的自带方法类:
SQL查询:
repository中声明相关方法:
@Transactional //开启事务
@Modifying //识别执行更新操作
@Query(value = "select * from person where name = ?1",nativeQuery = true)
Person findMyByName(String name);
@Transactional //开启事务
@Modifying //识别执行更新操作
//利用原生的 SQL 进行查询操作. ?1 表示第一个参数的占位符
@Query(value = "select * from person where name=?1", nativeQuery = true)
public List<Person> findPersonByName(String name);
//利用原生的 SQL 进行删除操作
@Query(value = "delete from person where id=?1 ", nativeQuery = true)
@Modifying
@Transactional
public int deletePersonById(int uid);
//利用原生的 SQL 进行修改操作
@Query(value = "update person set name=?1 where id=?2 ", nativeQuery = true)
@Modifying
@Transactional
public int updatePersonName(String name,int id);
//利用原生的 SQL 进行插入操作
@Query(value = "insert into person(name,age) value(?1,?2)", nativeQuery = true)
@Modifying
@Transactional
public int insertPerson(String name,int age);
//利用原生的 SQL 实现姓名的模糊查询
@Query(value=" SELECT * FROM person WHERE name LIKE %:name% ",nativeQuery=true)
List<Person> queryBynameSQL(@Param(value = "name") String name);
controller中添加新方法:
一些简单的增删改查
//原生 sql 的调用
/**
* @param name:
* @return Object
* @author Ladidol
* @description 通过名字查询
* @date 2022/4/13 22:50
*/
@RequestMapping("/findPersonByName")
public Object findStuByName(String name) {
List<Person> person = personRepository.findPersonByName(name);
return person;
}
/**
* @param id:
* @return Object
* @author Ladidol
* @description 通过id查询
* @date 2022/4/13 22:50
*/
@RequestMapping("/deletePersonById")
public Object deleteStudentById(int id) {
int i = personRepository.deletePersonById(id);
Map<String,Object> map=new HashMap<String,Object>();
if(i>0) {
map.put("success", true);
}else {
map.put("success", false);
}
return map;
}
/**
* @param name:
* @param id:
* @return Object
* @author Ladidol
* @description 通过id修改name
* @date 2022/4/13 22:50
*/
@RequestMapping("/updatePersonName")
public Object updateStudentName(String name,int id) {
int i = personRepository.updatePersonName(name,id);
Map<String,Object> map=new HashMap<String,Object>();
if(i>0) {
map.put("success", true);
}else {
map.put("success", false);
}
return map;
}
/**
* @param name:
* @param age:
* @return Object
* @author Ladidol
* @description 插入新的person
* @date 2022/4/13 22:51
*/
@RequestMapping("/insertPerson")
public Object insertStudent(String name,int age) {
int i = personRepository.insertPerson(name,age);
Map<String,Object> map=new HashMap<String,Object>();
if(i>0) {
map.put("success", true);
}else {
map.put("success", false);
}
return map;
}
/**
* @param keyword:
* @return Object
* @author Ladidol
* @description 通过名字中的关键字查询列表
* @date 2022/4/13 22:51
*/
@RequestMapping("/queryBynameSQL")
public Object queryBynameSQL(String keyword) {
List<Person> person= personRepository.queryBynameSQL(keyword);
return person;
}
部分运行结果:
增:
改:
查:
最终数据库中:
这只是一个小入门! 小小了解一下jpa.
jpa自动建表就很nice!
想了解jpql的可以戳这里
END:
参考链接:
这是一个神奇的字符串:
6L6T5LqG5L2g77yM6LWi5LqG5LiW55WM5Y+I6IO95aaC5L2V44CC