JPA配置,简单使用以及常见问题

1.引入pom依赖

<!--springboot-JPA-->
<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--mysql连接-->
<dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
</dependency>

2.配置数据源

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/joe?serverTimezone=UTC
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

  jpa:
    show-sql: true

2.1 driver-class-name(驱动类)

根据mysql版本不同不一样,有的是com.mysql.cj.jdbc.Driver,有的是com.mysql.jdbc.Driver,不会报错,但是会有提示信息。

提示:Loading class com.mysql.jdbc.Driver‘. This is deprecated. The new driver class is com.mysql.cj.jdbc.Driver‘.

2.2 time zone 异常

异常:java.sql.SQLException: The server time zone value ‘?D1ú±ê×?ê±??‘ is unrecognized or represents more than one time zone.

解决:在datasource-url后拼接参数 serverTimezone=UTC

3.生成数据库表实体类domain

@Data
@Entity
@Table(name = "user")
public class User implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Long userId;

    @Column(name = "user_name")
    private String userName;

    private Long age;

    private String gender;

    private String address;
}

3.1 实体类建议用工具生成,因为jpa要求实体类中的字段都必须在数据库中找到对应列,即类属性只能比表字段少不能多,否则会报异常:

org.springframework.dao.InvalidDataAccessResourceUsageException

如何生成 IDEA自动生成JPA实体

3.2 数据库所有的表必须要有主键,jpa要求所有的表都必须有主键列,实体类必须有@Id标注,可以是联合主键,但是不能没有,没有的话会报异常:

org.hibernate.AnnotationException: No identifier specified for entity: com.joe.jpa.domain.User

联合主键如何使用 JPA联合主键

4.编写dao层

@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
}

1.jpa已经给我们提供了单表的增删改查操作,只需要在dao接口上实现 JpaRepository<T, ID>接口,就可以通过接口里的方法完成crud操作。

其中JpaRepository里的泛型,T是表的实体类,ID是表的主键对应的实体类属性数据类型,我这里是<User, Integer>。

5.测试类

即使自定义的UserRepository没有编写任何代码,注入后一样可以能使用 save(),findXXX(),delete(),count()等方法,并且测试有效,其实是JPA内部 CrudRepository 提供, SimpleJpaRepository 实现的,而 JpaRepository 是CrudRepository的子类,我们又实现了 JpaRepository所以就可以直接用。

详细类图在 JpaRepository 中 右键>Diagrams>show Diagrams...>java class Diagrams 可以查看。 图文步骤:IDEA查看类继承关系

5.1 保存

//保存和批量保存
@Test
public void testSave() {

    //保存
    User user = new User();
    user.setUserName("张三");
    user.setAge(23);
    user.setGender("男");
    userRepository.save(user);
    log.info("保存成功,主键:{}", user.getUserId());

    //批量保存
    User user2 = new User();
    user2.setUserName("李四");
    user2.setAge(27);
    user2.setGender("男");

    User user3 = new User();
    user3.setUserName("王五");
    user3.setAge(25);
    user3.setGender("女");

    User user4 = new User();
    user4.setUserName("赵六");
    user4.setAge(26);
    user4.setGender("女");

    List<User> list = new ArrayList();
    list.add(user2);
    list.add(user3);
    list.add(user4);
    userRepository.saveAll(list);
    log.info("批量保存成功");
}

JPA中提供了save() 单个数据保存和saveAll()批量保存的方法,但是批量保存也是循环执行的单条保存,

这个可以在运行时控制台打印的SQL或者直接从源码SimpleJpaRepository.saveAll()看出来,

所以大批量的插入最好不要用自带的saveAll()去执行。

批量插入的SQL语句

批量插入saveAll()源码

5.2 查询

JpaRepository提供的可以直接使用的查询虽然只有find()和findAll()两种,但是进行了多次重载,可以满足很多种场景的查询。

5.2.1 查询全部和主键查询

List<T> findAll();

Optional<T> findById(ID var1);

List<T> findAllById(Iterable<ID> var1);

