1. 项目构建
【Filt】->【new】 -> 【project】 -> 选择Spring Initializr -> 【next】,填写Group,Artifact,Type ->【next】
-
选择依赖包
- 左边选择
Core
,右边勾选Lombok
- 左边选择
Web
,右边勾选Web
- 左边选择
SQL
,右边勾选JPA
和MySQL
【next】->【finish】
- 左边选择
2.配置文件
在配置文件resource.application.xml
前,需要创建以下配置类
package com.example.springdatajpa.config;
public class MyDatabaseConfig extends MySQL5InnoDBDialect {
@Override
public String getTableTypeString() {
// 设置创建表的存储引擎为 InnoDB,字符编码为 utf-8
return " ENGINE=InnoDB DEFAULT CHARSET=utf8";
}
}
在resource.application.yml
文件中添加如下配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/springdatajpa?useSSL=FALSE&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
show-sql: true # 打印sql语句
hibernate:
ddl-auto: update
# 设置jsp存储引擎,使用上面的配置类
database-platform: com.example.springdatajpa.config.MyDatabaseConfig
spring data jpa
的配置说明:
-
spring.jpa.show-sql:是否在日志打印sql语句
同样的,可以在
logback-spring.xml
中配置如下可以打印sql
和sql
参数<!--开发环境:打印控制台--> <springProfile name="dev"> <!-- 打印sql --> <logger name="org.hibernate.SQL" level="DEBUG"/> <!-- 打印sql的参数 --> <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE"/> <root level="info"> <appender-ref ref="CONSOLE"/> </root> </springProfile>
-
spring.jpa.hibernate.ddl-auto:是hibernate的配置属性,其主要作用是:自动创建、更新、验证数据库表结构。
该参数的几种配置如下:
-
create:每次加载都会删除上一次的生成的表,然后根据
model
类再重新来生成新表,会导致数据库表数据丢失。 -
create-drop:每次加载时,根据
model
类生成表,但是sessionFactory
一关闭,表就自动删除。 -
update:最常用的属性,第一次加载时根据
model
类会创建表的结构(前提是先建立好数据库),以后加载时根据model
类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等应用第一次运行起来后才创建。 - validate:每次加载时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
-
create:每次加载都会删除上一次的生成的表,然后根据
spring.jpa.database-platform:在
SpringBoot 2.0
版本中创建数据表的时候,默认存储引擎是MyISAM
。这个参数值org.hibernate.dialect.MySQL5InnoDBDialect
是在建表的时候,将默认的存储引擎切换为InnoDB
,但默认的字符编码为latin1
,所以一般都是自定义配置类继承MySQL5InnoDBDialect
来指定字符编码,或者手动创建表指定字符编码,或者创建表后,修改表字符编码。
3.建立数据实体类
数据库实体类是一个 POJO Bean
对象。这里我们先建立一个 UserDO
的数据库实体。数据库实体的源码如下
package com.example.springdatajpa.entity;
@Entity
@Table(name = "User") // 指定表名,不指定使用实体类名称
@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true, value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
public class UserDO {
@Id // 主键id
@GeneratedValue(strategy = GenerationType) // 主键生成策略
@Column(name = "id")
private Long id;
@Column(name = "username", length = 50) // 表列的字段名,长度50
private String username;
@Column(name = "age", length = 3) // 表列的字段名,长度3
private Integer age;
}
注意点:
@JsonIgnoreProperties:忽略
Hibernate
的延迟加载的一些属性"hibernateLazyInitializer", "handler", "fieldHandler",这些属性在实体类里没有所以要忽略掉,否则转换为Json
会报错。-
@GeneratedValue:设置主键
id
的生成策略。Jpa
支持4
种生成策略:- TABLE:使用一个特定的数据库表格来保存主键
- SEQUENCE:根据底层数据库的序列来生成主键,需要数据库支持序列。
- IDENTITY:主键由数据库自动生成(主要是自动增长型)
- AUTO:主键由程序控制(JPA默认)
四种数据库支持情况:
数据库名称 支持的id策略 mysql GenerationType.TABLE GenerationType.AUTO GenerationType.IDENTITY 不支持GenerationType.SEQUENCE oracle GenerationType.AUTO GenerationType.SEQUENCE GenerationType.TABLE 不支持GenerationType.IDENTITY postgreSQL GenerationType.TABLE GenerationType.AUTO GenerationType.IDENTITY GenerationType.SEQUENCE 都支持 kingbase GenerationType.TABLE GenerationType.SEQUENCE GenerationType.IDENTITY GenerationType.AUTO 都支持 上面的生成策略都是自增
id
,移植和在分布式下都不方便,JPA
可以使用UUID
生成策略:@Id @GenericGenerator(name = "system-uuid", strategy = "uuid") @GeneratedValue(generator = "system-uuid") @Column(name = "id") private String id; // uuid必须为String类型
4.实现持久层服务
JPA
中,实现持久层服务很简单。只需要新建接口继承org.springframework.data.jpa.repository.JpaRepository<T, ID>
类即可,其中T
是数据库实体类,ID
是数据库实体类的主键类型
package com.example.springdatajpa.repository;
/**
* 符合SpringDataJpa的Dao层接口规范
* JpaRepository<操作的实体类类型,实体类中主键属性的类型>
* * 封装了基本curd操作
* JpaSpecificationExecutor<操作的实体类类型>
* * 封装了复杂查询(如分页等)
*/
@Repository
public interface UserRepository extends JpaRepository<UserDO, Long>, JpaSpecificationExecutor<UserDO> {
// 如果需要自定义方法查询,可以添加
User findByUsername(String username);
}
一行代码也不用写。UserDO
这个实体类,拥有父类的如下功能:
5.创建Service
服务
-
UserService
接口package com.example.springdatajpa.service; public interface UserService { UserDO saveUser(UserDO userDO); UserDO findById(long id); }
-
UserService
接口的实现类UserServiceImpl
package com.example.springdatajpa.service.impl; @Service public class UserServiceImpl implements UserService { @Autowired private UserRepository userRepository; /** * save: 保存或更新 * 根据传递的对象是否存在主键id, * 如果没有id主键属性,则保存 * 存在id主键属性,根据id查询数据,再更新数据 */ @Override public UserDO saveUser(UserDO userDO) { UserDO save = userRepository.save(userDO); return save; } @Override public UserDO findById(long id) { UserDO byId = userRepository.findById(id).get(); return byId; } }
6.controller
类
package com.example.springdatajpa.controller;
@RestController
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/add-user")
public UserDO addPerson(@RequestBody UserDO user){
return userService.saveUser(user);
}
@GetMapping("/get-user")
public UserDO getPerson(@RequestParam Long id){
return userService.findById(id);
}
}
启动程序,如果数据库中的表不存在时,会自动创建表,在Postman
中执行
- 添加用户
- 通过id获取用户