SpringBoot整合Spring Data JPA步骤-(上)
1. 创建一个Maven的jar工程。如图:
![v2-45d13523735ab66bc6c7bff7319db4ec_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=b93a20c6-332f-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-45d13523735ab66bc6c7bff7319db4ec_b.jpg)
2. 修改POM文件
(1)添加Web启动器,Thymeleaf启动器,Spring Data JPA启动器坐标。
<!--web启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Thymeleaf启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--Spring Data JPA启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
(2)添加MySQL数据库、数据库连接池坐标。
<!--MySQL数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.20</version>
</dependency>
3.修改全局配置文件
添加数据库配置、连接池配置、JPA正向工程配置,显示SQL语句配置。
全局配置文件application.properties
#添加数据库配置
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/ssm
spring.datasource.username=root
spring.datasource.password=root
#连接池配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#JPA正向工程配置
spring.jpa.hibernate.ddl-auto=update
#显示SQL语句配置
spring.jpa.show-sql=true
SpringBoot整合Spring Data JPA步骤-(下)
1. 创建Users实体类,
包含id、name、age、address属性,其中id为主键。
@Entity
@Table(name = "t_users")
public class Users {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "name")
private String name;
@Column(name = "age")
private Integer age;
@Column(name = "address")
private String address;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Users{" +
"id=" + id +
", name='" + name + ''' +
", age=" + age +
", address='" + address + ''' +
'}';
}
}
2. 创建Dao接口继承JpaRepository接口。
/**
*Dao接口继承JpaRepository接口
* 参数一:当前需要映射的实体
* 参数二:当前映射的实体中的OID的类型
*/
public interface UsersRepository extends JpaRepository<Users,Integer> {
}
3. 在工程中添加测试启动器。
<!--测试启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
4. 创建启动类。
/**
* 启动类
*/
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class,args);
}
}
编写测试代码使用正向工程创建表,并在表中插入一条数据。
/**
* 测试UsersRepository
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = App.class)
public class UsersRepositoryTest {
@Autowired
private UsersRepository usersRepository; //注入接口类型目的是调用其操作方法
@Test
public void addUsers(){
Users users = new Users();
users.setName("袁帅");
users.setAge(18);
users.setAddress("安徽宿州学院");
this.usersRepository.save(users);
}
}
测试结果
![v2-be21710347b4df6295d85991ffe63850_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=b93a20c6-332f-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-be21710347b4df6295d85991ffe63850_b.jpg)
SpringBoot整合Spring Data JPA-Repository接口使用
在Spring Data JPA中提供了几个核心接口?
Repository接口
CrudRepository接口
PagingAndSortingRepository接口
JpaRepository接口
JpaSpecificationExecutor接口
Repository接口的作用是什么?
提供了方法名称命名查询方式
提供了基于@Query注解查询与更新
方法名称命名查询方式的规则是什么?
方法的名称必须要遵循驼峰命名规则。
fingBy(关键字)+属性名称(首字母大写)+查询条件(首字母大写)
编写接口
public interface UsersRepositoryByName extends Repository<Users,Integer> {
List<Users> findByName(String name);//根据姓名查询
List<Users> findByNameAndAge(String name,Integer age);//根据姓名和年龄查询
List<Users> findByNameLike(String name);//模糊查询
}
接口测试
/**
* Repository接口测试
*/
@Autowired
private UsersRepositoryByName usersRepositoryByName;//注入Repository接口
@Test
public void fingByName(){
List<Users> users = this.usersRepositoryByName.findByNameAndAge("杜程程", 18);
for (Users u: users
) {
System.out.println(u);
}
}
@Query注解的作用是什么?
该方法执行@Query注解方式查询
/**
* Repository接口 二、Query注解方式查询
*/
@Autowired
private UsersRepositoryQueryAnnotation usersRepositoryQueryAnnotation;
public interface UsersRepositoryQueryAnnotation extends Repository<Users,Integer> {
//HQL查询
@Query("from Users where name = ?1")
List<Users> queryByNameUseHQL(String name);
//SQL查询
@Query(value = "select * from t_users where name=?",nativeQuery = true)
List<Users> queryByNameUseSQL(String name);
@Query("update Users set name = ?1 where id = ?2 ")
@Modifying //需要执行一个更新操作
void updateUsersNameById(String name ,Integer id);
}
/**
* Repository接口测试 二、@Query注解查询
*/
@Test
public void queryByNameUseHQL(){
List<Users> users = this.usersRepositoryQueryAnnotation.queryByNameUseHQL("杜程程");
for (Users u:users
) {
System.out.println(u);
}
}
@Test
public void queryByNameUseSQL(){
List<Users> users = this.usersRepositoryQueryAnnotation.queryByNameUseSQL("杜程程");
for (Users u:users
) {
System.out.println(u);
}
}
@Test
@Transactional//@Test和@Transactional一起使用时事务是自动回滚的
@Rollback(false)
public void updateUsersNameById(){
this.usersRepositoryQueryAnnotation.updateUsersNameById("张作霖",3);
}
@Modifying注解的作用是什么?
@Modifying //需要执行一个更新操作
SpringBoot整合Spring Data JPA-CrudRepository接口使用
CrudRepository接口的作用是什么?
主要是完成一些增删改查操作
CrudRepository接口的继承结构是什么样的?
CrudRepository接口继承Repository接口
CrudRepository接口中有哪些常见方法?
Save() //添加或更新
findOne(ID) //根据id查询
findAll() //查询所有
delete(ID) //根据id删除
SpringBoot整合Spring Data JPA-PagingAndSortingRepository接口使用
PagingAndSortingRepository接口的作用是什么?
PagingAndSortingRepository接口提供了分页和排序的操作
PagingAndSortingRepository的继承结构是什么样的?
PagingAndSortingRepository接口继承了CrudRepository接口
PagingAndSortingRepository排序的步骤是什么?
1. 编写接口类UsersRepository继承PagingAndSortingRepository接口
/**
* PagingAndSortingRepository接口
*/
public interface UsersRepositoryPagingAndSortingRrpository extends PagingAndSortingRepository<Users,Integer> {
}
2. 排序测试
/**
* PagingAndSortingRepository接口测试
* 排序测试
*/
@Test
public void sorting(){
//Order 定义排序规则
Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id");
//Sort 封装了排序规则
Sort sort = new Sort(order);
List<Users> list = (List<Users>) this.usersRepositoryPagingAndSortingRrpository.findAll(sort);
for (Users u:list
) {
System.out.println(u);
}
}
PagingAndSortingRepository分页的步骤是什么?
继承PagingAndSortingRepository接口
测试分页
/**
* PagingAndSortingRepository接口测试
* 分页测试
*/
@Test
public void paging(){
/**
* Pageable:封装了分页的参数,当前页,每页显示的条数。
* 注意:它的当前页是从0开始的
* PageRequest page当前页 size每页显示的条数
*/
Pageable pageable = new PageRequest(0,2);
Page<Users> page = this.usersRepositoryPagingAndSortingRrpository.findAll(pageable);
System.out.println("当前数据的总条数:"+page.getTotalElements());
System.out.println("总页数:"+page.getTotalPages());
List<Users> list = page.getContent();
for (Users u:list
) {
System.out.println(u);
}
}
SpringBoot整合Spring Data JPA-JpaRepository接口使用
JpaRepository接口的作用是什么?
JpaRepository接口对继承的父接口中的方法的返回值进行适配(转换)。
(其父接口的返回值是Iterable<>类型,而JpaRepository接口的返回值类型是List<>)
JpaRepository继承结构是什么样的?
JpaRepository接口继承了PagingAndSortingRepository接口
Spring Data JPA-JPASpecificationExecutor接口使用
JPASpecificationExecutor接口的作用是什么?
JPASpecificationExecutor接口主要是提供了多条件查询的支持,并且可以在查询中添加分页和排序
与PagingAndSortingRepository不同。
PagingAndSortingRepository是对查询所有的结果做排序和分页处理
而它是根据查询条件对查询的结果做分页和排序处理
JPASpecificationExecutor接口的继承结构是什么样的?
JPASpecificationExecutor接口单独存在,完全独立。
一般情况下JPASpecificationExecutor接口和JPA-JpaRepository接口搭配使用
/**
* JpaSpecificationExecutor接口
*/
public interface UsersRepositoryJpaSpecificationExecutor extends JpaRepository<Users,Integer>, JpaSpecificationExecutor<Users> {
}
Specification对象的作用是什么?
用于封装查询条件
/**
* JpaSpecificationExecutor多条件封装查询
*/
@Test
public void jpaSpecificationExecutor(){
Specification<Users> spe = new Specification() {
/**
*
* @param root:查询对象的属性的封装
* @param criteriaQuery:封装了我们要执行的查询中的部分的各个部分的信息:select from order...
* @param criteriaBuilder :查询条件的构造器。定义不同的查询条件
* @return
*/
@Override
public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
/**
* where name = ? and age = ?
*/
List<Predicate> list = new ArrayList<>();
list.add(criteriaBuilder.equal(root.get("name"),"张作霖"));
list.add(criteriaBuilder.equal(root.get("age"),"18"));
Predicate[] predicates = new Predicate[list.size()];
return criteriaBuilder.and(list.toArray(predicates));
}
};
List<Users> all = this.usersRepositoryJpaSpecificationExecutor.findAll(spe);
for (Users u:all
) {
System.out.println(u);
}
}
SpringBoot整合Spring Data JPA-建立双向一对多关联映射
@GeneratedValue注解的作用是什么?
设置主键自增
@ManyToOne注解的作用是什么?
多对一
@JoinColumn注解的作用是什么?
设者外键
SpringBoot整合Spring Data JPA-建立双向多对多关联映射
@ManyToMany注解的作用是什么?
多对多
@JoinTable注解的作用是什么?
设置中间表
创建一个菜单实体,包含menusid、menusname、menusurl、fatherid属性,与Roles为多对多关联关系,一个角色可以拥有多个菜单,一个菜单可以分配个多个角色。
package com.bjsxt.pojo;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "t_menus")
public class Menus {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "menusid")
private Integer menusid;
@Column(name = "menusname")
private String menusname;
@Column(name = "menusurl")
private String menusurl;
@Column(name = "fatheriod")
private Integer fatheriod;
@ManyToMany(mappedBy = "menus")
private Set<Roles> roles = new HashSet<>();
public Set<Roles> getRoles() {
return roles;
}
public void setRoles(Set<Roles> roles) {
this.roles = roles;
}
public Integer getMenusid() {
return menusid;
}
public void setMenusid(Integer menusid) {
this.menusid = menusid;
}
public String getMenusname() {
return menusname;
}
public void setMenusname(String menusname) {
this.menusname = menusname;
}
public String getMenusurl() {
return menusurl;
}
public void setMenusurl(String menusurl) {
this.menusurl = menusurl;
}
public Integer getFatheriod() {
return fatheriod;
}
public void setFatheriod(Integer fatheriod) {
this.fatheriod = fatheriod;
}
@Override
public String toString() {
return "Menus{" +
"menusid=" + menusid +
", menusname='" + menusname + ''' +
", menusurl='" + menusurl + ''' +
", fatheriod=" + fatheriod +
", roles=" + roles +
'}';
}
}
SpringBoot整合Spring Data JPA-操作双向多对多关联映射
编写测试代码,创建角色一个对象,创建两个菜单对象,建立角色对象与菜单对象的关系,并插入到表中。
package com.bjsxt.pojo;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "t_roles")
public class Roles {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "rolesid")
private Integer rolesid;
@Column(name = "rolesname")
private String rolesname;
public Set<Menus> getMenus() {
return menus;
}
public void setMenus(Set<Menus> menus) {
this.menus = menus;
}
@OneToMany(mappedBy = "roles")
private Set<Users> users = new HashSet<>();
@Override
public String toString() {
return "Roles{" +
"rolesid=" + rolesid +
", rolesname='" + rolesname + ''' +
", users=" + users +
", menus=" + menus +
'}';
}
@ManyToMany(cascade = CascadeType.PERSIST,fetch = FetchType.EAGER)
@JoinTable(name = "t_roles_menus",joinColumns = @JoinColumn(name = "role_id"),inverseJoinColumns =@JoinColumn(name = "menu_id"))
private Set<Menus> menus = new HashSet<>();
public Integer getRolesid() {
return rolesid;
}
public void setRolesid(Integer rolesid) {
this.rolesid = rolesid;
}
public String getRolesname() {
return rolesname;
}
public void setRolesname(String rolesname) {
this.rolesname = rolesname;
}
public Set<Users> getUsers() {
return users;
}
public void setUsers(Set<Users> users) {
this.users = users;
}
}
测试代码
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = App.class)
public class ManyToManytest {
@Autowired
private RolesRepository rolesRepository;
@Test
public void manyToManytestSave(){
Menus menus = new Menus();
menus.setMenusname("尚学堂管理系统");
menus.setFatheriod(0);
Menus menus2 = new Menus();
menus2.setMenusname("尚学堂项目管理");
menus2.setFatheriod(1);
Roles roles = new Roles();
roles.setRolesname("项目经理");
roles.getMenus().add(menus);
roles.getMenus().add(menus2);
menus.getRoles().add(roles);
menus2.getRoles().add(roles);
this.rolesRepository.save(roles);
}
}