示例:

    @Test
    public void testFindAll() {

        List<User> userList = userRepository.findAll();
        log.info("查询所有:{}", userList);
    }

    @Test
    public void testFindById() {

        //主键查询-查询一个
        Optional<User> userOptional = userRepository.findById(2);
        if (userOptional.isPresent()) {
            log.info("根据主键查询:{}", userOptional.get());
        }

        //主键查询-查询多个
        List<Integer> userIdList = Arrays.asList(new Integer[]{2, 3});
        List<User> userListByIds = userRepository.findAllById(userIdList);
        log.info("根据多个主键查询:{}", userListByIds);
    }
排序查询

List<T> findAll(Sort var1);

排序查询需要借助Sort类实现

Sort类实例化 Sort ageSort = Sort.by(Sort.Direction.DESC, "age");

第一个参数可以省略,默认为Sort.Direction.ASC,第二个参数为要排序的字段对应的实体类属性,例如

@Test
public void testFindSort() {

    //Sort ageSort = Sort.by("age");
    Sort ageSort = Sort.by(Sort.Direction.DESC, "age");//倒叙
    List<User> userListSortByAge = userRepository.findAll(ageSort);
    log.info("查询所有按照age倒叙:{}", userListSortByAge);
}
条件查询

<S extends T> List<S> findAll(Example<S> var1);

条件查询需要借助Example类实现

Example实例化 Example<User> userExample = Example.of(user);

参数为装有带条件的数据库实体。例如:

@Test
public void testFindByExample() {

    //等同条件查询
    User user = new User();
    user.setGender("男");
    Example<User> userExample = Example.of(user);
    List<User> userExampleList = userRepository.findAll(userExample);
    log.info("性别为男的用户为:{}", userExampleList);

    //等同条件查询唯一记录,如果查到两条会报错
    User user2 = new User();
    user2.setUserName("张三");
    Example<User> oneUserExample = Example.of(user2);
    Optional<User> oneUser = userRepository.findOne(oneUserExample);
    log.info("名字叫张三的记录:{}", oneUser);
}
分页查询

分页查询需要借助PageRequest类实现

PageRequest实例化: PageRequest pageParam = PageRequest.of(1, 2);

第一个参数为页码,第二个参数为页行数,注意jpa的页码是从0开始算的,传入0查询的是第一页数据。例如

@Test
public void testFindByPage() {
    //分页查询  jpa页码是从0开始的,传入1的话,返回的是第二页的数据
    PageRequest pageParam = PageRequest.of(1, 2);
    Page<User> userListByPage = userRepository.findAll(pageParam);
    long totalElements = userListByPage.getTotalElements();
    int totalPages = userListByPage.getTotalPages();
    List<User> content = userListByPage.getContent();
    log.info("分页查询结果,总记录数:{},总页数:{},选定页数据:{}", totalElements, totalPages, content);
}

以上所以的查询是JPA提供的可以直接使用的查询接口,所有的查询都是等值查询,即column=xxx ,

如要想实现 like, <,> ,isnull ,in等操作,需要手动写SQL或者借助 特殊查询类JpaSpecificationExecutor.findAll()和 查询条件类Specification实现。

jpa排序分组条件查询 jpa自定义查询和复杂条件查询

原文地址:https://www.cnblogs.com/joe-/p/10340531.html

时间: 2024-11-09 01:39:43

JPA配置,简单使用以及常见问题的相关文章

SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法

首先谢谢大佬的简书文章:http://www.jianshu.com/p/45ad65690e33# 这篇文章中讲的是spring中使用spring data jpa,使用了xml配置文件.我现在使用的是spring boot ,没有了xml文件配置就方便多了.我同样尝试了两种方式,也都是简单的查询,需要更复杂的查询,还需要我研究研究.往下看,需要先配置springboot的开发环境,需要大致了解springboot,这里可以看下面两篇文章: springboot 项目新建 springboot

Spring JPA配置讲解

JPA是Java EE5规范之一,是一个orm规范,由厂商来实现该规范.目前有hibernate,OpenJPA,TopLink和EclipseJPA等实现 Spring提供三种方法集成JPA: 1.LocalEntityManagerFactoryBean:适用于那些仅使用JPA进行数据访问的项目.该FactoryBean根据 JPA PersistenceProvider自动检测配置文件进行工作,一般从“META-INF/persistence.xml”读取配置信息.这种方式最简单,但是不能

