JPA是Java Persistence API的简写,是官网提出的一种ORM标准!

JPA标准,都在包门路:javax.persistence.*下,像一些罕用的如:@Entity、@Id及@Transient都在此门路下。这些也是一些当初市面上罕用的ORM一些约定俗成的注解了。

Spring Data JPA是Spring基于Hibernate开发的一个JPA框架。能够极大的简化JPA的写法,能够在简直不必写具体代码的状况下,实现对材料的拜访和操作。除了「CRUD」外,还包含如分页、排序等一些罕用的性能。

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></dependency>

application.properties 配置

spring.datasource.url=jdbc:mysql://localhost:3306/rumenz_springbootspring.datasource.username=rootspring.datasource.password=root1234spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.jpa.hibernate.ddl-auto=updatespring.sql.init.mode=alwaysspring.sql.init.schema-locations=classpath:/ddl/user-book.sqlspring.sql.init.data-locations=classpath:/ddl/user-book-data.sql
spring.jpa.hibernate.ddl-auto 是否依据实体类更新数据库,有四个属性值
属性值作用
create每次加载hibernate时都会删除上一次的生成的表,而后依据你的model类再从新来生成新表,哪怕两次没有任何扭转也要这样执行,这就是导致数据库表数据失落的一个重要起因。
create-drop每次加载hibernate时依据model类生成表,然而sessionFactory一敞开,表就主动删除。
update最罕用的属性,第一次加载hibernate时依据model类会主动建设起表的构造(前提是先建设好数据库),当前加载hibernate时依据 model类自动更新表构造,即便表构造扭转了但表中的行依然存在不会删除以前的行。要留神的是当部署到服务器后,表构造是不会被马上建设起来的,是要等利用第一次运行起来后才会。
validate每次加载hibernate时,验证创立数据库表构造,只会和数据库中的表进行比拟,不会创立新表,然而会插入新值。
spring.sql.init.mode 是否应用sql文件初始化数据库,有3个值
属性值作用
ALWAYS始终初始化数据库。
EMBEDDED仅初始化嵌入式数据库。
NEVER永远不要初始化数据库。
  • spring.sql.init.schema-locations 指定建表的sql文件
  • spring.sql.init.data-locations指定数据sql文件

创立实体类

User.java@Getter@Setter@Builder@AllArgsConstructor@Entity //jpa必填@DynamicInsert //填充默认值@DynamicUpdate //填充默认值@Table(name = "user") //jpa必填@NoArgsConstructorpublic class User {    @Id //jpa必填    @GeneratedValue(strategy = GenerationType.IDENTITY) //jpa必填    private Integer id;    private String name;    private String domain;    @Column(name = "age",columnDefinition = "tinyint default 0")    private Integer age;}
@GeneratedValue(strategy = GenerationType.IDENTITY)有以下几种类型
  • TABLE:应用一个特定的数据库表格来保留主键。
  • SEQUENCE:依据底层数据库的序列来生成主键,条件是数据库反对序列。
  • IDENTITY:主键由数据库主动生成(次要是主动增长型)
  • AUTO:主键由程序控制。

创立repository

