Java Persistence API是一种标准技术,可让您将对象“映射”到关系数据库。
目前Hibernate是最流行的JPA实现之一。
优点:JPA在新增、修改、删除操作支持非常好。大大减少了数据库SQL的编写。
缺点:JPA在查询方面支持不太友好,主要是体现在多表连接查询上,所以复杂的查询可以用EntityManager方式。
实体类加载方式:
传统上,JPA“实体”类在persistence.xml文件中指定。在Spring Boot中,此文件不是必需的,而是使用“实体扫描”。默认情况下,将搜索主配置类(用@EnableAutoConfiguration或注释的一个@SpringBootApplication)下的所有软件包。
也可以使用@EntityScan注释来自定义实体扫描位置。
第一步:先在Mysql数据库创建一个表,并设置主键自动增长
脚本如下:
CREATE TABLE `tab_employee` (
`emp_id` int(11) UNSIGNED AUTO_INCREMENT,
`emp_name` varchar(100) DEFAULT NULL,
`emp_no` varchar(100) DEFAULT NULL,
`create_date` date DEFAULT NULL,
PRIMARY KEY (`emp_id`)
);
select * from tab_employee;
第二步:创建一个maven项目,并在pom.xml中引入SpringBoot的Jar,JPA的Jar,Mysql的Jar
pom.xml内容如下:
4.0.0
com.oysept
jpa_springboot
1.0-SNAPSHOT
jar
org.springframework.boot
spring-boot-starter-parent
2.3.0.RELEASE
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-jpa
mysql
mysql-connector-java
8.0.20
org.springframework.boot
spring-boot-maven-plugin
SpringBoot启动类:
package com.oysept;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class JpaApplication {
public static void main(String[] args) {
SpringApplication.run(JpaApplication.class, args);
}
}
项目结构图如下:
第三步:创建一个application.yml配置文件,指定启动端口和Mysql数据库配置
注:Mysql8.0版本以上的数据库,连接的配置有点变化,比如url后指定时区和数据库编码方式等。
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/oysept?serverTimezone=GMT&useUnicode=true&characterEncoding=utf8
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
show-sql: true
第四步:创建一个JPA实体类
@Entity:标识了该注解了的类,被认为是一个典型的实体类。
@Table:标识实体类映射的数据库表信息,name属性,表示数据库中的表名。
@Column:标识实体类映射的数据库表字段信息,name属性,表示数据库表中的字段名。
@Id:标识一个唯一ID,常用于数据库表主键字段。
@GeneratedValue:标识数据库主键字段生成策略。
TABLE:使用一个特定的数据库表来保存主键。
SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列、Mysql好像不支持该方式。
IDENTITY:主键由数据库自动生成(主要是自动增长型)。
AUTO:主键由程序控制,会自动匹配主键生成策略。
package com.oysept.bean;
import javax.persistence.*;
import java.util.Date;
/**
* 员工表
* @Table中的name属性,表示数据库中的表名
* @Column中的name属性,表示数据库表中的字段名
* @author ouyangjun
*/
@Entity
@Table(name = "TAB_EMPLOYEE")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "emp_id")
private Long empId;
@Column(name = "emp_name")
private String empName;
@Column(name = "emp_no")
private String empNO;
@Column(name = "create_date")
private Date createDate;
public Long getEmpId() {return empId;}
public void setEmpId(Long empId) {this.empId = empId;}
public String getEmpName() {return empName;}
public void setEmpName(String empName) {this.empName = empName;}
public String getEmpNO() {return empNO;}
public void setEmpNO(String empNO) {this.empNO = empNO;}
public Date getCreateDate() {return createDate;}
public void setCreateDate(Date createDate) {this.createDate = createDate;}
}
第五步:创建一个UserRepository工具类,并继承JpaRepository接口。
JPA的功能一般是从Repository或CrudRepository接口扩展,JpaRepository接口是其子类。
并且JPA有一套自己的方法名称命名方式,如需自定义实现,可以通过@Query注解进行扩展。
package com.oysept.repository;
import com.oysept.bean.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
public interface UserRepository extends JpaRepository {
/**
* jpa自带分页查询
* @param pageable
* @return
*/
Page findAll(Pageable pageable);
/**
* 根据用户ID查询一条数据,jpa有一定的查询规则,以一些通用前缀开头,比如findBy、find、get等
* 如果不想用这种默认规则,需要在接口上添加@Query主键,自定义实现数据查询,如下面一个接口
* @param empId
* @return
*/
User findByEmpId(Long empId);
/**
* jpa支持对象查询,简称HQL,也支持原生sql查询
* @return
*/
@Query("select u from User u")
List listUser();
// 原生sql方式查询
@Query(value = "select emp_id as empId, emp_name as empName, emp_no as empNO, create_date as createDate from tab_employee",
nativeQuery = true)
List listEmployee();
}
第六步:创建一个UserController控制器工具类,用于测试JPA接口
先创建一个空壳子,然后再一步步添加测试接口。
package com.oysept.controller;
import com.oysept.bean.User;
import com.oysept.repository.UserRepository;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
@RestController
public class JpaController {
@Autowired
private UserRepository userRepository;
}
方法1、新增User信息
// 新增user访问地址: http://localhost:8080/jpa/insertUser
@RequestMapping(value="/jpa/insertUser")
public User insertUser() {
User user = new User();
user.setEmpName("aaaa");
user.setEmpNO("bbbb");
user.setCreateDate(new Date());
return userRepository.save(user);
}
方法2、批量新增User信息
// 批量新增User访问地址: http://localhost:8080/jpa/batchInsertUser
@RequestMapping(value="/jpa/batchInsertUser")
public List batchInsertUser() {
User user = null;
List list = new ArrayList();
for (int i=0; i<10; i++) {
user = new User();
user.setEmpName("aaaa");
user.setEmpNO("bbbb");
user.setCreateDate(new Date());
list.add(user);
}
List userList = userRepository.saveAll(list);
return userList;
}
方法3、JPA自带分页,查询全部用户信息。
/**
* JPA自带分页,查询全部用户信息
* 访问地址: http://localhost:8080/jpa/findAll
*/
@RequestMapping(value="/jpa/findAll")
public Page findAll() {
Pageable pageable = Pageable.unpaged();
Page page = userRepository.findAll(pageable);
return page;
}
// 自定义方式获取全部User信息, 访问地址: http://localhost:8080/jpa/listUser
@RequestMapping(value="/jpa/listUser")
public List listUser() {
List list = userRepository.listUser();
return list;
}
方法4、根据ID查询User数据
// 根据ID查询User数据,访问地址: http://localhost:8080/jpa/findByEmpId
@RequestMapping(value="/jpa/findByEmpId")
public User findByEmpId() {
Long empId = 1L; // ID
User user = userRepository.findByEmpId(empId);
return user;
}
方案一:在application.yml或application.properties增加以下配置:
spring.jpa.properties.hibernate.hbm2ddl.auto=update
这个hibernate.hbm2ddl.auto参数的作用主要用于:自动创建、更新、验证数据库表结构。
有四个值:
create: 每次加载 hibernate 时都会删除上一次的生成的表,然后根据你的 model 类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
create-drop :每次加载 hibernate 时根据 model 类生成表,但是 sessionFactory 一关闭,表就自动删除。
update:最常用的属性,第一次加载 hibernate 时根据 model 类会自动建立起表的结构(前提是先建立好数据库),以后加载 hibernate 时根据 model 类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等 应用第一次运行起来后才会。
validate :每次加载 hibernate 时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
实体类配置如下:
@Id
@GeneratedValue
private Long empId;
方案二:直接在实体类中指定主键生成策略
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long empId;
方法名称命名规则:findBy(关键字)+属性名称(属性名称的首字母大写)+查询条件(首字母大写)
关键字 |
方法名 |
sql where 子句 |
---|---|---|
And |
findByNameAndPwd |
where name= ? and pwd =? |
Or |
findByNameOrSex |
where name= ? or sex=? |
Is,Equal |
findById,findByIdEquals |
where id= ? |
Between |
findByIdBetween |
where id between ? and ? |
LessThan |
findByIdLessThan |
where id < ? |
LessThanEqual |
findByIdLessThanEquals |
where id <= ? |
GreaterThan |
findByIdGreaterThan |
where id > ? |
GreaterThanEqual |
findByIdGreaterThanEquals |
where id > = ? |
After |
findByIdAfter |
where id > ? |
Before |
findByIdBefore |
where id < ? |
IsNull |
findByNameIsNull |
where name is null |
isNotNull,Not |
findByNameNotNull |
where name is not Null null |
Like |
findByNameLike |
where name like ? |
NotLike |
findByNameNotLike |
where name not like ? |
StartingWith |
findByNameStartingWith |
where name like ‘?%’ |
EndingWith |
findByNameEndingWith |
where name like ‘%?’ |
Containing |
findByNameContaining |
where name like ‘%?%’ |
OrderBy |
findByIdOrderByXDesc |
where id=? order by x desc |
Not |
findByNameNot |
where name <> ? |
In |
findByIdIn(Collection> c) |
where id in (?) |
NotIn |
findByIdNotIn(Collection> c) |
where id not in (?) |
True |
findByAaaTue |
where aaa = true |
False |
findByAaaFalse |
where aaa = false |
IgnoreCase |
findByNameIgnoreCase |
where UPPER(name)=UPPER(?) |
识别二维码关注个人微信公众号
本章完结,待续,欢迎转载!
本文说明:该文章属于原创,如需转载,请标明文章转载来源!