SpringData 学习笔记-雷云龙

SpringData 学习笔记

一、SpringData概述

1、 springdata:是spring的一个子项目。用于简化数据库访问。支持Nosql 和关系型数据存储。其主要目标是使数据库的访问变得更加方便快捷。

2、springdata所支持的Nosql 数据库:

-MongoDB(文档数据库)

-Neo4j(图形数据库)

-Redis(键值存储)

-Hbase(列族数据库)

3、存储技术:

JDBC JPA

二、搭建JPA环境

1、JPA :java持久化API,是sun公司推出基于ORM的规范,内部是接口和抽象类组成。实现致力于减少Dao 层的操作。声明接口即可

1、创建maven 工程导入坐标

<dependencies>
    <!-- junit -->
   <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
   </dependency>
    <!-- hibernate对jpa的支持包 -->
   <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernateentitymanager</artifactId>
      <version>5.4.9.Final</version>
    </dependency>
        <!-- c3p0 -->
     <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
            <version>5.4.4.Final</version>
      </dependency>
        <!-- log日志-->
      <dependency>
            <groupId>apache-log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
      </dependency>
        <!-- Mysql and MariaDB -->
    <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <version>5.1.6</version>
     </dependency>
    </dependencies>

2、JPA的核心配置文件

1、配置到类路径下的META-INF的文件夹下

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <!--配置persistence-unit持久化单元:
        name :持久化名称
        transaction-type:事务管理方式
                    JTA :分布式事务管理
          RESOURCE_LOCAL:本地事务管理

    -->
    <persistence-unit name="myjpa" transaction-type="RESOURCE_LOCAL">
        <!--JPA的实现方式-->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <!--数据库信息-->
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="root"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/mybookshop"/>
            <!--可选配置,jpa 实现方(Hibernate)的配置信息
            显示sql:         hibernate.show_sql : true 显示
            自动创建数据库表: hibernate.hbm2ddl.auto :
                                  create : 程序运行时创建数据库表,(如果有表先删除,再创建)
                                  update: 程序运行时创建(如果有表不创建)
                                  none :不创建
            -->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>

3、映射关系

实体类 ,配置映射关系:

  • 1.实体类和表的映射关系

  • @Entity

  • @Table(name =“goods_info”)

  • 2.实体类中属性和表字段的映射关系

  • @Column (name =“bname”)

    1. @GeneratedValue(strategy = GenerationType.IDENTITY) //住建生成策略(自增)mysql

      strategy = GenerationType.SEQUENCE :序列(底层数据库必须支持序列)oracle

      strategy = GenerationType.TABLE : 通过一张数据库表的形式,完成主键自增

      strategy = GenerationType.AUTO : 程序自动选择以上策略

package com.tydic.entity;

import javax.persistence.*;

/**
 * @author: tydic leiyunlong
 * @time: 2019/12/25
 * @Version: 1.0
 */
@Entity
@Table(name ="goods_info")
public class Books {
    @Id  //声明住建ID
    @GeneratedValue(strategy = GenerationType.IDENTITY) //生成策略
    @Column (name ="id")
    private Integer  id;
    @Column (name ="bname")
    private  String name;
    @Column (name ="bprice")
    private  Double price;
    @Column (name ="bread")
    private  String read;
    @Column (name ="manu")
    private  String manu;
    @Column (name ="db_source")
    private String db_source;

    public Books() {
    }

