Spring Data JPA 简单使用

一、使用Spring Data JPA前的准备

(一)简介

1.JPA与Hibetnate的关系

JPA和Hibernate的关系就像JDBC和JDBC驱动的关系,JPA是规范,Hibernate除了作为ORM框架之外,它也是一种JPA实现。JPA怎么取代Hibernate呢?JDBC规范可以驱动底层数据库吗?答案是否定的,也就是说,如果使用JPA规范进行数据库操作,底层需要hibernate作为其实现类完成数据持久化工作。

2.Spring Data jpa

Spring Data JPA 让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现,在实际的工作工程中,推荐使用Spring Data JPA + ORM(如:hibernate)完成操作,这样在切换不同的ORM框架时提供了极大的方便,同时也使数据库层操作更加简单,方便解耦

3.总结:

JPA是一种规范,Hibernate实现了JPA规范,即Hibernate为JPA的一种实现;而Spring Data JPA是对JPA进行更高级的封装,让其dao编码变得更简单。
  
建议官网逛一逛:Spring Data JPA

(二)导包

部分其他依赖就不一个一个的列举,读者也可以根据自己实际的开发情况进行添加

<!-- Spring Data JPA 依赖  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

(三) 配置文件

#Tomcat容器相关配置
server.port=8888
#数据库配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/diarysystem?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&allowMultiQueries=true&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=123456
#正向工程
spring.jpa.hibernate.ddl-auto=update
#sql显示
spring.jpa.show-sql=true

二、实操

(一)接口编写

package com.sgh.disrysystemweb.dao;

import com.sgh.disrysystemweb.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * 编写UserDao
 */
public interface UserRepository extends JpaRepository<User,Integer> {
}

(二) 实体类

package com.sgh.disrysystemweb.entity;

import lombok.Data;
import lombok.ToString;
import javax.persistence.*;

@Entity
@Data
@ToString
@Table(name="user") //对应数据库表名
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)//自增长
    @Column(name = "uid") //如果不传真,默认此属性名
    private Integer uid;
    @Column
    private String name;
    @Column
    private Integer age;
    @Column
    private String telphone;
    @Column
    private String email;
    @Column
    private String job;

    public User(){
    }
}

(三)测试

package com.sgh.disrysystemweb.dao;

import com.sgh.disrysystemweb.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.transaction.Transactional;

/**
 * @author sugha
 * @version 1.0
 * @description
 * @date 2021/1/12 0012 22:27
 */
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration("classpath:applicationContext.xml")
@SpringBootTest
public class UserDaoTest {
    @Autowired
    private UserRepository usersDao;
    /**
     * 添加用户
     */
    @Test
    @Transactional// 在测试类对于事务提交方式默认的是回滚。
    @Rollback(false)//取消自动回滚
    public void testInsertUsers(){
        User user = new User();
        user.setTelphone("1234555");
        user.setName("SGH");
        user.setJob("java编程");
        user.setEmail("123124@qq.com");
        user.setAge(12);
        usersDao.save(user);
    }
}

三、拓宽

(一)JPA接口关系

在这里插入图片描述
RoleRepository是我自己创建的一个接口,QueryByExampleExecutor只是我又自己继承了,所以才有两条线。

(二)JPA主要接口使用

在使用之前先看两张截图(应该能看清楚吧,如果看不清可见官网):
在这里插入图片描述
在这里插入图片描述

在下面的接口测试中只用到了截图中的部分,但注意让大家进行扩展学习了。

1.JpaRepository接口

编写接口
package com.sgh.disrysystemweb.dao.demo;

import com.sgh.disrysystemweb.entity.Role;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.QueryByExampleExecutor;

import javax.transaction.Transactional;
import java.util.List;


public interface RoleRepository extends JpaRepository<Role, String> {
    //方法名称必须要遵循驼峰式命名规则,findBy(关键字)+属性名称(首字母大写)+查询条件(首字母大写)
    //根据roleName查询
    List<Role> findByRoleName(String roleName);

    //根据roleName and roleCode查询
    List<Role> findByRoleNameAndRoleCode(String roleName, String roleCode);

    //根据roleName模糊查询
    List<Role> findByRoleNameLike(String roleName);

    @Query("from Role where role_Name = ?1 ")
    List<Role> queryByNameHQL(String rolename);