数据长久层,负责拜访数据库,在这里申明的办法个别不必实现,只有依照Jpa的标准就能够主动生成SQL语句。
package com.rumenz.lession15.controller.repository;import com.rumenz.lession15.controller.entity.User;import org.springframework.data.domain.Page;import org.springframework.data.domain.Pageable;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.data.repository.PagingAndSortingRepository;import org.springframework.stereotype.Repository;import java.util.List;import java.util.Optional;/** * @className: UserRepository * @description: TODO 类形容 * @author: 入门小站 rumenz.com * @date: 2021/12/14 **/@Repositorypublic interface UserRepository extends PagingAndSortingRepository<User,Integer> {    Optional<User> findById(Integer id);    List<User> findDistinctUserByName(String name);    Integer countUserByName(String name);    List<User> readDistinctByName(String name);    Page<User> findAllByName(String name, Pageable pageable);}
Jpa能够通过接口名生成对应的sql语句,如 find... By,read... By,query... By,count... By,和get... By 。这些办法能够蕴含其余表达式,例如在要创立的查问上设置 Distinct 标记。第一个 By 用作分隔符,示意条件的开始,前面定义实体属性的各种条件,并将它们用 And 和 Or 连接起来。例如:
interface RumenzRepository extends JpaRepository<Rumenz, Long> {  List<Rumenz> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);  // 为查问启用 distinct 标记  List<Rumenz> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);  List<Rumenz> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);  // 为单个属性启用疏忽大小写  List<Rumenz> findByLastnameIgnoreCase(String lastname);  // 为所有属性启用疏忽大小写  List<Rumenz> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);  // 为查问启用动态 Order by  List<Rumenz> findByLastnameOrderByFirstnameAsc(String lastname);  List<Rumenz> findByLastnameOrderByFirstnameDesc(String lastname);}
举一些例子
关键字办法示例JPQL snippet
AndfindByLastnameAndFirstname… where x.lastname = ?1 and x.firstname = ?2
OrfindByLastnameOrFirstname… where x.lastname = ?1 or x.firstname = ?2
Is, EqualsfindByFirstname,findByFirstnameIs,findByFirstnameEquals… where x.firstname = ?1
BetweenfindByStartDateBetween… where x.startDate between ?1 and ?2
LessThanfindByAgeLessThan… where x.age < ?1
LessThanEqualfindByAgeLessThanEqual… where x.age <= ?1
GreaterThanfindByAgeGreaterThan… where x.age > ?1
GreaterThanEqualfindByAgeGreaterThanEqual… where x.age >= ?1
AfterfindByStartDateAfter… where x.startDate > ?1
BeforefindByStartDateBefore… where x.startDate < ?1
IsNull, NullfindByAge(Is)Null… where x.age is null
IsNotNull, NotNullfindByAge(Is)NotNull… where x.age not null
LikefindByFirstnameLike… where x.firstname like ?1
NotLikefindByFirstnameNotLike… where x.firstname not like ?1
StartingWithfindByFirstnameStartingWith… where x.firstname like ?1 (parameter bound with appended %)
EndingWithfindByFirstnameEndingWith… where x.firstname like ?1 (parameter bound with prepended %)
ContainingfindByFirstnameContaining… where x.firstname like ?1 (parameter bound wrapped in %)
OrderByfindByAgeOrderByLastnameDesc… where x.age = ?1 order by x.lastname desc
NotfindByLastnameNot… where x.lastname <> ?1
InfindByAgeIn(Collection ages)… where x.age in ?1
NotInfindByAgeNotIn(Collection ages)… where x.age not in ?1
TruefindByActiveTrue()… where x.active = true
FalsefindByActiveFalse()… where x.active = false
IgnoreCasefindByFirstnameIgnoreCase… where UPPER(x.firstame) = UPPER(?1)

Repository有3种

JpaRepository继承PagingAndSortingRepository,PagingAndSortingRepository继承CrudRepository。

  • CrudRepository提供CRUD的性能
  • PagingAndSortingRepository提供分页和排序功能
  • JpaRepository提供JPA相干的办法,如刷新长久化数据、批量删除等。

service