    public Books(String name, Double price, String read, String manu, String db_source) {
        this.name = name;
        this.price = price;
        this.read = read;
        this.manu = manu;
        this.db_source = db_source;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public String getRead() {
        return read;
    }

    public void setRead(String read) {
        this.read = read;
    }

    public String getManu() {
        return manu;
    }

    public void setManu(String manu) {
        this.manu = manu;
    }

    public String getDb_source() {
        return db_source;
    }

    public void setDb_source(String db_source) {
        this.db_source = db_source;
    }
}


4、操作步骤

**// 1. 记载配置文件创建工厂(实体管理器工厂)对象 factory **

EntityManagerFactory factory = Persistence.createEntityManagerFactory(“myjpa”);

​ createEntityManagerFactory(“myjpa”);持久化单元名称,

​ Persistence静态方法,根据持久化单元名称创建实体管理器工厂对象factory,

内部维护了数据库信息,维护了缓存信息,维护了实体管理器对象,创建factory 过程中创建了数据库表,线程安全的。

解决EntityManagerFactory 浪费资源问题:

静态代码块的形式创建公共EntityManagerFactory 对象

**// 2. 通过实体管理器工厂获取实体管理器 emf **

EntityManager emf = factory.createEntityManager();

emf.persist(book); //插入

emf.merge ;//更新 需要先根据ID查询,再更新

emf .find; //根据ID查询,查询的对象就是当前本身,调用find方法就会调用sql 语句进行查询

emf.reference ;//获取到的对象是一个动态代理的对象,不会立即发送sql 语句进行查询,当调用查询结果对象时 候才执行 ,也就是延迟加载。

emf . remove ;//删除 需要先根据ID查询,再删除

// 3. 获取事务对象 et,开启事务

EntityTransaction et = emf.getTransaction();

et.begin();开启

et.commit ; 提交

et.rollback;回滚

// 4. 完成CRUD操作

// 5. 提交事务(回滚)

// 6. 释放资源

测试:

package com.tydic.test;

import com.tydic.entity.Books;
import org.junit.Test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

/**
 *
 * @author: tydic leiyunlong
 * @time: 2019/12/25
 * @Version: 1.0  
 */
public class BookTest {
    @Test
    public void BookSave(){
        EntityManagerFactory factory  = Persistence.createEntityManagerFactory("myjpa");
        EntityManager emf =  factory.createEntityManager();
        EntityTransaction  et = emf.getTransaction();
        et.begin();
        Books book = new Books();
        book.setName("啦啦啦");
        book.setPrice(18.2);
        emf.persist(book); //保存
        et.commit();
        emf.close();
        factory.close();

    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-08s47FVv-1578302998473)(C:\Users\lyl\AppData\Roaming\Typora\typora-user-images\1577257430219.png)]

5、创建实体管理器工厂公工具

解决实体管理器工厂的浪费资源和时间消耗问题:

  • 第一次访问getEntityManger() 经过静态代码块创建工厂对象 factory ,getEntityManger 方法获取 EntityManager 管理器对象
  • 第二次访问 getEntityManger()直接通过一个已经创建好的工厂对象 factory 创建EntityManager对象
package com.tydic.utils;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**
 *
 * @author: tydic leiyunlong
 * @time: 2019/12/25
 * @Version: 1.0
 */
public class JpaUtils {
    private static EntityManagerFactory  factory;
    static {
        // 1. 加载配置文件,创建entityManagerFactory 工厂对象
        factory = Persistence.createEntityManagerFactory("myjpa");
    }
        //2.获取EntityManager 对象
    public  static EntityManager getEntityManger(){
        return  factory.createEntityManager();
    }
}

测试:

package com.tydic.test;

import com.tydic.entity.Books;
import com.tydic.utils.JpaUtils;
import org.hibernate.dialect.Database;
import org.junit.Test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

/**
 *
 * @author: tydic leiyunlong
 * @time: 2019/12/25
 * @Version: 1.0  
 */
public class BookTest {
    @Test
    public void bookSave(){
       /* // 1. 记载配置文件创建工厂(实体管理器工厂)对象
        EntityManagerFactory factory  = Persistence.createEntityManagerFactory("myjpa");
        // 2. 通过实体管理器工厂获取实体管理器
        EntityManager emf =  factory.createEntityManager();*/
       
       
        EntityManager emf = JpaUtils.getEntityManger();
        // 3. 获取事务对象,开启事务
        EntityTransaction  et = emf.getTransaction();
        et.begin();
        // 4. 完成CRUD操作
        Books book = new Books("啦啦啦",12.2,"好书","A","0");
        emf.persist(book); //保存
        // 5. 提交事务(回滚)
        et.commit();
        // 6. 释放资源
        emf.close();
      //  factory.close();  公共的静态的就不用关闭了

    }
}

6、查询

1.按照ID 查询

/**
     *   根据id 查询
     */
    @Test
    public  void findById(){

        // 1. 通过工厂获取管理器对象
        EntityManager entityManger = JpaUtils.getEntityManger();
        // 2. 获取事务,开启事务
        EntityTransaction transaction = entityManger.getTransaction();
        transaction.begin();
        // 3.  CRUD
        entityManger.find(Books.class,1);
        // 4. 提交事务
        transaction.commit();
        // 5. 释放资源
        entityManger.close();
    }

2. 查询全部

@Test
    public  void findAll(){

        // 1. 通过工厂获取管理器对象
        EntityManager entityManger = JpaUtils.getEntityManger();
        // 2. 获取事务,开启事务
        EntityTransaction transaction = entityManger.getTransaction();
        transaction.begin();
        // 3.  查询所有
        String jpql = "from com.tydic.entity.Books";
        Query query = entityManger.createQuery(jpql);  //创建query 查询对象,query对象才是执行jpql 的对象 
        List resultList = query.getResultList(); // 执行查询,并 封装结果集
        for (Object o:resultList) {
            System.out.println(o);
        }
        // 4. 提交事务
        transaction.commit();
        // 5. 释放资源
        entityManger.close();
    }

1、 倒序查询

sql : SELECT * FROM goods_info GROUP BY id DESC

jpql : from Books group by id desc

2 、统计总条数

sql: SELECT COUNT(id) FROM goods_info

jpql: select count (id) from Books [count(属性的 id )]

query.getSingleResult(); 唯一的结果集

3.分页查询

sql: SELECT * FROM goods_info limit ?,?

