Spring Boot学习笔记(二)——Spring-data-jpa

时间:2023-01-27 16:06:34

JPA简介

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

JPA是一套规范,不是一套产品。Hibernate是一套产品,如果这些产品实现了JPA规范,那么我们可以叫它们为JPA的实现产品。使用JPA,就可以把我们的应用完全从Hibernate中解脱出来 

Spring-data-jpa就是基于Hibernate的实现,配合Spring Boot可以更加快速高效的开发我们的项目,其使用简单快捷,甚至可以不用写一条SQL语句,基本可以满足大部分需求,深受广大开发者的青睐。

Spring-data-jpa主要类介绍

Spring-data-jpa的提供了这么几个类供我们的crud操作:

CrudRepository:基本的增删改查操作接口

QueryByExampleExecutor:根据实例条件查询接口

PagingAndSortingRepository:分页和排序接口集成CrudRepository接口

JpaRepository:继承了上面所有接口

由此可见我们只需实现JpaRepository接口便可拥有上面所有功能

Spring-data-jpa基本使用

添加pom依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--mysql依赖-->
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>

修改配置文件:application.yml 增加数据库连接配置,修改为自己的数据库

#设置端口
server:
  port: 8080
  context-path: /
#开发环境日志
logging:
  config: log4j2-dev.xml
spring:
#############################################主库配置#########################################
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/blog?useUnicode=true&characterEncoding=utf-8&characterSetResults=utf-8
    username: root
    password: 123456
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

创建实体类UserInfo

@Entity
@Table(name = "user_info")
public class UserInfo implements Serializable {

    @Id
    @GeneratedValue
    @Column(name = "user_id")
    private Integer userId;

    @Column(name = "user_name")
    private String userName;
    省略get()/set()方法
}

@Entity:表明这是个实体类

@Table(name = "user_info"):映射数据库表

@Column(name = "user_id"):映射数据库字段

@GeneratedValue:表明为主键id

创建接口类UserInfoRepository继承JpaRepository

public interface UserInfoRepository extends JpaRepository<UserInfo,Integer> {
}

创建service实现类UserInfoServiceImpl(接口在这省略)

@Service
public class UserInfoServiceImpl implements UserInfoService {

    @Autowired
    private UserInfoRepository userInfoRepository;

    @Override
    public UserInfo findAll(Integer id){
        UserInfo user = userInfoRepository.findOne(id);
        return user;
    }
}

创建控制层UserInfoController

@Controller
public class UserInfoController {

    @Autowired
    private UserInfoService userInfoService;

    @RequestMapping(value = "/findOne")
    @ResponseBody
    public UserInfo findAll(@RequestParam("id") Integer id){
        UserInfo user = userInfoService.findOne(id);
        return user;
    }
}

到此我们就完成了一个简单的查询操作,接下来创建数据库,运行项目(会自动创建数据表),往数据库手动添加一条信息,然后打开浏览器访问 http://127.0.0.1:8080/findOne?id=1 即可看到结果。

jpa的分页排序操作:修改UserInfoServiceImpl实现类即可

@Service
public class UserInfoServiceImpl implements UserInfoService {

    @Autowired
    private UserInfoRepository userInfoRepository;

    @Override
    public Page<UserInfo> findOne(Integer id){
        //排序
        Sort sort = new Sort(Sort.Direction.DESC,"排序字段");
        //分页(从第一页开始,每页10条数据)
        Pageable pageable = new PageRequest(1,10,sort);
        Page<UserInfo> page = userInfoRepository.findAll(pageable);
        return page;
    }
}

JpaRepository接口提供的其他方法大家可以自己去尝试很简单,这里要说的是jpa是一种规范,那么他的查询方法同样有严格的命名定义,除了一些简单增删改查外,稍微复杂点的如 findByNameLike、findByNameStartingWith 等一系列方法都是遵循严格的命名定义不能随便写,下面给出jpa按规则查询的方法:

Keyword Sample JPQL snippet
IsNotNull findByAgeNotNull ...  where x.age not null
Like findByNameLike ...  where x.name like ?1
NotLike findByNameNotLike ...  where x.name not like ?1
StartingWith findByNameStartingWith ...  where x.name like ?1(parameter bound with appended %)
EndingWith findByNameEndingWith ...  where x.name like ?1(parameter bound with prepended %)
Containing findByNameContaining ...  where x.name like ?1(parameter bound wrapped in %)
OrderBy findByAgeOrderByName ...  where x.age = ?1 order by x.name desc
Not findByNameNot ...  where x.name <> ?1
In findByAgeIn ...  where x.age in ?1
NotIn findByAgeNotIn ...  where x.age not in ?1
True findByActiveTrue ...  where x.avtive = true
Flase findByActiveFalse ...  where x.active = false
And  findByNameAndAge ...  where x.name = ?1 and x.age = ?2
Or findByNameOrAge ...  where x.name = ?1 or x.age = ?2
Between findBtAgeBetween ...  where x.age between ?1 and ?2
LessThan findByAgeLessThan ...  where x.age  <  ?1
GreaterThan findByAgeGreaterThan ...  where x.age > ?1
After/Before ... ...
IsNull findByAgeIsNull ...  where x.age is null
我们只需要在接口中按规则定义这些方法即可,不用写实现直接使用即可,那么问题来了,这些方法名字又长记不住怎么办,能不能自己定义呢,答案是肯定的,这里给出例子,在UserInfoRepository接口中定义方法,通过@Query注解可以自定义SQL语句,这样我们就可以使用我们自己的CRUD方法了,然后直接在service中调用即可。 注意:jpa的sql是面向对象的,因此from后的表名可以使用相应的实体类,占位符用?1代表参数里的第几个参数,相当于mybatis参数中的@param
public interface UserInfoRepository extends JpaRepository<UserInfo,Integer> {

    /**
     * 根据用户名查询用户信息
     * @param userName
     * @return
     */
    @Query("select u from UserInfo u where u.userName=?1")
    UserInfo findUserInfoByName(String userName);

    /**
     * 查询用户信息
     * @return
     */
    @Query("select u from UserInfo u ")
    UserInfo findUserInfo();
}
Spring-data-jpa的简单操作到此就结束了,怎么样是不是很简单呢,当然还有更加高级的玩法,我们可以通过继承JpaSpecificationExecutor来扩展我们的复杂查询操作,在下一篇中我会做详细介绍以及对jpa的封装,让我们的开发变得更加方便易懂