spring+springMVC+JPA配置详解

SpringMVC是越来越火,自己也弄一个Spring+SpringMVC+JPA的简单框架. 1.搭建环境. 1)下载Spring3.1.2的发布包:Hibernate4.1.7的发布包(没有使用hibernate的API,只是使用了它对JPA的实现):下载 BoneCP 连接池框架及其依赖的jar,下载缓存框架ehcache,全部所用到的jar包如下: ? antlr-2.7.7.jar bonecp-0.7.1.RELEASE.jar bonecp-provider-0.7.1-rc2.j

Docker+nginx+tomcat7配置简单的负载均衡

本文介绍在Docker上配置简单的负载均衡,宿主机为Ubuntu 14.04.2 LTS,两个CentOS容器,宿主机安装Nginx,两台容器安装tomcat7.结构如下: 此方案的原理是将宿主机的端口和docker容器的端口做一个映射(即访问宿主机的某端口会映射到docker容器对应的端口),然后在宿主机通过配置Nginx,即可达到访问宿主机的某端口,按规则分配到指定的服务地址,即完成了负载均衡. 配置步骤 1.准备宿主机,宿主机是Ubuntu 14.04.2 LTS,安装在Vmware中,具

Spring + hibernate + JPA 配置

最近对hibernate的JPA实现比较感兴趣,在此记录下配置方法,备查. 先上maven依赖包配置,这里使用的是spring3.1.2和hibernate3.6.0 <dependencies>                 <dependency>             <groupId>org.hibernate</groupId>             <artifactId>hibernate-entitymanager</

debian配置简单的vsftp服务器

能用到FTP也是在用apache的时候总是在windows下修改好,而又要传到web服务器里.架起来vsftp有会更方便一点! 也是由于只是自己用所以没有做些高难度的动作... 安装vsftp apt-get install update apt-get install vsftpd 查看ftp是否启动 netstat -a|grep ftp* ftp -localhost 控制vsftp是否随系统启动 可以用rcconf这个套件 apt-get install update 然后输入rccon

puppet yum安装配置,简单证书维护

Puppet学习之puppet的安装和配置 一.Puppet简介 Puppet基于ruby语言开发的自动化系统配置工具,可以C/S模式或独立运行,支持对所有UNIX及类UNIX系统的配置管理,最新版本也开始支持对Windows操作系统有限的一些管理.Puppet适用于服务器管的整个过程 ,比如初始安装.配置更新以及系统下线. 二.Puppet的安装 Puppet的安装方式支持源码安装.yum安装以及ruby的gem安装.官网推荐使用yum来安装puppet,方面以后的升级.管理.维护.Cento

配置简单的浮动静态路由,实现链路冗余

网络拓扑如下图. 2.按照上图参数配置各个主机的IP,默认网关一定是连接这个网段的路由器的那个端口的IP地址,要不然只能ping 通本网段的主机,而无法ping通其他网段的主机. 3.在这个实验中交换机是不用配置,没有必要,那么接下来就是配置路由器,还是按照最上面图中的参数设配置路由器.在全局配置模式下 输入interface fastEthernet 0/0 进入接口配置模式,给接口配置ip址,ip address 192.168.1.254 255.255.255.0 接着是no shutd

JPA配置实体时 insertable = false, updatable = false

当使用JPA配置实体时,如果有两个属性(一个是一般属性,一个是多对一的属性)映射到数据库的同一列,就会报错. 这时,在多对一的@JoinColumn注解中添加insertable = false, updatable = false就能解决. 例如:   /** * 用户类 */ @Entity @Table(name = "TBL_SYS_USER") public class SysUser{ @Id @GeneratedValue(generator = "system

Spring data jpa 实现简单动态查询的通用Specification方法

本篇前提: SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法 这篇文章中的第二种方法 实现Specification 这块的方法 只适用于一个对象针对某一个固定字段查询,下面通过泛型改写了这个方法: import java.util.List; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import j