 /**
     * 分页查询
     */
    @Test
    public  void queryAll(){

        // 1. 通过工厂获取管理器对象
        EntityManager entityManger = JpaUtils.getEntityManger();
        // 2. 获取事务,开启事务
        EntityTransaction transaction = entityManger.getTransaction();
        transaction.begin();
        // 3.  查询所有
        String jpql = "from Books";
        Query query = entityManger.createQuery(jpql);  //创建query 查询对象,query对象才是执行jpql 的对象
        query.setFirstResult(0);  // 设置起始页
        query.setMaxResults(4);   // 每页条数
        List resultList = query.getResultList(); // 执行查询,并封装结果集
        for (Object o:resultList) {
            System.out.println(o);
        }

        // 4. 提交事务
        transaction.commit();
        // 5. 释放资源
        entityManger.close();
    }

4.模糊查询

/**
     * 模糊查询
     */
    @Test
    public  void queryLike(){
        // 1. 通过工厂获取管理器对象
        EntityManager entityManger = JpaUtils.getEntityManger();
        // 2. 获取事务,开启事务
        EntityTransaction transaction = entityManger.getTransaction();
        transaction.begin();
        // 3.  查询所有
        String jpql = "from Books where name like ?1 ";
        Query query = entityManger.createQuery(jpql);  //创建query 查询对象,query对象才是执行jpql 的对象
        query.setParameter(1,"%三%");
        query.setFirstResult(0);  // 设置起始页
        query.setMaxResults(4);   // 每页条数
        List resultList = query.getResultList(); // 执行查询,并封装结果集
        for (Object o:resultList) {
            System.out.println(o);
        }
        // 4. 提交事务
        transaction.commit();
        // 5. 释放资源
        entityManger.close();
    }

四、SpringData JPA

1.SpringData JPA 概述

是基于ORM 框架,JPA规范的基础上封装的一套JPA应用框架。解脱了Dao层操作,封装了CRUD,可以使用 springdata JPA +ORM (hibernate)。

2.SpringData JPA特性

使用SpringData JPA 减少了数据库访问层的操作,只需要写接口即可。

3. 几者之间的关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FeIrnmsK-1578302998474)(C:\Users\lyl\AppData\Roaming\Typora\typora-user-images\1577323977115.png)]

五、搭建SpringData JPA 环境

1.jar包

** 注意jar 的版本兼容性,后期检查得

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <org.springframework.version>4.2.5.RELEASE</org.springframework.version>
    <org.hibernate.version>4.3.8.Final</org.hibernate.version>
    <spring-data-jpa.version>1.9.0.RELEASE</spring-data-jpa.version>
    <com.fasterxml.jackson.version>2.5.0</com.fasterxml.jackson.version>
    <org.slf4j.version>1.6.1</org.slf4j.version>