    @Query(value = "select * from Role where role_Name = ?1 ",nativeQuery = true)
    List<Role> queryByRoleNameSQL(String roleName);
//
    @Query("update Role set role_Name=?1 where roleid= ?2")
    @Modifying        //需要执行一个更新操作
    @Transactional //加上事务
    void updateRoleNameById(String roleName,String roleId);
}

编写映射实体类
package com.sgh.disrysystemweb.entity;

import lombok.Data;
import lombok.ToString;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;

@Entity
@Data
@ToString
@Table(name="role") //对应数据库表名
public class Role {
    @Id
    @Column(name ="ROLEID")
    private String roleid;
    @Column(name ="ROLE_NAME")
    private String roleName;
    @Column(name ="ROLE_CODE")
    private String roleCode;
    @Column(name ="ROLE_TYPE")
    private String roleType;
    @Column(name ="ISACTIVE")
    private String isactive;
    @Column(name ="CREATE_DATE")
    private String createDate;
    @Column(name ="TENANT_ID")
    private String tenantId;
    @Column(name ="DTYPE")
    private String dtype;
    @Column(name ="REMARK")
    private String remark;
    @Column(name ="CREATOR")
    private String creator;
    @Column(name ="MODIFY_DATE")
    private String modifyDate;
    @Column(name ="REVISER")
    private String reviser;
    @Column(name ="LABEL_NAME")
    private String labelName;
    @Column(name ="TS")
    private String ts;
    @Column(name ="DR")
    private Integer dr;
    @Column(name ="MODIFIED_TIME")
    private Date modifiedTime;
    @Column(name ="CREATION_TIME")
    private Date creationTime;
    @Column(name ="NEW_TS")
    private String newTs;
    @Column(name ="ROLE_NAME2")
    private String roleName2;
    @Column(name ="BASEROLE_TYPE")
    private String baseroleType;
    @Column(name ="EXT01")
    private String ext01;
    @Column(name ="ORGANIZATION_ID")
    private String organizationId;

}

编写测试类
package com.sgh.disrysystemweb.dao.demo;

import com.sgh.disrysystemweb.entity.Role;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.transaction.Transactional;
import java.util.List;
import java.util.Optional;

