Spring Data知识点总结
学习时学习使用的课程: SpringData讲解视频
记录一些自己的学习笔记,希望一些内容可以帮助到正在学习JPA的小伙伴。
1.MySQL、Mybatis、SpringData介绍
1.1 SpringData:
旨在统一和简化对各类型持久化存储和访问,而不拘泥于是关系型数据库还是MySQL数据存储,使得对数据库的访问变得方便快捷
1.2 MyBatis
是一个优秀的持久层框架,它对jdbc的操作如MySQL等数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
1.3 MySQL
是一款跨平台的关系型数据库管理系统,Oracle公司的。
2. 传统方式访问数据库
2.1 jdbc原生态的方式访问
//步骤一:定义连接数据库的相关信息
(1) 连接数据库的驱动:8.0版本以下的数据库的驱动名
com.mysql.jdbc.Driver
(2)8.0版本以上的数据库的驱动名
com.mysql.cj.jdbc.Driver
static String driver = "com.mysql.jdbc.Driver";
连接数据库
static String url = "jdbc:mysql://localhost:3306/school?useSSL=false";
static String username = "root";
static String password = "root";
public static void main(String[] args) {
//步骤二:加载jdbc驱动
Class.forName(driver);
//步骤三:通过驱动管理器获得和数据的连接
Connection conn = DriverManager.getConnection(url,username,password);
System.out.println("数据库的连接:"+conn);
//步骤四:定义查询的sql语句
sql="";
//步骤五:创建一个PreparedStatement对象(可以用来执行sql,来操作数据库)
PreparedStatement pstmt = conn.prepareStatement(sql);
//步骤六:执行sql,得到结果集
ResultSet rs = pstmt.executeQuery();
//步骤七:关闭资源
}
2.2 spring jdbc模板
需要配置jdbc数据源连接,代码量非常多
要在pom.xml文件中引入jar包
<!-- MySQL的jdbc驱动包 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!-- MySQL的jdbc驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
在application.properties文件中配置数据源
jdbc.url = jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC
jdbc.user = root
jdbc.password = root
jdbc.driverClass = com.mysql.cj.jdbc.Driver
3 springdata快速起步
- 要添加spring-data-jpa和hibernate-entitymanager依赖
- 先开发实体类-------->自动生成数据表
- 添加@Entity默认生成表的名称和实体类相同 @Table(name = “表名”),自定义生成表名称
//用注解方法
@Entity
@Table(name="test_employee")每次更改表名会重新创建一个新表
public class Employee {
4. JPA
4.1接口介绍
4.11 实现repository接口,可以用继承或者注解
//使用注解
@RepositoryDefinition(domainClass = Employee.class,idClass=Integer.class)
public interface EmployeeRepository {
}
//使用继承extends接口Repository,不提供任何方法,没有包含方法声明,是一个空接口,标记接口
public interface EmployeeRepository extends Repository<T,ID extends Serializable> {
}
4.12 如果没有继承Respsitory运行时会报如下图错误
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'com.smk.repository.EmployeeRepository'
available
4.13 PagingAndSortingRepository
//分页查询并根据某个字段进行排序
//单元测试
@Test
public void testPageAndSort(){
Sort.Order order = new Sort.Order(Sort.Direction.DESC,"id");
Sort sort = new Sort(order);
//page:index是从0开始的,第几页每页显示多少条
//查询第1页,每页展示5个
Pageable pageable = new PageRequest(0,5,sort );
Page<Employee> page = employeePagingAndSortingRepository.findAll(pageable);
System.out.println("查询totalPage:"+page.getTotalPages());
System.out.println("查询总记录数:"+page.getTotalElements());
System.out.println("查询当前第几页:"+(page.getNumber()+1));
System.out.println("查询当前页面集合:"+page.getContent());
System.out.println("查询当前页面记录数:"+page.getNumberOfElements());
}
}
4.14 JpaSpecificationExecutor接口使用介绍
//repository中继承接口
public interface EmployeeJpaSpecificationExecutorRepository
extends JpaRepository<Employee,Integer>,
JpaSpecificationExecutor<Employee> {
//加上实体类
}
单元测试
Specification<Employee> specification = new Specification<Employee>() {
@Override
/**
* root:要查询的实体类就是我们要查询的类型
* query:添加查询条件
* cb:构建predicate
*/
//query查询条件
public Predicate toPredicate(Root<Employee> root,
CriteriaQuery<?> query,
CriteriaBuilder cb) {
//root(employee(age))查询年龄超过50
Path path = root.get("age");
return cb.gt(path,50);
}
};
Page<Employee> page = employeeJpaSpecificationExecutorRepository.findAll
(specification,pageable);
4.2 添加相关依赖
4.3 Repository中查询方法定义规则和使用
4.4 Repository中自定义复杂查询
- 在Repository方法中使用,不需要遵循查询方法命名规则
- 只需要将@Query定义在Repository中的方法之上
- 命名参数可以自己定义
4.4.1 注解@Query和@Param
- @Query 是JPA中的注解,用于绑定方法和与数据库表有关的操作。
- 它的查询语法格式分为两种,一种是数据库原生语句,这种方式需要在属性里面显式地将nativeQuery属性设置为true。
- 另一种是JPA的语法格式,这种方式需要搭配@Entity和@Table注解使用。
- 它的参数调用格式也分为两种,一种是通过 ?+入参坐标的形式来调用,例如:?1。
- 另一种则是通过:+变量名的形式调用,例如::userName。当使用第二种方式时,需要用@Param来对参数名进行映射。
//原生语句
@Query(value = "select * from User where user_id = :id", nativeQuery = true)
List<User> findUser(@Param(value = "id") String userId);
//这里假定已经定义了一个User类,并且用@Entity(value = "userTable")注解标注过
//JPA语法格式
@Query(value = "select u from userTable u where u.userId = ?1")
List<User> findUser(String userId);
4.4.2 更新update和删除delete
- 更新update和删除delete操作整合事务需要加上注解 @Modifying注解使用
- @Query执行更新或删除操作时在Repository的@Query上面添加上 @Modifying注解 在service层对应的方法上加上事务 @Transactional注解 ,仅仅需要查询的时候不需要加上事务
4.5 Jpa中实体映射关系
- @OneToOne 配置一对一关联,属性targetEntity指定关联的对象的类型
- @OneToMany注解“一对多”关系中‘一’方的实体类属性(该属性是一个集合对象),targetEntity注解关联的实体类类型,mappedBy注解另一方实体类中本实体类的属性名称
多端(Users)使用@ManyToOne。在JPA规范中,一对多的双向关系由多端(Users)来维护。也就是说多端(Users)为关系维护端,负责关系的增删改查。 - @ManyToOne注解“一对多”关系中‘多’方的实体类属性(该属性是单个对象),targetEntity注解关联的实体类类型
多对多关系的解除由关系维护端来解除多对多的关系。关系被维护端不能解除关系不能解除关系。
@JoinColumn指定该实体类对应的表中引用的表的外键,name属性指定外键名称,referencedColumnName指定应用表中的字段名称
/表之间直接关联
@ManyToOne
@JoinColumn(name="student_id")
private TeacherEntity teacherEntity;
//学生和课程之间也是多对多
@ManyToMany
@JoinTable(name="smk_stu_cou",joinColumns
= @JoinColumn(name="student_id"),
inverseJoinColumns = @JoinColumn(name="course_id"))
private Set<CourseEntity> courseEntities;
有不全面和错误的地方希望大家可以留言我再订正,和大家一起学习成长。