</properties>
<!--                     版本全部修改  一定要改                      -->
<dependencies>
        <!--单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
        <!--============================  spring 包   =====================-->
        <!--spring AOP相关包-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.8</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.0.8.RELEASE</version>
        </dependency>
        <!---->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
        <!--spring对orm 框架的支持包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
        <!--spring核心包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
        <!--============================-  hibernate包  =====================-->
        <!--hibernate核心包-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.1.0.Final</version>
        </dependency>
        <!--hibernateJPA实现包-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.1.0.Final</version>
        </dependency>
        <!--验证包-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.15</version>
        </dependency>
        <dependency>
            <!--springData JPA的坐标-->
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>2.0.7.RELEASE</version>
        </dependency>
        <!--springdata JPA 必须引入-->
        <dependency>
            <groupId>javax.el</groupId>
            <artifactId>javax.el-api</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.web</groupId>
            <artifactId>javax.el</artifactId>
            <version>2.2.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.1.5.RELEASE</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

*** 修改jar

<?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>

    <groupId>com.tydic</groupId>
    <artifactId>SpringData_JPA</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>6</source>
                    <target>6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <org.springframework.version>4.2.5.RELEASE</org.springframework.version>
        <org.hibernate.version>4.3.8.Final</org.hibernate.version>
        <spring-data-jpa.version>1.9.0.RELEASE</spring-data-jpa.version>
        <com.fasterxml.jackson.version>2.5.0</com.fasterxml.jackson.version>
        <org.slf4j.version>1.6.1</org.slf4j.version>
    </properties>
    <dependencies>
        <!-- Spring的支持包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${org.springframework.version}</version>
            <scope>test</scope>
        </dependency>
        <!-- 引入web前端的支持 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <!-- SpringMCV上传需要用到io包-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!-- 文件上传用到的包 -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.2.2</version>
        </dependency>
        <!-- SpringMVC的json支持包 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${com.fasterxml.jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>${com.fasterxml.jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${com.fasterxml.jackson.version}</version>
        </dependency>
        <!--SpringDataJpa -> Spring封装了JPA (还是要用之前的JPA)-->
        <!-- hibernate的支持包 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${org.hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${org.hibernate.version}</version>
        </dependency>
        <!-- SpringData的支持包 -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>${spring-data-jpa.version}</version>
        </dependency>
        <!-- SpringDataJpa的擴展包 -->
        <dependency>
            <groupId>com.github.wenhao</groupId>
            <artifactId>jpa-spec</artifactId>
            <version>3.1.1</version>
            <!-- 把所有的依賴都去掉 -->
            <exclusions>
                <exclusion>
                    <groupId>*</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- c3p0 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
            <version>5.4.4.Final</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.2.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <!--lang包:对Java中的lang包中的东西做扩展-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.5</version>
        </dependency>
        <!-- 測試包 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <!-- 这个scope 只能作用在编译和测试时,同时没有传递性。表示在运行的时候不添加此jar文件 -->
            <scope>provided</scope>
        </dependency>
        <!-- 日志文件(大家学习MyBatis时候详细讲解) -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${org.slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${org.slf4j.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>
    </dependencies>
</project>

2.配置Spring整合JPA

applicationContext

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                 http://www.springframework.org/schema/beans/spring-beans.xsd
                 http://www.springframework.org/schema/context
                 http://www.springframework.org/schema/context/spring-context.xsd
                 http://www.springframework.org/schema/data/jpa
                 http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
                 http://www.springframework.org/schema/tx
                 http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--配置service扫包-->
    <context:component-scan base-package="com.tydic.service"/>
    <!-- 1. 配置dataSource数据源-->
    <!--关联外部的db.properties-->
    <context:property-placeholder location="classpath:db.properties"/>
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${db.driver}"/>
        <property name="jdbcUrl" value="${db.url}"/>
        <property name="user" value="${db.username}"/>
        <property name="password" value="${db.password}"/>
    </bean>
    <!-- 2. 配置JPA 的EntityManagerFactory-->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!--jpa 实现产品的适配器-->
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
        </property>
        <!-- 扫描加了@Entity的包-->
        <property name="packagesToScan" value="com.tydic.entity"/>
        <!--jpa实现产品的 属性-->
        <property name="jpaProperties">
            <props>
                <!--二级缓存-->
                <!--<prop key="factory_class">org.hibernate </prop>
                <prop key="net.sf">eh</prop>-->
                <!--生成数据表的列的策略-->
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>
    <!-- 3. 配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    <!-- 4. 配置支持注解的事务-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <!-- 5. 配置springdata-->
    <!--扫描Repository Bean 所在的包-->
    <!--jpa 的命名空间-->
    <jpa:repositories base-package="com.tydic.dao" entity-manager-factory-ref="entityManagerFactory"/>
</beans>

六、Reporstory 接口

  1. Reporstory 接口 是一个空接口,即标记接口

  2. 若我们定义的接口继承了Reporstory ,则该接口会被IOC容器识别为一个Reporstory Bean,纳入到IOC容器中,进而可以在该接口中定义满足一定规范的方法

  3. 实际上也可以通过@RepositoryDefinition(domainClass = Books.class,idClass = Integer.class) 注解代继承

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2WXKJNtO-1578302998474)(C:\Users\lyl\AppData\Roaming\Typora\typora-user-images\1577346050387.png)]

1、方法规范

  1. 查询的话,以get 、find、read 方法开头

  2. 条件查询时,条件的属性用条件的关键字连接

  3. 条件属性以首字母大写

  4. 若有级联查询,则属性之间使用 _ 隔开

    package com.tydic.dao;
    
    import com.tydic.entity.Books;
    import org.springframework.data.repository.RepositoryDefinition;
    
    import java.util.List;
    
    /**
     *
     * @author: tydic leiyunlong
     * @time: 2019/12/26
     * @Version: 1.0  
     */
    //该注解相当于接口继承了Reporstory
    @RepositoryDefinition(domainClass = Books.class,idClass = Integer.class)
    public interface BookDao  {
    
        List<Books> findAll();
        List <Books> getByName (String name);
    }
    
   
   ```java
   package com.tydic.test;
   
   import com.tydic.dao.BookDao;
   import com.tydic.entity.Books;
   import org.junit.Test;
   import org.springframework.context.ApplicationContext;
   import org.springframework.context.support.ClassPathXmlApplicationContext;
   
   import javax.sql.DataSource;
   import java.sql.SQLException;
   import java.util.List;
   
   /**
    *
    * @author: tydic leiyunlong
    * @time: 2019/12/26
    * @Version: 1.0  
    */
   public class BookTest {
   
       private ApplicationContext ctx = null;
       private  BookDao bookDao = null;
   
       { ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
           bookDao = ctx.getBean(BookDao.class);
       }
   
       /*测试方法*/
       @Test
       public  void findAll(){
           List<Books>  list =bookDao.findAll();
           for(Object O : list){
               System.out.println(O);
           }
   
       }
       @Test
       public void testJPA(){
   
       }
       /*测试datasource*/
       @Test
       public void  testDatasource() throws SQLException {
           DataSource dataSource = ctx.getBean(DataSource.class);
           System.out.println(dataSource.getConnection());
       }
   }

2、@Query 注解

1.使用@Query注解,可以自定义jpql 语句

@RepositoryDefinition(domainClass = Detail.class,idClass = Integer.class)
public interface DetailDao {
    List<Detail> findAll();
/*查询在detail表中ID最大值的Book*/
    @Query("SELECT b from Books b where b.id = (SELECT max (d.id) from Detail  d)")
    Books getMaxIdBook();
}


----------------------------------------------------------------------------------------
 /*Query 的子查询*/
    @Test
    public  void  queryGetMaxId(){
        Books books = detailDao.getMaxIdBook();
        System.out.println(books);
    }

2.传参

第一种方式,使用占位符,需要标记 1 2

​ 注意:这里的 b.name 是属性 不是列名字 b.bname

 /*@Query 传参*/
    @Query("select b from Books b where b.name = ?1 and  b.read = ?2")
    List<Books> testQueryParam1(String name , String read);


-----------------------------------------------------------------------------------------
     @Test
    public void testParma1(){
        List<Books> books = bookDao.testQueryParam1("啦啦啦","好书");
        for (Object L :books){
            System.out.println(L);
        }
    }

第二种方式,使用命名参数的方式:

@Query("select b from Books b where b.name = :name and  b.read = :read")List<Books> testQueryParam2(@Param("name") String name , @Param("read") String read);
-----------------------------------------------------------------------------------------
     @Test
    public void testParma2(){
        List<Books> books = bookDao.testQueryParam2("啦啦啦","好书");
        for (Object L :books){
            System.out.println(L);
        }
    }

like 方式(同样可以使用参数命名 like %:name%)

@Query("select b from Books b where b.name like %?1% or  b.read like %?2%")
    List<Books> testQueryParam3(String name , String read);
-------------------------------------------------------------------------------------
    @Test
    public void testParma3(){
        List<Books> books = bookDao.testQueryParam3("啦","好");
        for (Object L :books){
            System.out.println(L);
        }
    }

使用nativeQuery = true 即可使用原生的sql 查询

@Query(value = "select xxx from xxx" ,nativeQuery = true)

3、@Modifying 注解和事务

/*修改操作* 在query中写jpql 语句,更新和删除必须使用@Modifying 注解,用来通知springdata 这是一个update 操作 或者是delete 操作* 以为springdata 的每个方法都默认是只读事务,所以必须加事务,而事务需要放在service 层,记得配置service自动扫包
**/
@Modifying@Query("update  Books b set b.name= ?1 where b.id =?2 ")void  updataBooks (String name ,Integer id);
-------------------------------------------------------------------------------------
@Test
    public void updateBooks(){
         booksService.updataBooks("哈哈哈",9);

七、Reporstory子接口

1、CrudReporstory

只要继承了CrudReporstory 接口,即可使用已经封装好的CRUD方法

1. save 保存方法

package com.tydic.dao;

import com.tydic.entity.Orders;
import org.springframework.data.repository.CrudRepository;

/**
 *   CrudRepository 中save方法批量保存
 */
public interface OrderDao extends CrudRepository <Orders,Integer> {

}
@Service
public class OrderService {
    @Autowired
    private OrderDao orderDao;

    @Transactional
    public void  saveOrders (List<Orders> orders){
        orderDao.save(orders);

    }
 @Test
    public void saveOrders(){
        List <Orders> list = new ArrayList<Orders>();
        for (int i = 'a';i<'z';i++){
            Orders orders = new Orders();
            orders.setName("买家"+(char)i + ""+ (char)i);
            orders.setAddress("家住"+(char)i+"地方");
            orders.setCreatetime(new Timestamp(System.currentTimeMillis()));
            list.add(orders);
            orderService.saveOrders(list);
        }
    }

2.删除

跟保存类似

后续。。。。

2、PagingAndSortingReporstory

分页和排序
1.分页:

public interface OrderDao extends PagingAndSortingRepository<Orders,Integer> {

}
@Test
    public void pagingAndSorting(){
        int pageNo = 3-1;  //起始页
        int pageSize = 5;  // 每页最大数
        // Pageable 接口通常使用的是PageRequest实现类
        PageRequest pageable = new PageRequest(pageNo,pageSize);
        Page<Orders> page = orderDao.findAll(pageable);
        System.out.println("总记录数:" + page.getTotalElements());
        System.out.println("总页数:"+page.getTotalPages());
        System.out.println("当前第几页:"+ (page.getNumber()+1));   
        System.out.println("当前页的list:"+page.getContent());
        System.out.println("当前页的记录数:"+page.getNumberOfElements());

    }

2.排序

 @Test
    public void pagingAndSorting(){
        int pageNo = 3-1;  //起始页
        int pageSize = 5;  // 每页最大数
        // Pageable 接口通常使用的是PageRequest实现类
        // 排序相关的
        Sort.Order order1  = new Sort.Order(Sort.Direction.ASC,"id");  //升序
        Sort.Order order2  = new Sort.Order(Sort.Direction.DESC,"id");  //降序
        Sort sort = new Sort(order2);
        PageRequest pageable = new PageRequest(pageNo,pageSize,sort);
        Page<Orders> page = orderDao.findAll(pageable);
        System.out.println("总记录数:" + page.getTotalElements());
        System.out.println("总页数:"+page.getTotalPages());
        System.out.println("当前第几页:"+ (page.getNumber()+1));
        System.out.println("当前页的list:"+page.getContent());
        System.out.println("当前页的记录数:"+page.getNumberOfElements());

    }

3、JpaRepository

JpaRepository extends PagingAndSortingReporstory extends CrudReporstory extends Reporstory

更新数据,类似于JPA 的 emf.merge ;//更新 需要先根据ID查询,再更新

@Test
    public void JpaRepostory(){
            Orders orders = new Orders();
            orders.setName("我是买家A");
            orders.setAddress("我是住址A");
            orders.setId(67);
            orders.setCreatetime(new Timestamp(System.currentTimeMillis()));
            orderDao.saveAndFlush(orders);
        }

4、JpaSpecificationExecutor

JpaSpecificationExecutor 他不是Repository 家族的 ,是实现一组Criteria查询相关的方法

Specification :封装了Criteria 的查询条件,通常使用匿名内部类的方式来创建接口对象。

    public interface OrderDao extends JpaRepository<Orders,Integer>, JpaSpecificationExecutor<Orders> {

}
/**
     * 目标:实现带查询条件的分页。
     * 调用JpaSpecificationExecutor的Page<T> findAll(Specification<T> var1, Pageable var2);
     * Specification :封装了Criteria 的查询条件,通常使用匿名内部类的方式来创建接口对象。
     * Pageable 封装了请求分页的信息,如pageNo,pageSize,sort等
     */
    @Test
    public void JpaSpecificationExecutor (){
        int pageNo = 3-1;  //起始页
        int pageSize = 5;  // 每页最大数
        PageRequest pageable = new PageRequest(pageNo,pageSize);
        Specification<Orders>  specification =  new Specification<Orders>() {
            /**
             *  目标:id  >16 的对象
             * @param root   :代表查询的实体类
             * @param criteriaQuery  :可以从中得到root对象,即告知Criteria  查询哪一个实体类,也                 可以添加查询条件,还可以介个EntityManager 对象得到最终查询的TypeQuery 对象
             * @param criteriaBuilder :CriteriaBuilder对象,用于创建Criteria相关对象的工厂,可                 以从中获取到Predicate 对象
             * @return :Predicate 类型,代表一个查询条件
             */
            @Override
            public Predicate toPredicate(Root<Orders> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

                Path path =root.get("id");
                Predicate predicate = criteriaBuilder.gt(path,16);

                return predicate;
            }
        };

        Page<Orders> page = orderDao.findAll(specification,pageable);
        System.out.println("总记录数:" + page.getTotalElements());
        System.out.println("总页数:"+page.getTotalPages());
        System.out.println("当前第几页:"+ (page.getNumber()+1));
        System.out.println("当前页的list:"+page.getContent());
        System.out.println("当前页的记录数:"+page.getNumberOfElements());


    }

5、自定义Repository 接口方法

步骤:

  • 定义一个接口:声明要添加的,并自实现的方法。

  • 提供该接口的实现类:类名需要在声明的Repository 后加Impl,并实现方法

  • 声明Repository 接口,并继承刚才定义的接口

  • 使用

后续。。。

ers>() {
/**
* 目标:id >16 的对象
* @param root :代表查询的实体类
* @param criteriaQuery :可以从中得到root对象,即告知Criteria 查询哪一个实体类,也 可以添加查询条件,还可以介个EntityManager 对象得到最终查询的TypeQuery 对象
* @param criteriaBuilder :CriteriaBuilder对象,用于创建Criteria相关对象的工厂,可 以从中获取到Predicate 对象
* @return :Predicate 类型,代表一个查询条件
*/
@Override
public Predicate toPredicate(Root root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

            Path path =root.get("id");
            Predicate predicate = criteriaBuilder.gt(path,16);

            return predicate;
        }
    };

    Page<Orders> page = orderDao.findAll(specification,pageable);
    System.out.println("总记录数:" + page.getTotalElements());
    System.out.println("总页数:"+page.getTotalPages());
    System.out.println("当前第几页:"+ (page.getNumber()+1));
    System.out.println("当前页的list:"+page.getContent());
    System.out.println("当前页的记录数:"+page.getNumberOfElements());


}

## 5、自定义Repository 接口方法

步骤:

- 定义一个接口:声明要添加的,并自实现的方法。

- 提供该接口的实现类:类名需要在声明的Repository 后加Impl,并实现方法

- 声明Repository  接口,并继承刚才定义的接口

- 使用

  

后续。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值