学习笔记:JavaEE开发的颠覆者SpringBoot实战(七)数据访问

本文详细介绍了SpringDataJPA的基本使用,包括实体类定义、数据访问层接口定义及配置,以及如何通过SpringDataJPA进行数据查询、更新、分页排序等操作。此外,还深入探讨了Spring的声明式事务管理,包括事务行为配置、类级别事务使用及SpringDataJPA和SpringBoot下的事务支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. 引入Docker

二. Spring Data JPA

1.Spring Data JPA

是Spring Data的一个子项目,它通过提供基于JPA的Repository极大地减少了JPA作为数据访问方案的代码量。JPA的主要实现有Hibernate,EclipseLink和OpenJPA等

2.定义数据访问层

@Entity
public class Person{
    @Id
    @GeneratedValue
    private int id;
    private String name;
    private Integer age;
    private String address;

    //set get    

}
public interface PersonRepository extends JpaRepository<Person,Long>{
    //定义数据访问操作的方法
}

3.配置使用Spring Data JPA

在spring环境中,使用Spring Data JPA可通过@EnableJpaRepositories来注解开启Spring Data JPA的支持,@EnableJpaRepositories接受的value参数用来扫描数据访问层所在包下的数据访问接口定义。

@Configuration
@EnableJpaRepositories("com.shm.dao")
public class JpaConfiguration{

    @Bean
    public EntityManagerFactory entityManagerFactory(){
        //...    
    }
    
    //还需要配置DataSource,PlatformTransactionManager等相关必须bean

}

4.定义查询方法

4.1 根据属性名查询

public interface PersonRepository extends JpaRepository<Person,Long>{
    //定义数据访问操作的方法
    /**
     *通过名字相等查询,参数为name
     *相当于JPQL:select p from Person p where p.name=?1
     */       
    List<Person> findByName(String anme);

    /**
     *通过名字like查询,参数为name
     *相当于JPQL:select p from Person p where p.name like ?1
     */       
    List<Person> findByNameLike(String name);

    /**
     *通过名字和地址查询,参数为name和address
     *相当于JPQL:select p from Person p where p.name = ?1 and p.address = ?2
     */       
    List<Person> findByNameAndAddress(String name,String address);

}

4.2 使用JPA的NamedQuery查询

支持JPA的NameQuery来定义查询方法,即一个名称映射一个查询语句。

@Entity
@NamedQuery(name="Person.myFindByName",query="select p from Person where p.name=?1")
public class Person{
    @Id
    @GeneratedValue
    private int id;
    private String name;
    private Integer age;
    private String address;

    //set get    

}
public interface PersonRepository extends JpaRepository<Person,Long>{
    //定义数据访问操作的方法
    /**
     *这时我们使用的是NamedQuery里定义的查询语句
     */       
    List<Person> myFindByName(String anme);


}

4.3 使用@Query查询

/**
*使用索引
*/
public interface PersonRepository extends JpaRepository<Person,Long>{
    //定义数据访问操作的方法
    
    @Query("select p from Person p where p.address=?1")      
    List<Person> myFindByAddress(String address);
}


/**
*使用命名参数
*/
public interface PersonRepository extends JpaRepository<Person,Long>{
    //定义数据访问操作的方法
      
    @Query("select p from Person p where p.address= ::address")       
    List<Person> myFindByAddress(String address);
}

/**
*更新查询
*/
public interface PersonRepository extends JpaRepository<Person,Long>{
    //定义数据访问操作的方法
     
    @Modifying 
    @Query("update Person p set p.name=?1")       
    int setName(String name); // 返回的int值表示影响的行数
}

4.4 Specification

数据操作接口实现JpaSpecificationExecutor

public interface PersonRepository extends JpaRepository<Person,Long>,JpaSpecificationEcecutor<Person>{

}


public class CustomerSpecs{

    public static Specification<Person> personFormHefei(){
        return new Specification<Person>(){
            //构造查询条件
            @Override
            public Predicate toPredicate(Root<Person> root,CriteriaQuery<?> query,CriteriaBuilder cb){
                return cb.equal(root.get("address"),"合肥");
            }
        };
    }

}


//静态导入
import static com.shm.springbootdemo.util.CustomerSpecs.*;

//使用
List<Person> person = personRepository.findAll(personFormHefeis);

4.5 分页排序

//定义
public interface PersonRepository extends JpaRepository<Person,Long>{
    List<Person> findByName(String name,Sort sort);
    Page<Person> findByName(String name,Pageable pageable);
}


//排序使用
List<Person> person = personRepository.findByName("xxx",new Sort(Direction.ASC,"age"));


//分页使用
List<Person> person2 = personRepository.findByName("xxx",new PageRequest(0,10));

三. Spring Data JPA

1. 什么是Spring Data REST