/**
 * @author sugha
 * @version 1.0
 * @description
 * @date 2021/1/9 0013 22:21
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class RoleRepositoryTest {
    @Autowired
    RoleRepository roleRepository;
    @Test
    public void insertTest(){
        Role role = new Role();
        role.setRoleid("222");
        role.setRoleCode("222");
        role.setRemark("备注");
        role.setRoleName("角色1");
        role.setDr(1);
        roleRepository.save(role);
    }

    @Test
    public void findByRoleNameTest(){
        List<Role> roles = roleRepository.findByRoleName("角色1");
        for(Role role : roles){
            System.out.println(role);
        }
    }
    @Test
    public void findByRoleNameAndRoleCode(){
        List<Role> roles = roleRepository.findByRoleNameAndRoleCode("角色1", "222");
        for(Role role : roles){
            System.out.println(role);
        }
    }

    @Test
    public void findByRoleNameLikeTest() {
        List<Role> roles = roleRepository.findByRoleNameLike("角色_");//占位符还是自己输入
        for(Role role : roles){
            System.out.println(role);
        }
    }

    @Test
    public void queryByNameHQLTest(){
        List<Role> roles = roleRepository.queryByNameHQL("角色1");
        for(Role role : roles){
            System.out.println(role);
        }
    }

    @Test
    public void queryByRoleNameSQLTest(){
        List<Role> roles = roleRepository.queryByRoleNameSQL("角色1");
        for(Role role : roles){
            System.out.println(role);
        }
    }

    @Test
    @Transactional //@Transactional与@Test 一起使用时 事务是自动回滚的。
    @Rollback(false) //取消自动回滚
    public void updateRoleNameByIdTest(){
        roleRepository.updateRoleNameById("角色2","222");
    }

}

2.JPASpecificationExecutor接口

JpaSpecificationExecutor接口的使用一般要和Repository体系的接口一起使用

注意:

在讲述原理的时候Dao对象其实是注入了一个代理对象,通过继承Repository体系接口完成代理对象SimpleJpaRepository实现类对象的注入。而JpaSpecificationExecutor对象不在Repository接口体系内那么就无法完成对象注入,所以要使用JpaSpecificationExecutor对象必须要实现Repository体系接口

3.PagingAndSortingRepository接口

该接口提供了分页与排序的操作,注意:该接口继承了CrudRepository接口

接口编写
package com.sgh.disrysystemweb.dao.demo;

import com.sgh.disrysystemweb.entity.Role;
import org.springframework.data.repository.PagingAndSortingRepository;


public interface RoleRepositoryPagingAndSorting  extends PagingAndSortingRepository<Role,String> {

}

测试类编写
package com.sgh.disrysystemweb.dao.demo;

import com.sgh.disrysystemweb.entity.Role;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
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.test.context.junit4.SpringJUnit4ClassRunner;
//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 java.util.List;

/**
 * @author sugha
 * @version 1.0
 * @description
 * @date 2021/1/10 0014 10:06
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class RoleRepositoryPagingAndSortingTest {
    @Autowired
    private RoleRepositoryPagingAndSorting roleRepositoryPagingAndSorting;
    @Test
    public void testPagingAndSortingRepositorySort() {
        //Order	定义了排序规则
        Sort.Order order=new Sort.Order(Sort.Direction.DESC,"roleid");
        //Sort对象封装了排序规则
        Sort sort=Sort.by(order);
        List<Role> list= (List<Role>) roleRepositoryPagingAndSorting.findAll(sort);
        for (Role Role:list){
            System.out.println(Role);
        }
    }

    @Test
    public void testPagingAndSortingRepositoryPaging() {
        //Pageable:封装了分页的参数,当前页,煤业显示的条数。注意:它的当前页是从0开始
        //PageRequest(page,size):page表示当前页,size表示每页显示多少条
        Pageable pageable= PageRequest.of(1,2);
        Page<Role> page=this.roleRepositoryPagingAndSorting.findAll(pageable);
        System.out.println("数据的总条数:"+page.getTotalElements());
        System.out.println("总页数:"+page.getTotalPages());
        List<Role> list=page.getContent();
        for (Role Role:list){
            System.out.println(Role);
        }
    }

    @Test
    public void testPagingAndSortingRepositorySortAndPaging() {
        Sort sort=Sort.by(new Sort.Order(Sort.Direction.DESC,"roleid"));
        Pageable pageable=PageRequest.of(0,2,sort);
        Page<Role> page=this.roleRepositoryPagingAndSorting.findAll(pageable);
        System.out.println("数据的总条数:"+page.getTotalElements());
        System.out.println("总页数:"+page.getTotalPages());
        List<Role> list=page.getContent();
        for (Role Role:list){
            System.out.println(Role);
        }
    }

}

4.QueryByExampleExecutor接口

QBE是一种查询技术,允许动态创建查询,并且不需要编写包含字段名称的查询。

5.CrudRepository接口

CrudRepository接口,主要是完成一些增删改查的操作。注意:CrudRepository接口继承了Repository接口。

编写接口
package com.sgh.disrysystemweb.dao.demo;

import com.sgh.disrysystemweb.entity.Role;
import org.springframework.data.repository.CrudRepository;

/**
 * @author sugha
 * @version 1.0
 * @description
 * @date 2021/1/10 0014 11:33
 */
public interface RoleRepositoryCrudRepository extends CrudRepository<Role,String> {
}

编写测试类
package com.sgh.disrysystemweb.dao.demo;

import com.sgh.disrysystemweb.entity.Role;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;
import java.util.Optional;

/**
 * @author sugha
 * @version 1.0
 * @description
 * @date 2021/1/10 0014 11:34
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class RoleRepositoryCrudRepositoryTest {
    @Autowired
    private RoleRepositoryCrudRepository roleRepositoryCrudRepository;

    @Test
    public void testCrudRepositorySave() {
        Role role = new Role();
        role.setRoleid("12312312");
        role.setRoleName("黑暗猎手");
        role.setRoleCode("VN");
        roleRepositoryCrudRepository.save(role);
    }

    @Test
    public void testCrudRepositoryUpdate() {
        Role role = new Role();
        role.setRoleid("222223");
        role.setRoleName("光辉");
        role.setRoleCode("GHHHHHHH");
        this.roleRepositoryCrudRepository.save(role);
    }

    @Test
    public void testCrudRepositoryFindOne() {
        Optional<Role> role = roleRepositoryCrudRepository.findById("222223");
        System.out.println(role);
    }

    @Test
    public void testCrudRepositoryFindAll() {
        List<Role> list = (List<Role>) this.roleRepositoryCrudRepository.findAll();
        for (Role user : list) {
            System.out.println(user);
        }
    }

    @Test
    public void testCrudRepositoryDeleteById() {
        roleRepositoryCrudRepository.deleteById("222223");
    }

}

参考文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值