springboot系列文章(九)springboot与jpa

SpringBoot整合SpringData JPA :

先来了解下什么是jpa:是hibernate的抽象是他的一个子集:(jdbc--->mysql)包括映射元数据:
 jPA中的API:
        Persistence  类是用于获取 EntityManagerFactory 实例。该类包含一个名为 createEntityManagerFactory 的 静态方法 。createEntityManagerFactory 方法有如下两个重载版本。 带有一个参数的方法以 JPA 配置文件 persistence.xml 中的持久化单元名为参数

 EntityManagerFactory 接口主要用来创建 EntityManager 实例。该接口约定了如下4个方法:

  •         createEntityManager():用于创建实体管理器对象实例。
  •         createEntityManager(Map map):用于创建实体管理器对象实例的重载方法,Map 参数用于提供 EntityManager 的属性。
  •         isOpen():检查 EntityManagerFactory 是否处于打开状态。实体管理器工厂创建后一直处于打开状态,除非调用close()方法将其关闭。
  •         close():关闭 EntityManagerFactory 。 EntityManagerFactory 关闭后将释放所有资源,isOpen()方法测试将返回 false,其它方法将不能调用,否则将导致IllegalStateException异常。

        EntityManager 是完成持久化操作的核心对象。实体作为普通 Java 对象,只有在调用 EntityManager 将其持久化后才会变成持久化对象。
        EntityManager 对象在一组实体类与底层数据源之间进行 O/R 映射的管理。它可以用来管理和更新 Entity Bean, 根椐主键查找 Entity Bean, 还可以通过JPQL语句查询实体。

  •                 persist (Object entity):用于将新创建的 Entity 纳入到 EntityManager 的管理。该方法执行后,传入 persist() 方法的 Entity 对象转换成持久化状态。
  •                 remove (Object entity):删除实例。如果实例是被管理的,即与数据库实体记录关联,则同时会删除关联的数据库记录
  •                 flush ():同步持久上下文环境,即将持久上下文环境的所有未保存实体的状态信息保存到数据库中。
  •                 setFlushMode (FlushModeType flushMode):设置持久上下文环境的Flush模式。参数可以取2个枚举
  •                 FlushModeType.AUTO 为自动更新数据库实体,
  •                 FlushModeType.COMMIT 为直到提交事务时才更新数据库记录。
  •                 getFlushMode ():获取持久上下文环境的Flush模式。返回FlushModeType类的枚举值。
  •                 refresh (Object entity):用数据库实体记录的值更新实体对象的状态,即更新实例的属性值。
  •                 clear ():清除持久上下文环境,断开所有关联的实体。如果这时还有未提交的更新则会被撤消。
  •                 contains (Object entity):判断一个实例是否属于当前持久上下文环境管理的实体。
  •                 isOpen ():判断当前的实体管理器是否是打开状态。
  •                 getTransaction ():返回资源层的事务对象。EntityTransaction实例可以用于开始和提交多个事务。
  •                 close ():关闭实体管理器。之后若调用实体管理器实例的方法或其派生的查询对象的方法都将抛出 IllegalstateException 异常,除了getTransaction 和 isOpen方法(返回 false)。不过,当与实体管理器关联的事务处于活动状态时,调用 close 方法后持久上下文将仍处于被管理状态,直到事务完成。
  •                 createQuery (String qlString):创建一个查询对象。
  •                 createNamedQuery (String name):根据命名的查询语句块创建查询对象。参数为命名的查询语句。
  •                 createNativeQuery (String sqlString):使用标准 SQL语句创建查询对象。参数为标准SQL语句字符串。
  •                 createNativeQuery (String sqls, String resultSetMapping):使用标准SQL语句创建查询对象,并指定返回结果集 Map的 名称

   EntityTransaction 接口用来管理资源层实体管理器的事务操作。通过调用实体管理器的getTransaction方法 获得其实例

  •                 begin ()  用于启动一个事务,此后的多个数据库操作将作为整体被提交或撤消。若这时事务已启动则会抛出 IllegalStateException 异常。
  •                 commit ()用于提交当前事务。即将事务启动以后的所有数据库更新操作持久化至数据库中。
  •                 rollback ()撤消(回滚)当前事务。即撤消事务启动后的所有数据库更新操作,从而不对数据库产生影响。
  •                 setRollbackOnly ()使当前事务只能被撤消。
  •                 getRollbackOnly ()查看当前事务是否设置了只能撤消标志
  •                 isActive () 查看当前事务是否是活动的。如果返回true则不能调用begin方法,否则将抛出 IllegalStateException 异常;如果返回 false 则不能调用 commit、rollback、setRollbackOnly 及 getRollbackOnly 方法,否则将抛出 IllegalStateException 异常

      
    JPQL: JPQL语言,即 Java Persistence Query Language 的简称。JPQL 是一种和 SQL 非常类似的中间性和对象化查询语言,它最终会被编译成针对不同底层数据库的 SQL 查询,从而屏蔽不同数据库的差异。  JPQL语言的语句可以是 select 语句、update 语句或delete语句,它们都通过 Query 接口封装执行
    Query接口:
        调用EntityManager的createQuery,create NamedQuery 及 createNativeQuery 方法可以获得查询对象,

  •             setHint(String hintName, Object value) 设置与查询对象相关的特定供应商参数或提示信息。参数名及其取值需要参考特定 JPA 实现库提供商的文档。 如果第二个参数无效将抛出IllegalArgumentException异常。
  •             setParameter(int position, Object value) 为查询语句的指定位置参数赋值。Position 指定参数序号,value 为赋给参数的值。
  •             setParameter(int position, Date d, TemporalType type) 为查询语句的指定位置参数赋 Date 值。Position 指定参数序号,value 为赋给参数的值,temporalType 取 TemporalType 的枚举常量,包括 DATE、TIME 及 TIMESTAMP 三个  用于将 Java 的 Date 型值临时转换为数据库支持的日期时间类型(java.sql.Date、java.sql.Time及java.sql.Timestamp)。
  •             setParameter(int position, Calendar c, TemporalType type)  为查询语句的指定位置参数赋 Calenda r值。position 指定参数序号,value 为赋给参数的值,temporalType 的含义及取舍同前。
  •             setParameter(String name, Object value) 为查询语句的指定名称参数赋值。
  •             setParameter(String name, Date d, TemporalType type) 为查询语句的指定名称参数赋 Date 值。用法同前。
  •             setParameter(String name, Calendar c, TemporalType type)  为查询语句的指定名称参数设置Calendar值。name为参数名,其它同前。该方法调用时如果参数位置或参数名不正确,或者所赋的参数值类型不匹配,将抛出 IllegalArgumentException 异常。

    语句:
            查询所有实体的 JPQL 查询字串很简单,例如:
          

  select o from Order o 或  select o from Order as o
            Query query = entityManager.createQuery( "select o from Order o"); 
            List orders = query.getResultList();
            Iterator iterator = orders.iterator();
            while( iterator.hasNext() ) {
                // 处理Order
            }


            JPQL也支持包含参数的查询,例如:
         

   select o from Orders o where o.id = :myId
   select o from Orders o where o.id = :myId and o.customer = :customerName


         注意:参数名前必须冠以冒号(:),执行查询前须使用Query.setParameter(name, value)方法给参数赋值。
            也可以不使用参数名而使用参数的序号,例如:
          

  select o from Order o where o.id = ?1 and o.customer = ?2
            其中 ?1 代表第一个参数,?2 代表第一个参数。在执行查询之前需要使用重载方法Query.setParameter(pos, value) 提供参数值。
            Query query = entityManager.createQuery( "select o from      Orders o where o.id = ?1 and o.customer = ?2" );
            query.setParameter( 1, 2 );
            query.setParameter( 2, "John" );
            List orders = query.getResultList();


            group by字句
            Query.getSingleResult()得到查询结果。例如:
            

