springboot整合springdatajpa步骤及使用
一:spring data jpa介绍
spring data:其实spring data就是spring提供了一个操作数据的框架。而spirng data jpa只是spring data框架下的一个基于jpa标准操作数据的模块。
spring data jpa:基于jpa的标准对数据进行操作。简化操作持久层的代码。只需要编写接口就可以。
二:springboot整合spring data jpa
1.搭建整合环境:maven工程继承springboot父工程
2.修改pom文件添加坐标
3.在项目中添加application.yml文件
spring:
# 配置数据源
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
username: root
password: root
# 配置连接池
type: com.alibaba.druid.pool.DruidDataSource
# 配置jpa
jpa:
# 配置正向工程
hibernate:
ddl-auto: update
# 配置在控制台打印sql语句
show-sql: true
4.添加实体类
@Entity //表示该类是实体类
@Table(name="tb_users") //表示正向工程生成的表名为tb_users
public class User {
@Id //表示该字段为主键
@GeneratedValue(strategy=GenerationType.IDENTITY) //表示该键生成策略为自增
@Column(name="id") //生成的表中对应的字段为id
private Integer id;
@Column(name="username")
private String name;
@Column(name="age")
private Integer age;
@Column(name="address")
private String address;
...}
5.编写dao接口
public interface UserRepository extends JpaRepository<User, Integer> {
}
6.在pom文件中添加测试启动器的坐标
7.创建启动类
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
8.编写测试代码
//JpaRepository--添加数据
@Test
public void testSave() {
User user = new User();
user.setName("成龙");
user.setAge(42);
user.setAddress("中国深圳");
this.userRepository.save(user);
}
三:spring data jpa提供的核心接口

1.Repository接口
2.CrudRepository接口
3.PagingAndSortingRepository接口
4.JpaRepository接口
5.JpaSpecificationExecutor接口
四:Repository接口的使用
1.提供了方法名称命名查询方式
1.1编写接口
public interface UserRepositoryByName extends Repository<User, Integer> {
//方法名称必须遵循驼峰式命名规则。
//findBy(关键字)+实体属性名(首字母大写)+查询条件(首字母大写)
public List
public List
public List
}
1.2测试代码
//Repository--方法名称命名测试
@Test //单条件查询
public void testFindByName() {
List
for (User user : userList) {
System.out.println(user);
}
}
@Test //多条件查询
public void testFindByNameAndAge() {
List
for (User user : userList) {
System.out.println(user);
}
}
@Test //模糊查询
public void testFindByNameLike() {
List
for (User user : userList) {
System.out.println(user);
}
}
2.提供了基于@Query注解的查询与更新
2.1编写接口
//Repository接口的@query注解查询
public interface UserRepositoryQueryAnnotation extends Repository<User, Integer> {
//采用hibernate的hql语句查询(User类名,name实体属性,:name别名 对应@Param中的key)
@Query("from User where name = :name")
public List
//采用slq语句
@Query(value="select * from tb_users where username = ?",nativeQuery=true)
public List
//更新操作
@Query("update User set name = :name where id = :id")
@Modifying //需要执行一个更新操作
public void updateUserNameById(@Param("name")String name,@Param("id")Integer id);
}
2.2测试代码
//Repository--@Query注解测试
@Test //hql语句查询
public void testFindByNameUserHQL() {
List
for (User user : userList) {
System.out.println(user);
}
}
@Test //sql语句查询
public void testFindByNameUserSQL() {
List
for (User user : userList) {
System.out.println(user);
}
}
@Test //修改数据
@Transactional //@Test与@Transactional一起使用时,事务是自动回滚的
@Rollback(false) //取消自动回滚
public void testUpdateUserNameById() {
this.userRepositoryQueryAnnotation.updateUserNameById("葛优", 1);;
}
五:CrudRepository接口
1.CrudRepository接口,主要是完成一些增删改查操作。CrudRepository接口继承Repository接口。

2.编写接口
//CrudRepository接口
public interface UserRepositoryCrudRepository extends CrudRepository<User, Integer> {
}
3.测试代码
//CrudRepository--测试
@Test //添加数据
public void testCrudRepositorySave() {
User user = new User();
user.setAddress("中国杭州");
user.setAge(16);
user.setName("姜文");
this.userRepositoryCrudRepository.save(user);
}
@Test //修改数据
public void testCrudRepositoryUpdate() {
User user = new User();
user.setId(4);
user.setAddress("中国广州");
user.setAge(28);
user.setName("姜文");
this.userRepositoryCrudRepository.save(user);
}
@Test //根据id查询
public void testCrudRepositoryFindById() {
Optional
System.out.println(user);
}
@Test //查询所有
public void testCrudRepositoryFindAll() {
List
for (User user : userList) {
System.out.println(user);
}
}
@Test //根据id删除数据
public void testCrudRepositoryDeleteById() {
this.userRepositoryCrudRepository.deleteById(4);
}
六:PagingAndSortingRepository接口
1.该接口提供了分页与排序的操作。该接口集成了CrudRepository接口。

