【Spring Boot系列学习】07.数据存储SQL-关系型数据库Spring-data-jpa

一、spring-data-jpa

1.jpa

JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate,TopLink,JDO等ORM框架各自为营的局面。JPA是在充分吸收了现有Hibernate,TopLink,JDO等ORM框架的基础上发展而来的,具有易于使用,伸缩性强等优点。

注意:JPA是一套规范,不是一套产品,那么像Hibernate,TopLink,JDO他们是一套产品,如果说这些产品实现了这个JPA规范,那么我们就可以叫他们为JPA的实现产品。

2.spring-data-jpa

Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率!

注意:spring data jpa让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现

3.基本查询

基本查询也分为两种,一种是spring data默认已经实现,一种是根据查询的方法来自动解析成SQL。

3.1默认基本查询(预先生成方法)

spring data jpa 默认预先生成了一些基本的CURD的方法,如增、删、改等方法。
其操作步骤:
1).继承JpaRepository(即相当于开发Dao接口)

public interface UserRepository extends JpaRepository<User, Long> {
}

2).使用默认方法(即相当于service层调用dao的方法)

@Test
public void testBaseQuery() throws Exception {
	User user=new User();
	userRepository.findAll();
	userRepository.findOne(1l);
	userRepository.save(user);
	userRepository.delete(user);
	userRepository.count();
	userRepository.exists(1l);
	// ...
}

3.2自定义基础查询

自定义的简单查询就是根据方法名来自动生成SQL,主要的语法是findXXBy,readAXXBy,queryXXBy,countXXBygetXXBy后面跟属性名称:

User findByUserName(String userName);

也使用一些加一些关键字And、 Or

User findByUserNameOrEmail(String username, String email);

具体的关键字,使用方法和生产成SQL如下表所示

KeywordSampleJPQL snippet
AndfindByLastnameAndFirstname… where x.lastname = ?1 and x.firstname = ?2
OrfindByLastnameOrFirstname… where x.lastname = ?1 or x.firstname = ?2
Is,EqualsfindByFirstnameIs,findByFirstnameEquals… where x.firstname = ?1
BetweenfindByStartDateBetween… where x.startDate between ?1 and ?2
LessThanfindByAgeLessThan… where x.age < ?1
LessThanEqualfindByAgeLessThanEqual… where x.age ⇐ ?1
GreaterThanfindByAgeGreaterThan… where x.age > ?1
GreaterThanEqualfindByAgeGreaterThanEqual… where x.age >= ?1
AfterfindByStartDateAfter… where x.startDate > ?1
BeforefindByStartDateBefore… where x.startDate < ?1
IsNullfindByAgeIsNull… where x.age is null
IsNotNull,NotNullfindByAge(Is)NotNull… where x.age not null
LikefindByFirstnameLike… where x.firstname like ?1
NotLikefindByFirstnameNotLike… where x.firstname not like ?1
StartingWithfindByFirstnameStartingWith… where x.firstname like ?1 (parameter bound with appended %)
EndingWithfindByFirstnameEndingWith… where x.firstname like ?1 (parameter bound with prepended %)
ContainingfindByFirstnameContaining… where x.firstname like ?1 (parameter bound wrapped in %)
OrderByfindByAgeOrderByLastnameDesc… where x.age = ?1 order by x.lastname desc
NotfindByLastnameNot… where x.lastname <> ?1
InfindByAgeIn(Collection ages)… where x.age in ?1
NotInfindByAgeNotIn(Collection age)… where x.age not in ?1
TRUEfindByActiveTrue()… where x.active = true
FALSEfindByActiveFalse()… where x.active = false
IgnoreCasefindByFirstnameIgnoreCase… where UPPER(x.firstame) = UPPER(?1)

4.复杂查询

在实际的开发中我们需要用到分页、删选、连表等查询的时候就需要特殊的方法或者自定义SQL

4.1分页查询

spring data jpa已经帮我们实现了分页的功能,在查询的方法中,需要传入参数Pageable ,当查询中有多个参数的时候Pageable建议做为最后一个参数传入

Page<User> findALL(Pageable pageable);    
Page<User> findByUserName(String userName,Pageable pageable);