Query query = entityManager.createQuery(
                                "select max(o.id) from Orders o");
            Object result = query.getSingleResult();
            Long max = (Long)result;


            having子句:
                例如,以下语句用于查询订购总数大于100的商家所售商品及数量:
              

 select o.seller, o.goodId, sum(o.amount) from V_Orders o group by 
                o.seller, o.goodId having sum(o.amount) > 100
                having子句与where子句一样都可以使用参数。


            update语句用于执行更新主要对于单个实体类的批量更新:
              

 update Customers c set c.status = '未偿付' where c.balance < 10000


            delete语句:
                
            JPQL中提供了内置的函数:

  •                     concat(String s1, String s2):字符串合并/连接函数。
  •                     substring(String s, int start, int length):取字串函数。
  •                     trim([leading|trailing|both,] [char c,] String s):从字符串中去掉首/尾指定的字符或空格。
  •                     lower(String s):将字符串转换成小写形式。
  •                     upper(String s):将字符串转换成大写形式。
  •                     length(String s):求字符串的长度。
  •                     locate(String s1, String s2[, int start]):从第一个字符串中查找第二个字符串(子串)出现的位置。若未找到则返回0。

注解:
        @Table(name="jpa_customer")//用来让实体与数据表不同命名
        主键:
        @Id用于映射主键的在get()之上
        @GeneratedValue:用于生成主键生成策略
                name="IDENTITY"采用数据库ID自增方式
                name=GeneratorType.Table
        @Column(name="xxx")这个属性对应的字段为xxx
                (length=20,nullable=false,unique="true")
        @Basic:如果没加都是这个注解,就是字段名与属性名相同

        @Transient指定不需要映射到数据表中的属性
        @Temporal(TemporalType.DATE)//指定属性必须是年月日还是具体到秒
        @Temporal(TemporalType.TIMESTAMP)