Spring Data REST是基于Spring Data的repository之上,可以把 repository 自动输出为REST资源,目前支持Spring Data JPA、Spring Data MongoDB、Spring Data Neo4j、Spring Data GemFire、Spring Data Cassandra的 repository 自动转换成REST服务。注意是自动。简单点说,Spring Data REST把我们需要编写的大量REST模版接口做了自动化实现.

2. restful api

REST是一种设计风格(与具体的语言无关),它的URL主体是资源,是个名词。而且也仅支持HTTP协议,规定了使用HTTP Method表达本次要做的动作,类型一般也不超过那四五种。这些动作表达了对资源仅有的几种转化方式。

常用的HTTP动词有下面五个(括号里是对应的SQL命令)。

    GET(SELECT):从服务器取出资源(一项或多项)。
    POST(CREATE):在服务器新建一个资源。
    PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
    PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
    DELETE(DELETE):从服务器删除资源。
    HEAD:获取资源的元数据。
    OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。

3. 实现

Spring Boot 2.0.0.RELEASE

添加依赖

pom.xml

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>

配置

# DATA REST (RepositoryRestProperties)
spring.data.rest.base-path= # Base path to be used by Spring Data REST to expose repository resources.
spring.data.rest.default-page-size= # Default size of pages.
spring.data.rest.detection-strategy=default # Strategy to use to determine which repositories get exposed.
spring.data.rest.enable-enum-translation= # Enable enum value translation via the Spring Data REST default resource bundle.
spring.data.rest.limit-param-name= # Name of the URL query string parameter that indicates how many results to return at once.
spring.data.rest.max-page-size= # Maximum size of pages.
spring.data.rest.page-param-name= # Name of the URL query string parameter that indicates what page to return.
spring.data.rest.return-body-on-create= # Return a response body after creating an entity.
spring.data.rest.return-body-on-update= # Return a response body after updating an entity.
spring.data.rest.sort-param-name= # Name of the URL query string parameter that indicates what direction to sort results.

四.声明式事务

1. spring的事务机制

所有的数据访问技术都有事务处理机制,这些结束提供了API用来开启事务,提交事务来完成数据操作,或者在发生错误的时候回滚数据。

而spring的事务机制是统一的机制来处理不同数据访问技术的事务处理。spring的事务机制提供了一个PlatformTranasctionManager接口,不同的数据访问技术的事务使用不同的接口实现。

数据访问技术实现
JDBCDatatSourceTrancactionManager
JPAJpaTrancactionManager
HibernateHibernateTrancactionManager
JDOJdoTrancactionManager
分布式事务JtaTrancactionManager

 

 

 

 

 

 

 

2. 声明式事务

spring支持声明式事务,即是用注解来选择需要使用事务的方法,他使用@Transactional注解在方法上表明该方法需要事务支持。这是一个基于AOP的实现操作。被注解的方法在被调用时,spring开启要给新的事务,方法无异常运行结束后,spirng会提交这个事务。

@Trancactional
public void saveSonmething(){
    //操作
}

spring提供一个@EnableTransactionManagement注解在配置类上来开启声名式事务的支持。使用该注解后,spring容器会自动扫描注解@Transcaction的方法和类

@Configuration
@EnableTransactionManagement
public class AppConfig{

}

3. 注解事务行为

 

数名称

功能描述

readOnly

该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。例如:@Transactional(readOnly=true)

rollbackFor

该属性用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如:

指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)

指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})

rollbackForClassName

该属性用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:

指定单一异常类名称:@Transactional(rollbackForClassName="RuntimeException")

指定多个异常类名称:@Transactional(rollbackForClassName={"RuntimeException","Exception"})

noRollbackFor

该属性用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。例如:

指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class)

指定多个异常类:@Transactional(noRollbackFor={RuntimeException.class, Exception.class})

noRollbackForClassName

该属性用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:

指定单一异常类名称:@Transactional(noRollbackForClassName="RuntimeException")

指定多个异常类名称:

@Transactional(noRollbackForClassName={"RuntimeException","Exception"})

propagation

该属性用于设置事务的传播行为,具体取值可参考表6-7。

例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)

isolation

该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况,通常使用数据库的默认隔离级别即可,基本不需要进行设置

timeout

该属性用于设置事务的超时秒数,默认值为-1表示永不超时

4. 类级别使用@Transactional

@Transactional不仅可以注解在方法上,也可以注解在类上。当注解在类上的时候以为这此类的所有public方法都是开启事务的。如果类和方法同时使用注解,则类级别的注解会重载方法级别的注解。

5. Spring Data JPA的事务支持

Spring Data JPA对所有的默认方法都开启了事务支持,并且插叙类事务默认开启readOnly=true属性。

6.Spring Boot的事务支持

springboot默认自动配置事务管理器,并且自动开启注解事务的支持

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值