Pageable 是spring封装的分页实现类,使用的时候需要传入页数、每页条数和排序规则

@Test
public void testPageQuery() throws Exception {
	int page=1,size=10;
	Sort sort = new Sort(Direction.DESC, "id");
    Pageable pageable = new PageRequest(page, size, sort);
    userRepository.findALL(pageable);
    userRepository.findByUserName("testName", pageable);
}

限制查询:有时候我们只需要查询前N个元素,或者支取第一个实体

User findFirstByOrderByLastnameAsc();
User findTopByOrderByAgeDesc();
Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);
List<User> findFirst10ByLastname(String lastname, Sort sort);
List<User> findTop10ByLastname(String lastname, Pageable pageable);

4.2自定义SQL查询

其实Spring data 觉大部分的SQL都可以根据方法名定义的方式来实现,但是由于某些原因我们想使用自定义的SQL来查询,spring data也是完美支持的;在SQL的查询方法上面使用@Query注解,如涉及到删除和修改在需要加上@Modifying.也可以根据需要添加 @Transactional 对事物的支持,查询超时的设置等

@Modifying
@Query("update User u set u.userName = ?1 where u.id = ?2")
int modifyByIdAndUserId(String  userName, Long id);
	
@Transactional
@Modifying
@Query("delete from User where id = ?1")
void deleteByUserId(Long id);
  
@Transactional(timeout = 10)
@Query("select u from User u where u.emailAddress = ?1")
User findByEmailAddress(String emailAddress);

4.3多表查询

多表查询在spring data jpa中有两种实现方式,第一种是利用hibernate的级联查询来实现,第二种是创建一个结果集的接口来接收连表查询后的结果。

具体此处省略,见http://www.ityouknow.com/springboot/2016/08/20/spring-boo-jpa.html

参考:spring-data-jpa中文参考文档

spring-data-jpa的详细介绍和复杂使用

二、springboot集成spring-data-jpa

1.集成项目结构

2.添加依赖

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

需要注意的是,spring-data-jpa是在hibernate的基础上封装的,导入该依赖,也引入了hibernate的jar。

此处说明一下spring-data-jpa和hibernate的关系:

  • ①JPA首先得介绍一下,他只是一套规范和标准,也就是一堆堆的接口,并未实现;
  • ②hibernate是对JPA的一种实现,就是你具体执行持久化操作调用的方法内具体干了什么,都是Hibernate实现的;
  • ③spring-data-jpa则是对hibernate实行了再封装,大大的简化了原本DAO层的实现,也就是现在的repository层。因为本章就是用的spring-data-jpa。
  • ④spring  spring-boot官方对hibernate是一直都有支持的,而对mybatis则没有,但并不代表它不能与mybatis集成。

3.在application.properties中添加配置

##配置数据源
spring.datasource.url=jdbc:mysql://localhost:3306/db_shiro02?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.username = root
spring.datasource.password = 123456
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
##可不添加
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.show-sql= true

说明:spring.jpa.properties.hibernate.hbm2ddl.auto是hibernate的配置属性,其主要作用是:自动创建、更新、验证数据库表结构。

4.代码

实体类

@Entity
@Table(name="sys_user")
public class JpaUser {
    @Id
    @GeneratedValue
    private String id;
    private String usercode;
    private String username;
    private String password;
    private String salt;
    private String locked;
//省略get、set方法和toString方法
}

controller类

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @RequestMapping("/jpalist")
    public String jpalist(){
        logger.info("-------------list start-------------");
        List<JpaUser> list = userService.getAllUsers2();

        logger.info("-------------list end-------------");
        return list.toString();
    }
}

service层(接口省略,实现类如下)

@Service("userService")
public class UserServiceImpl implements UserService{
        @Autowired
        private UserRepository userRepository;
        private Logger logger = LoggerFactory.getLogger(this.getClass());
       
        @Override
        public List<JpaUser> getAllUsers2(){
            logger.info("-------------jpa UserServiceImpl getAllUsers2 start-------------");
            List<JpaUser> list = userRepository.findAll();
            logger.info("-------------jpa UserServiceImpl getAllUsers2 start-------------");
            return list;
        }       
}

repository(即dao接口)

public interface UserRepository extends JpaRepository<JpaUser, String> {
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值