有关jpa的会单独写篇文章介绍这里只是简单的介绍一下:

springboot整合流程:

1、引入spring-boot-starter-data-jpa 
2、配置文件打印SQL语句 
3、创建Entity标注JPA注解 
 4、创建Repository接口继承JpaRepository
 5、测试方法

JPA:ORM(Object Relational Mapping);
1)、编写一个实体类(bean)和数据表进行映射,并且配置好映射关系;

package com.kayleoi.springbootjpa.entity;


import javax.persistence.*;

/**
 * @Author kay三石
 * @date:2019/6/29
 */
//使用JPA注解配置映射关系
@Entity //告诉JPA这是一个实体类(和数据表映射的类)
@Table(name = "tbl_user") //@Table来指定和哪个数据表对应;如果省略默认表名就是user;
public class User {

    @Id //这是一个主键
    @GeneratedValue(strategy = GenerationType.IDENTITY)//自增主键
    private Integer id;

    @Column(name = "last_name",length = 50) //这是和数据表对应的一个列
    private String lastName;
    @Column //省略默认列名就是属性名
    private String email;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

2)、编写一个Dao接口来操作实体类对应的数据表(Repository)
 

package com.kayleoi.springbootjpa.repository;

import com.kayleoi.springbootjpa.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * @Author kay三石
 * @date:2019/6/29
 */
//继承JpaRepository来完成对数据库的操作
public interface UserRepository extends JpaRepository<User,Integer> {
}


3)、基本的配置JpaProperties。application.yml
 

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/jpa
    username: root
    password: 123
    driver-class-name: com.mysql.jdbc.Driver
  jpa:
    hibernate:
      ddl-auto: update      #更新或者创建数据表结构
    show-sql: true         #控制台显示SQL

4.测试:

package com.kayleoi.springbootjpa.controller;

import com.kayleoi.springbootjpa.entity.User;
import com.kayleoi.springbootjpa.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author kay三石
 * @date:2019/6/29
 */
@RestController
public class UserController {

    @Autowired
    UserRepository userRepository;

    @GetMapping("/user/{id}")
    public User getUser(@PathVariable("id") Integer id){
        User user = userRepository.getOne(id);
        return user;
    }

    @GetMapping("/user")
    public User insertUser(User user){
        User save = userRepository.save(user);
        return save;
    }

}
//其他的方法
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.data.jpa.repository;

import java.util.List;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;

@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
    List<T> findAll();

    List<T> findAll(Sort var1);

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

    <S extends T> List<S> saveAll(Iterable<S> var1);

    void flush();

    <S extends T> S saveAndFlush(S var1);

    void deleteInBatch(Iterable<T> var1);

    void deleteAllInBatch();

    T getOne(ID var1);

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

    <S extends T> List<S> findAll(Example<S> var1, Sort var2);
}


pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.kayleoi</groupId>
    <artifactId>spring-boot-data-jpa</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-jpa</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

到这里jpa的整合也就结束了,这里这是个demo而已。如果达到孰能生巧的结果还是必须在项目中的最终的体现,等具体的项目中遇到了我会把所有使用jpa的操作再详细的讲解,毕竟有时实战和demo还是不太一样的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kay三石 [Alay Kay]

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值