jpa的使用

目录

什么是jpa?

spring data jpa

springboot演示jpa

1.pom依赖

2.application.properties 配置

3.建立用户实体类

4. 声明 UserRepository接口,继承JpaRepository

5.定义测试类,演示添加操作

6.查询


什么是jpa?

        JPA是Java Persistence API的简称,中文名Java持久层API, 是 Sun 官方提出的 Java 持久化规范。它为 Java 开发人员提供了一种对象/ 关联映射工具来管理 Java 应用中的关系数据。 他的出现主要是为了简化现有的持久化开发工作和整合 ORM 技术。

spring data jpa

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

springboot演示jpa

1.pom依赖

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.45</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

2.application.properties 配置

spring.datasource.url=jdbc:mysql://localhost:3306/java-jpa?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.username=root
spring.datasource.password=x5
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#这是创建数据库表的配置
spring.jpa.properties.hibernate.hbm2ddl.auto=update
#这是数据库的方言配置。
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
#该配置当在执行数据库操作的时候会在控制台打印 sql 语句,方便我们检查排错等。
spring.jpa.show-sql=true

        这里介绍一下hibernate.hbm2ddl.auto的配置

  • create:表示每次加载Hibernate时都会删除上一次生成的表(包括数据), 然后重新生成新表,即使两次没有任何修改也会这样执行。 适用于每次执行单测前清空数据库的场景。

  • create-drop:表示每次加载Hibernate时都会生成表, 但当SessionFactory关闭时,所生成的表将自动删除。

  • update:最常用的属性值,第一次加载Hibernate时创建数据表 (前提是需要先有数据库),以后加载Hibernate时不会删除上一次生成的表 ,会根据实体更新,只新增字段,不会删除字段(即使实体中已经删除)。

  • validate:每次加载Hibernate时都会验证数据表结构, 只会和已经存在的数据表进行比较,根据model修改表结构,但不会创建新表。 不配置此项,表示禁用自动建表功能。

3.建立用户实体类

@Entity
public class User {
    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer id;
    @Column(nullable = false, unique = true)
    private String username;
    @Column(nullable = false)
    private String password;
    //省略了get,set方法。。。
}

        这里的一些注解解释如下:

  • @Entity 是一个类注解,用来注解该类是一个实体类用来进行和数据库中的表 建立关联关系,首次启动项目的时候,默认会在数据中生成一个同实体类相同名 字的表(table),也可以通过注解中的 name 属性来修改表(table)名称, 如@Entity(name=“user”) , 这样数据库中表的名称则是 user 。 该注解十分重要,如果没有该注解首次启动项目的时候你会发现数据库没有生 成对应的表。

  • @Table 注解也是一个类注解,该注解可以用来修改表的名字, 该注解完全可以忽略掉不用,@Entity 注解已具备该注解的功能。

  • @Id 类的属性注解,该注解表明该属性字段是一个主键,该属性必须具备,不可缺少。

  • @GeneratedValue 该注解通常和 @Id 主键注解一起使用,用来定义主键的 呈现形式,该注解通常有多种使用策略,先总结如下: @GeneratedValue(strategy= GenerationType.IDENTITY) 该注解由数据库自动生成,主键自增型,在 mysql 数据库中使用最频繁,oracle 不支持。

    • @GeneratedValue(strategy= GenerationType.AUTO) 主键由程序控制,默认的主键生成策略,oracle 默认是序列化的方式,mysql 默认是主键自增的方式。
    • @GeneratedValue(strategy= GenerationType.SEQUENCE) 根据底层数据库的序列来生成主键,条件是数据库支持序列,Oracle支持,Mysql不支持。
    • @GeneratedValue(strategy= GenerationType.TABLE) 使用一个特定的数据库表格来保存主键,较少使用。

        上面这些主键生成策略中,以 mysql 为例, IDENTITY 和 AUTO 用的较多, 二者当中 IDENTITY 用的多些,以下文章当中主键均使用 @GeneratedValue(strategy= GenerationType.IDENTITY) 的生成策略。

  • @Column 是一个类的属性注解,该注解可以定义一个字段映射到数据库属性的具体特征,比如字段长度,映射到数据库时属性的具体名字等。

  • @Transient 是一个属性注解,该注解标注的字段不会被映射到数据库当中。

4. 声明 UserRepository接口,继承JpaRepository

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

        JpaRepository<User,Integer> 泛型中的第一个参数是实体类的类名,第二个参数是主键的类型

 这里的 JpaRepository继承了接口PagingAndSortingRepository和QueryByExampleExecutor。 而PagingAndSortingRepository又继承CrudRepository。

 

所以,JpaRepository接口同时拥有了基本CRUD功能以及分页功能。 因此,这里我们可以继承JpaRepository, 从而获得Spring为我们预先定义的多种基本数据操作方法。

