赞
踩
JPA是Java Persistence API的简写,是官方提出的一种ORM规范!
JPA规范,都在包路径:
javax.persistence.*
下,像一些常用的如:@Entity、@Id及@Transient都在此路径下。这些也是一些现在市面上常用的ORM一些约定俗成的注解了。
Spring Data JPA是Spring基于Hibernate开发的一个JPA框架。可以极大的简化JPA的写法,可以在几乎不用写具体代码的情况下,实现对资料的访问和操作。除了「CRUD」外,还包括如分页、排序等一些常用的功能。
org.springframework.boot
spring-boot-starter-data-jpa
mysql
mysql-connector-java
spring.datasource.url=jdbc:mysql://localhost:3306/rumenz_springboot
spring.datasource.username=root
spring.datasource.password=root1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.sql.init.mode=always
spring.sql.init.schema-locations=classpath:/ddl/user-book.sql
spring.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 | 永远不要初始化数据库。 |
User.java @Getter @Setter @Builder @AllArgsConstructor @Entity //jpa必填 @DynamicInsert //填充默认值 @DynamicUpdate //填充默认值 @Table(name = "user") //jpa必填 @NoArgsConstructor public 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)
有以下几种类型
数据持久层,负责访问数据库,在这里声明的方法一般不用实现,只要按照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 **/ @Repository public interface UserRepository extends PagingAndSortingRepository { Optional findById(Integer id); List findDistinctUserByName(String name); Integer countUserByName(String name); List readDistinctByName(String name); Page 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 { List findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname); // 为查询启用 distinct 标志 List findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname); List findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname); // 为单个属性启用忽略大小写 List findByLastnameIgnoreCase(String lastname); // 为所有属性启用忽略大小写 List findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname); // 为查询启用静态 Order by List findByLastnameOrderByFirstnameAsc(String lastname); List findByLastnameOrderByFirstnameDesc(String lastname); }
举一些例子
关键字 | 方法示例 | JPQL snippet |
---|---|---|
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is, Equals | findByFirstname,findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age <= ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull, Null | findByAge(Is)Null | … where x.age is null |
IsNotNull, NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection ages) | … where x.age not in ?1 |
True | findByActiveTrue() | … where x.active = true |
False | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
Repository有3种
JpaRepository继承PagingAndSortingRepository,PagingAndSortingRepository继承CrudRepository。
业务逻辑层,负责调用
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 listByName(String name); Integer countByName(String name); List readDistinctByName(String name); Page 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 **/ @Service public 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 opt = userRepository.findById(id); return opt.isPresent()?opt.get():null; } @Override public List listByName(String name) { List res = userRepository.findDistinctUserByName(name); return res; } @Override public Integer countByName(String name) { return userRepository.countUserByName(name); } @Override public List readDistinctByName(String name) { return userRepository.readDistinctByName(name); } @Override public Page listByNamePage(String name, Integer page, Integer pageSize) { Sort sort = Sort.by("id").descending(); Pageable pageable= PageRequest.of(page-1, pageSize, sort); Page res = userRepository.findAllByName(name, pageable); return res; } }
前端控制器,负责接收前端请求,调用
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 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 readDistinctByName(@RequestParam("name") String name){ return userService.readDistinctByName(name); } //分页查询 //带条件查询 @GetMapping("/listByNamePage") public Page listByNamePage(@RequestParam("name") String name, @RequestParam("page") Integer page, @RequestParam("pageSize") Integer pageSize){ return userService.listByNamePage(name,page,pageSize); } }
本小结源码地址:
介绍
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。