版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
简介
使用Spring Data JPA之前先来了解一下JPA,Hibernate,Spring Data JPA三者之间的区别
JPA(Java Persistence API) JPA本身是一种规范,它的本质是一种ORM(对象关系映射)规范,用于将数据通过Java对象持久化、读取和管理到数据库中的关系表。
Hibernate 属于遵循JPA规范的一种实现,但是JPA是Hibernate遵循的规范之一,Hibernate还有其他实现的规范。类似于接口和实现类的关系
Spring Data JPA 是在JPA规范的基础下提供了Repository层的实现,可以看成是对JPA的再封装,默认使用Hibernate作为ORM实现
在了解了基本的情况之后去学习一下Spring Data JPA的使用
集成
笔者所使用的环境是spring boot,在pom文件中添加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
或者是在创建spring boot项目时勾选SQL → JPA
使用
准备
配置数据库连接
#通用数据源配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#serverTimezone=UTC&characterEncoding=UTF-8
spring.datasource.url=jdbc:mysql://localhost:3306/jpa?useSSL=FALSE&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
# JPA 相关配置
# 自动建表时切换默认存储引擎 当前切换为InnoDB
#spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
#配置在日志中打印出执行的 SQL 语句信息
spring.jpa.show-sql=true
# 每次运行项目删除重建表
#spring.jpa.hibernate.ddl-auto=create
# hibernate懒加载相关,配置之后单元测试读取数据时不会报错
spring.jpa.open-in-view=true
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
创建类
@Data //lombok
@Entity //必选注解
@Table(name = "user")//可选注解 如果不写name那么表明和类名一致
public class User {
@Id //声明实体唯一标识的属性
@GeneratedValue(strategy = GenerationType.IDENTITY) //sql自动生成主键
private Long id;
@Column(length = 50)//声明是一个字段, length声明字段长度
private String name;
@Column(length = 50)
private String account;
@Column(length = 50)
private String password;
}
//JpaRepository是Repository的子接口 两个泛型分别为表的实体和主键
@Repository
public interface UserDao extends JpaRepository<User, Long> {
}
当我们创建好了实体类以后只要在创建UserDao以后就可以对数据库进行访问了,我第一次使用也觉得很方便
开始使用
下面就来说下简单增删改查的使用
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class UserTest {
@Autowired
private UserDao userDao;
/**
* 新增
*/
@Test
public void addUser() {
User user = new User();
user.setName("王二");
user.setAccount("123");
user.setPassword("1234256");
userDao.save(user);
}
/**
* 删除
*/
@Test
public void delete() {
userDao.deleteById(3L);
}
/**
* 修改
* 修改使用的也是save,jpa判断是新增还是更新的方式主要是判断主键
* 如果主键被赋值就会去数据库中查询是否有这条数据,如果存在就是更新,不存在就是创建
* 更新时是全部字段的更新,如果有字段没有设置将会被赋值为null
*/
@Test
public void update() {
User user = new User();
user.setId(1L);
user.setName("张三");
user.setPassword("1221");
userDao.save(user);
}
/**
* 查询
*/
@Test
public void select() {
User firstUser = userDao.getOne(1L);
System.out.println(firstUser);
Optional<User> s = userDao.findById(1L);
s.ifPresent(System.out::println);
User user = new User();
user.setAccount("123"); //相当于查询 account 为123 的所有数据
Example<User> userExample = Example.of(user);
userDao.findAll(userExample);
//排序按照id 倒序排序
List<User> list = userDao.findAll(new Sort(Sort.Direction.DESC, "id"));
for (User u : list) {
System.out.println(u);
}
}
}
上面这些都是系统提供的方法,实际上我们还可以在UserDao中遵循规则定义方法
@Repository
public interface UserDao extends JpaRepository<User, Long> {
List<User> findByAccountEquals(String account);
}
这样JPA会为我们按照规则实现
idea编辑器会有相应的方法提示
定义SQL语句
/**
* nativeQuery默认是false,nativeQuery为false是使用不知道是JPQL还是HQL (+﹏+)~晕
* nativeQuery为true时是使用原生的sql语句,根据数据库的不同,sql语句可能有所区别
*/
@Query(nativeQuery = true, value = "select * from user where id in :idList")
List<User> findIdIn(@Param("idList") List<Long> idList);
/**
* 如果是删除或者是更新操作需要加上@Modifying注解以通知这是一个delete或update操作
*/
@Modifying
@Query(nativeQuery = true, value = "delete from user where id =:id")
void deleteById(@Param("id") Long id);
/**
* 执行insert 需要加上@Transactional和@Modifying两个注解
*/
@Transactional
@Modifying
@Query(nativeQuery = true, value = "insert into jpa.user (name) values (:name)")
void insert(@Param("name") String name);