5.定义测试类,演示添加操作

    @Autowired
    UserRepository userRepository;
    @Test
    public void userAddTest(){
        User user = new User();
        user.setUsername("五十六精研");
        user.setPassword("123456");
        userRepository.save(user);
    }

运行后发现添加完成

6.查询

        查询可以分为基本查询和自定义查询,一种是 spring data 默认已经实现了的, 只需要继承JpaRepository,一种是根据查询的方法来自动解析成 SQL。

1.基本查询

基本查询只需要调用 spring data 中实现好的放法即可。

@Test
    public void testQuery(){
        User user=new User();
        user.setUsername("张三");
        user.setPassword("123");
        user.setId(2);
        System.out.println("无条件查询全部:"+userRepository.findAll());
        System.out.println("查询记录数量:"+userRepository.count());
        System.out.println("根据id查询:"+userRepository.findById(2));
        //save方法id存在是修改,不存在是添加
        //System.out.println("修改:"+userRepository.save(user));
        //根据id删除
        //userRepository.deleteById(6);
    }

2.自定义查询

自定义的简单查询就是根据方法名来自动生成SQL, 主要的语法是findXXBy,readAXXBy,queryXXBy,countXXBy, getXXBy 后面跟属性名称,其中属性名开头的第一个字母大小写都可以,例如:

  • User findByUsername(String username); 
  • List findByUsernameAndPassword(String username, String password);
  • Integer deleteById(Integer id);
  • Integer countByUserName(String username);
  • List findByusername(String username);

使用方法就是将自定义的方法在UserRepository类中定义,就可以调用了。

3.复杂的查询

3.1 分页查询

        在实际的开发中我们需要用到分页、删选、连表等查询的时候就需要特殊的方法 或者自定义 SQL,以分页查询为例,spring data jpa已经帮我们实现了分页的功能, 在查询的方法中,需要传入参数Pageable,当查询中有多个参数的时候 Pageable建议做为最后一个参数传入。Pageable是 spring 封装的分页实现类, 使用的时候需要传入页数、每页条数和排序规则。

@Test
    public void testPage(){
        //page页(从0开始),size条
        int page=0,size=2;
        Sort sort = Sort.by(Sort.Direction.ASC,"id");//查询的排序选项。提供一个属性,以进行排序
        Pageable pageable = PageRequest.of(page,size,sort);//可以加sort排序也可以不加
       Page<User> pageUser=userRepository.findAll(pageable);
        System.out.println("分页查询后的结果:"+pageUser.toList());
    }

其中 Sort中的构造方法是私有的private 所以需要使用Sort.by来调用。

        Sort.by(Sort.Direction.ASC,"id");的第一个参数是正序或倒序,第二个参数 是进行排序的字段,需要排序的字段可以多个。

        Pageable中的构造方法也是受保护的protected所以需要使用PageRequest.of来调用。 其中page是页,size是每页多少条。

        jpa中的分页是先按照每页多少条进行分页后,在按页进行查询,如果查询的页 超过了所分的页,那么查询的结果将为空的集合,负数则会报错。

        由于Page类继承了Slice类,而Slice又继承了Streamable类,所以Page可以调用 Streamable类中的toList()方法获取查询后的数据。

3.2 自定义SQL查询

和Hibernate一样使用Hql语句

3.2.1 第一种使用注解@Query

    @Transactional
    @Modifying
    @Query("update User u set u.username = ?1 where u.id = ?2")
    int modifyByIdAndUserId(String username, Integer id);

    @Transactional
    @Modifying
    @Query("delete from User where id = ?1")
    void deleteByUserId(Integer id);

    @Query("from User")
    List<User> queryAll();

删除与修改的话注意要加@Modifying 和 @Transactional注解

3.2.2 使用EntityManager完全自定义可拼接的sql

编写查询语句:

    @Autowired
    EntityManager entityManager;

    @Test
    public void testSql2(){
        String sql="select * from user";
        List<User> list = entityManager.createNativeQuery(sql,User.class).getResultList();
        System.out.println(list);
    }    

        entityManager.createNativeQuery(sql)执行sql语句后返回Query对象 并调用Query对象中的getResultList()方法获取sql查询之后的数据。

以上就是jap的内容。

总结

        jpa是一个对数据库操作的框架,他已经为我们定已好了简单的对单表CRUD的操作。 也可以通过自定义的方法名实现操作,还可以使用注解和实体管理器(entityManager) 自定义sql,并为我们实现了分页查询。

参照文档:

一文搞懂 Spring JPA

jpa自定义sql的三种方式_ChuandongTan的博客-CSDN博客_jpa自定义sql查询