业务逻辑层,负责调用Repository解决数据实现业务。
package com.rumenz.lession15.controller.service;import com.rumenz.lession15.controller.entity.User;import org.springframework.data.domain.Page;import java.util.List;/** * @className: UserService * @description: TODO 类形容 * @author: 入门小站 rumenz.com * @date: 2021/12/14 **/public interface UserService {    Integer save(User user);    User get(Integer id);    List<User> listByName(String name);    Integer countByName(String name);    List<User> readDistinctByName(String name);    Page<User> listByNamePage(String name, Integer page, Integer pageSize);}//实现类package com.rumenz.lession15.controller.service.lmpl;import com.rumenz.lession15.controller.entity.User;import com.rumenz.lession15.controller.repository.UserRepository;import com.rumenz.lession15.controller.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.domain.Page;import org.springframework.data.domain.PageRequest;import org.springframework.data.domain.Pageable;import org.springframework.data.domain.Sort;import org.springframework.stereotype.Service;import java.util.List;import java.util.Optional;/** * @className: UserServiceImpl * @description: TODO 类形容 * @author: 入门小站 rumenz.com * @date: 2021/12/14 **/@Servicepublic class UserServiceImpl implements UserService {    @Autowired    UserRepository userRepository;    @Override    public Integer save(User user) {        User save = userRepository.save(user);        return save.getId();    }    @Override    public User get(Integer id) {        Optional<User> opt = userRepository.findById(id);        return opt.isPresent()?opt.get():null;    }    @Override    public List<User> listByName(String name) {        List<User> res = userRepository.findDistinctUserByName(name);        return res;    }    @Override    public Integer countByName(String name) {        return userRepository.countUserByName(name);    }    @Override    public List<User> readDistinctByName(String name) {        return userRepository.readDistinctByName(name);    }    @Override    public Page<User> listByNamePage(String name, Integer page, Integer pageSize) {        Sort sort = Sort.by("id").descending();        Pageable pageable= PageRequest.of(page-1, pageSize, sort);        Page<User> res = userRepository.findAllByName(name, pageable);        return res;    }}

Controller

前端控制器,负责接管前端申请,调用service,返回数据。
package com.rumenz.lession15.controller;import com.rumenz.lession15.controller.entity.User;import com.rumenz.lession15.controller.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.domain.Page;import org.springframework.data.domain.Pageable;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import java.util.List;/** * @className: RumenzController * @description: TODO 类形容 * @author: 入门小站 rumenz.com * @date: 2021/12/14 **/@RestController@RequestMapping("/rumenz")public class RumenzController {    @Autowired    UserService userService;    //保留数据    //id=1的数据不存在就增加    //id=1的数据存在就更新    @RequestMapping("/save")    public String save(){        User user=User.builder().id(1).name("入门小站123").domain("https://rumenz.com").build();        Integer save = userService.save(user);        return save.toString();    }    //通过id查问数据    @GetMapping("/get")    public User get(@RequestParam("id") Integer id){        return userService.get(id);    }    //带条件查问    @GetMapping("/listByName")    public List<User> get(@RequestParam("name") String name){        return userService.listByName(name);    }    //按条件查问符合条件的数量    @GetMapping("/countByName")    public Integer countByName(@RequestParam("name") String name){        return userService.countByName(name);    }    //带条件查问    @GetMapping("/readDistinctByName")    public List<User> readDistinctByName(@RequestParam("name") String name){        return userService.readDistinctByName(name);    }    //分页查问    //带条件查问    @GetMapping("/listByNamePage")    public Page<User> listByNamePage(@RequestParam("name") String name, @RequestParam("page") Integer page, @RequestParam("pageSize") Integer pageSize){        return userService.listByNamePage(name,page,pageSize);    }}
本小结源码地址:
  • GitHub:https://github.com/mifunc/spr...
  • Gitee:https://gitee.com/rumenz/spri...
  • https://rumenz.com/rumenbiji/...
介绍
  • 我的博客 https://rumenz.com/ ,
  • 我的工具箱 https://tooltt.com/
  • 微信公众号:【入门小站】

  • 关注【入门小站】回复【1001】获取 linux常用命令速查手册
  • 关注【入门小站】回复【1003】获取 LeetCode题解【java语言实现】
  • 关注【入门小站】回复【1004】获取 Java根底外围总结
  • 关注【入门小站】回复【1009】获取 阿里巴巴Java开发手册