2.编写接口
//PagingAndSortingRepository接口
public interface UserRepositoryPagingAndSorting extends PagingAndSortingRepository<User, Integer> {
}
3.测试代码
//PagingAndSortingRepository--测试
@Test //排序测试
public void testPagingAndSortingRepositorySort() {
//Sort对象封装了排序规则
Sort sort = new Sort(Direction.DESC, "id");
List
for (User user : userList) {
System.out.println(user);
}
}
@Test //分页测试
public void testPagingAndSortingRepositoryPaging() {
//Pageable封装了分页的参数,当前页,每页显示的条数。当前页是从零开始。
//PageRequest.of(page,size): page当前页,size每页显示的条数
Pageable pageable = PageRequest.of(0, 2);
Page
System.out.println("总条数:"+page.getTotalElements());
System.out.println("总页数:"+page.getTotalPages());
for (User user : page.getContent()) {
System.out.println(user);
}
}
@Test //排序+分页排序
public void testPagingAndSortingRepositorySortAndPaging() {
//PageRequest.of(int page, int size, Direction direction, String... properties)
//page:当前页,size:每页条数,direction:排序方向,properties:以哪个实体属性进行排序
Pageable pageable = PageRequest.of(0, 2, Direction.DESC, "id");
Page
System.out.println("总条数:"+page.getTotalElements());
System.out.println("总页数:"+page.getTotalPages());
for (User user : page.getContent()) {
System.out.println(user);
}
}
七:JpaRepository接口
1.该接口继承了PagingAndSortingRepository接口。对继承的父接口中的方法的返回值进行适配。

2.编写接口
//参数一T:当前需要映射的实体
//参数二ID:当前映射的实体中的OID(主键)的类型
public interface UserRepository extends JpaRepository<User, Integer> {
}
3.测试代码
八:JpaSpecificationExecutor接口
1.该接口主要是提供了多条件查询的支持,并且可以在查询中添加分页与排序。JpaSpecificationExecutor是单独存在。完全独立。

2.编写接口
//JpaSpecificationExecutor接口
public interface UserRepositorySpecification extends JpaRepository<User, Integer>, JpaSpecificationExecutor
}
3.测试代码
//6.JpaSpecificationExecutor--测试
@Test //单条件测试
public void testJpaSpecificationExecutor1() {
//Specification:用于封装查询条件, 接口的对象用匿名内部类。
Specification
//Predicate:封装了单个的查询条件
//Root
//CriteriaQuery query:封装了我们要执行查询中的各个部分信息,select from order by
//CriteriaBuilder criteriaBuilder:查询条件的构造器,定义不同的查询条件
@Override
public Predicate toPredicate(Root
//where name = "周星驰"
//equal(arg0,arg1): arg0:查询的条件属性 arg1:条件的值
Predicate pre = criteriaBuilder.equal(root.get("name"), "周星驰");
return pre;
}
};
List
for (User user : userList) {
System.out.println(userList);
}
}
@Test //多条件测试
public void testJpaSpecificationExecutor2() {
Specification
@Override
public Predicate toPredicate(Root
//一个Predicate封装一个查询条件,两个条件用数组或集合
Predicate[] pre = new Predicate[] {
criteriaBuilder.equal(root.get("name"), "周星驰"),
criteriaBuilder.equal(root.get("age"), 36)
};
//and(pre):pre是可变数组,通过and方法将多个条件连接起来
return criteriaBuilder.and(pre);
}
};
List
for (User user : userList) {
System.out.println(user);
}
}
4.多条件查询的第二种写法
@Test //多条件测试第二种写法
public void testJpaSpecificationExecutor3() {
Specification
@Override
public Predicate toPredicate(Root
//一个Predicate封装一个查询条件,两个条件用数组或集合
//and(pre):pre是可变数组,通过and方法将多个条件连接起来
//return criteriaBuilder.and(criteriaBuilder.equal(root.get("name"), "周星驰"),criteriaBuilder.equal(root.get("age"), 36));
//where (name = "周星驰" and age = 36) or id = 1 --and的优先级比or高,不用括号也可以
return criteriaBuilder.or(criteriaBuilder.and(criteriaBuilder.equal(root.get("name"), "周星驰"),criteriaBuilder.equal(root.get("age"), 36)),criteriaBuilder.equal(root.get("id"), "1"));
}
};
//sort封装排序规则
Sort sort = new Sort(Direction.DESC, "id");
List
for (User user : userList) {
System.out.println(user);
}
}
九:关联映射操作
1.一对多的关联关系
需求:角色与用户的一对多的关联关系
角色:一方(Role) 用户:多方(User)
1.1 User实体类
//多对一关系
@ManyToOne(cascade=CascadeType.PERSIST) //级联添加(添加用户的同时添加相应的角色)
@JoinColumn(name="role_id") //维护外键
private Role role; //tostring()方法中不能打印输出role对象,编译会报错
1.2 Role实体类
//一对多关系
@OneToMany(mappedBy="role") //添加user中外键对象属性
private Set
1.3测试多对一的关联关系
//多对一关系测试
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes=Application.class)
public class OneToManyTest {
@Autowired
private UserRepository userRepository;
//多对一关系的添加
@Test
public void testSave() {
//创建一个用户
User user = new User();
user.setAddress("中国杭州");
user.setAge(32);
user.setName("姜文");
//创建一个角色
Role role = new Role();
role.setRolename("管理员");
//关联
role.getUsers().add(user); //主表(先添加主表数据)
user.setRole(role); //从表(再添加从表数据)
//保存
this.userRepository.save(user);
}
//多对一关系的查询
@Test
public void testFind() {
Optional
System.out.println(user.get()); //打印输出User对象
String rolename = user.get().getRole().getRolename(); //获取rolename
System.out.println(rolename);
}
}
2.多对多的关联关系
需求:角色与菜单多对多关联关系
角色:多方 菜单:多方
2.1 Role实体类
//@JoinTable:映射中间表
//中间表中属性joinColumns:当前表主键所关联的中间表中的外键字段
//CascadeType.PERSIST添加数据时级联新建,FetchType.EAGER表示关系类在主体类加载的时候同时加载,立即加载
@ManyToMany(cascade=CascadeType.PERSIST,fetch=FetchType.EAGER)
@JoinTable(name="t_role_menu",joinColumns=@JoinColumn(name="role_id"),inverseJoinColumns=@JoinColumn(name="menu_id"))
private Set

浙公网安备 33010602011771号