JPA的学习

JPA

jpa详解

JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。

Spring Date整合jpa

Spring Date

pring Data是Spring的一个子项目,用于简化数据访问,包括NoSQL非关系型数据库,另外还包括对关系型数据库的访问支持。Spring Data使我们可以快速简单地使用普通的数据技术及新的数据访问技术,Spring Data会让数据的访问变得更加方便。

Spring Date jpa简介

  • Spring Data JPA是Spring基于ORM框架、JPA规范的基础上封装的一套JPA应用框架,可以让开发者用极简的代码即可实现对数据的访问和操作。Spring Data JPA其实就是Spring基于Hibrenate之上构建的JPA使用解决方案,方便在Spring Boot项目中使用JPA技术。

  • Spring Data JPA让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它实现。

Spring Data 与 Spring Data JPA的关系:关系

1.maven开发环境配置

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>

    <groupId>com</groupId>
    <artifactId>days66SpringDataJPA</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
<!--        Spring Data JPA-->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>1.11.0.RELEASE</version>
        </dependency>
        <!--hibernate 实现JPA的框架-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.2.5.Final</version>
        </dependency>
        <!-- 数据源与MySQL驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.28</version>
        </dependency>
        <!-- Spring测试框架 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

2.在resources下创建Spring JPA配置文件

spring-datajpa.xml

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:repository="http://www.springframework.org/schema/data/repository"
       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/aop  http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
         http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
         http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository.xsd">
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 配置自动扫描的包 -->
    <context:component-scan base-package="com.qfxa.service"/>
    <context:component-scan base-package="com.qfxa.dao"/>

    <!-- 数据源 -->
    <bean  id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">

        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <!-- jpa实现框架 -->
    <bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
        <property name="showSql" value="true"/>
    </bean>

    <!-- spring-data-jpa配置 本地容器实体管理工厂对象,并指定POJO类 -->
    <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="packagesToScan" value="com.qfxa.po"/>
        <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter"/>
        <property name="jpaProperties">
            <props>
<!--                <prop key="hibernate.hbm2ddl.auto">validate</prop>-->
                <prop key="hibernate.format_sql">true</prop>
            </props>
        </property>
    </bean>

    <bean id="jpaTx" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="emf"/>
    </bean>

    <!-- 设置自动注解事务驱动 -->
    <tx:annotation-driven proxy-target-class="false" transaction-manager="jpaTx"/>

    <!-- 启动仓库扫描 -->

    <jpa:repositories base-package="com.qfxa.dao"
                      entity-manager-factory-ref="emf"
                      transaction-manager-ref="jpaTx"/>
</beans>

jdbc.properties

jdbc.url=jdbc:mysql://localhost:3306/days1009?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root
jdbc.driver=com.mysql.jdbc.Driver

3.根据配置文件的扫描包名新建包

在这里插入图片描述

4.编码

4.1新建实体类

Profession.java

package com.qfxa.po;

import lombok.Data;

import javax.persistence.*;

@Data
@Entity
public class Profession {
//@Entity @Id基本映射注解 @GeneratedValue ID生成策略
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int pid;
    
    //@Column设置正向工程创建数据库对字段的设置
    @Column(length = 20, unique = true, name = "col_pname")
    private String pname;

    @Column(length = 50, unique = true, name = "col_pdesc", nullable = false)
    private String pdesc;
}

4.2创建Dao接口

IProFessionDao.java

package com.qfxa.dao;

import com.qfxa.po.Profession;
import org.springframework.data.jpa.repository.JpaRepository;

import java.io.Serializable;

public interface IProFessionDao extends JpaRepository<Profession, Serializable> {
    //两个参数  第一个参数实体类  第二个参数id对应的泛型Interger或者序列化接口,不能写int因为泛型只能是包装类型也可以写Number是其父类

}

4.3编写Service层

接口

package com.qfxa.service;


import com.qfxa.po.Profession;

import java.util.List;

public interface IProfessionService {

    List<Profession> getAll();

    Profession getProfessionByPid(int pid);

    boolean saveProfession(Profession p);

    boolean updateProfession(Profession p);

    boolean deleteProfession(int pid);
}

接口实现类

package com.qfxa.service.impl;

import com.qfxa.dao.IProFessionDao;
import com.qfxa.po.Profession;
import com.qfxa.service.IProfessionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ProfessionService implements IProfessionService {

    //类型注入@Autowired  另一种方式名字注入@Qualifier
    @Autowired
    private IProFessionDao ipd;

    @Override
    public List<Profession> getAll() {
        return ipd.findAll();
    }

    @Override
    public Profession getProfessionByPid(int pid) {
        return ipd.findOne(pid);
    }

    @Override
    public boolean saveProfession(Profession p) {
        return ipd.saveAndFlush(p) != null;
    }

    @Override
    public boolean updateProfession(Profession p) {
        return ipd.saveAndFlush(p) != null;
    }

    @Override
    public boolean deleteProfession(int pid) {

        try {
            ipd.delete(pid);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }
    
    //查找单个用findone   不用getone
}

5.Spring单元测试

TestProfessionService.java

package com.qfxa.service;

import com.qfxa.po.Profession;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)//让测试运行于Spring测试环境
@ContextConfiguration("classpath:spring-datajpa.xml")// Spring整合JUnit4测试时,使用注解引入多个配置文件
public class TestProfessionService {

    @Autowired
    private IProfessionService ips;

    @Test
    public void testGetAll(){
        List<Profession> list = ips.getAll();

        for (Profession p : list) {
            System.out.println(p);
        }
    }

    @Test
    public void testSaveProfession(){
        Profession p = new Profession();

        //如果id存在则修改 不存在则新增
        p.setPid(3);
        p.setPname("999988");
        p.setPdesc("999999988");

        System.out.println(ips.saveProfession(p));
    }
    
    
}

6.正向工程

(pojo创建好后 数据库都不用创建了,自动创建实体类对应的表)

在spring-datajpa.xml配置文件中添加

<props>
<prop key="hibernate.hbm2ridu.auto">create</prop>
</ props>
  • create(用于测试) 干掉表后创建
  • create-drop(用于测试)干掉-创建-干掉
  • update 如果没有表创建表,有表插入ID相同则修改,ID不同则添加
  • validate 必须在有表的条件下才能继续操作 无表报错 有表继续操作执行新增,自动创建表

7.在正向工程前,需存在一数据库与配置文件中的数据库相对应。

执行插入测试方法,查看控制台与正向工程生成表的效果

//控制台自动生成的SQL语句
Hibernate: 
    
    create table Profession (
        pid integer not null auto_increment,
        col_pdesc varchar(50) not null,
        col_pname varchar(20),
        primary key (pid)
    )
Hibernate: 
    
    alter table Profession 
        drop constraint UK_jg7g2cv1pme2g2p6cwuot1oqs
Hibernate: 
    
    alter table Profession 
        add constraint UK_jg7g2cv1pme2g2p6cwuot1oqs unique (col_pdesc)
Hibernate: 
    
    alter table Profession 
        drop constraint UK_quao7gtkcrsvwrof6oj230ugg
Hibernate: 
    
    alter table Profession 
        add constraint UK_quao7gtkcrsvwrof6oj230ugg unique (col_pname)
Hibernate: 
    select
        profession0_.pid as pid1_0_0_,
        profession0_.col_pdesc as col_pdes2_0_0_,
        profession0_.col_pname as col_pnam3_0_0_ 
    from
        Profession profession0_ 
    where
        profession0_.pid=?
Hibernate: 
    insert 
    into
        Profession
        (col_pdesc, col_pname) 
    values
        (?, ?)
true

Process finished with exit code 0

8.对于dao层需要根据需求查询的需要手动创建方法并且方法的命名必须遵循查询规则

查询方法规则

  • findAll()查询所有
  • findByXXX(Object xxx) 根据属性名等值查询
  • findByXXXAndYYY(Object xxx,Object yyy) 同时满足两个属性名与属性相同的查询
  • findByXXXOrYYY(Object xxx,Object yyy) 只要满足两个属性名与属性相同的任一条查询
  • 除了And和Or之外,还可使用的关键字

案例

8.1新建班级实体类

package com.qfxa.po;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.io.Serializable;

@Entity
@Data
public class Clazz implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int cid;
    private String cname;
    private String pname;
    private String cdesc;
}

8.2dao层

IClazzDao.java

package com.qfxa.dao;

import com.qfxa.po.Clazz;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface IClazzDao extends JpaRepository<Clazz, Integer> {

    List<Clazz> findByPname(String pname);

    List<Clazz> findByPnameAndCdesc(String pname, String cdesc);

    List<Clazz> findByPnameOrCdesc(String pname, String cdesc);

    List<Clazz> findByCidBetween(int min, int max);

    Page<Clazz> findByPname(String pname, Pageable p);
}

8.3service层

IClazzService.java

package com.qfxa.service;

import com.qfxa.po.Clazz;

import java.util.List;

public interface IClazzService {

    List<Clazz> getAllClazz();

    Clazz getClazzByCid(int cid);

    List<Clazz> getClazzByPname(String name);

    List<Clazz> getClazzByPnameAndCdesc(String name, String cdesc);

    List<Clazz> getClazzByCidBetween(int min, int max);

    List<Clazz> getClazzByPnameAndPage(String pname, int cp, int ps);
}

接口实现类

package com.qfxa.service.impl;

import com.qfxa.dao.IClazzDao;
import com.qfxa.po.Clazz;
import com.qfxa.service.IClazzService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ClazzServiceImpl implements IClazzService {

    @Autowired
    private IClazzDao icd;

    @Override
    public List<Clazz> getAllClazz() {
        return icd.findAll();
    }

    @Override
    public Clazz getClazzByCid(int cid) {
        return icd.getOne(cid);
    }

    @Override
    public List<Clazz> getClazzByPname(String name) {
        return icd.findByPname(name);
    }

    @Override
    public List<Clazz> getClazzByPnameAndCdesc(String name, String cdesc) {
        return icd.findByPnameOrCdesc(name, cdesc);
    }

    @Override
    public List<Clazz> getClazzByCidBetween(int min, int max) {
        return icd.findByCidBetween(min, max);
    }

    @Override
    public List<Clazz> getClazzByPnameAndPage(String pname, int cp, int ps) {

        Pageable p = new PageRequest(cp, ps);
        Page<Clazz> page = icd.findByPname(pname, p);

        return page.getContent();
    }
}

8.4Spring测试类

package com.qfxa.service;

import com.qfxa.po.Clazz;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-datajpa.xml")
public class TestClazzService {

    @Autowired
    private IClazzService ics;

    @Test
    public void testGetAllClazz(){
        List<Clazz> list = ics.getAllClazz();

        for (Clazz c : list) {
            System.out.println(c);
        }
    }

    @Test
    public void testGetClazzByCid(){
        Clazz c = ics.getClazzByCid(10);

        System.out.println(c);
    }

    @Test
    public void testGetClazzByPname(){
        for (Clazz c : ics.getClazzByPname("软件工程")) {
            System.out.println(c);
        }
    }

    @Test
    public void testGetClazzByPnameAndCdesc(){
        List<Clazz> list = ics.getClazzByPnameAndCdesc("软件工程", "隶属于土木工程专业的班级");

        for (Clazz c : list) {
            System.out.println(c);
        }
    }

    @Test
    public void testGetClazzByCidBetween(){
        List<Clazz> list = ics.getClazzByCidBetween(10, 14);

        for (Clazz c : list) {
            System.out.println(c);
        }
    }

    @Test
    public void getGetClazzByPage(){
        List<Clazz> list = ics.getClazzByPnameAndPage("软件工程", 0, 1);

        for (Clazz c : list) {
            System.out.println(c);
        }
    }
}

SpringBoot整合JPA

1.搭建SpringBoot环境:SpringBoot环境搭建

  • maven方式
  • 下载jar包方式
  • 联网创建方式

2.添加依赖

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.49</version>
</dependency>

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

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.8</version>
</dependency>

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
</dependency>

3.新建application.yml文件并配置

  • 连接数据库的配置driver可不配置
  • jpa配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver: =com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/days1009?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8
    username: root
    password: root
  jpa:
    database: mysql
    show-sql: true
    hibernate:
      ddl-auto: validate
    properties:
      hibernate:
        format_sql: true

4.编写代码

4.1pojo

package com.pojo;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.io.Serializable;

@Entity
@Data
public class Clazz implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int cid;
    private String cname;
    private String pname;
    private String cdesc;
}

4.2dao层

IClazzDao.java

package com.dao;

import com.qfedu.days67_spt_jpa.pojo.Clazz;
import org.springframework.data.jpa.repository.JpaRepository;

public interface IClazzDao extends JpaRepository<Clazz, Integer> {
}

4.3service层

package com.service;

import com.pojo.Clazz;

import java.util.List;

public interface IClazzServic {

    List<Clazz> getAllClazz();

    Clazz getClazzByCid(int cid);

    boolean updateClazz(Clazz c);
}

接口实现类

package com.impl;

import com.dao.IClazzDao;
import com.pojo.Clazz;
import com.service.IClazzServic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ClazzServiceImpl implements IClazzServic {

    @Autowired
    private IClazzDao icd;

    @Override
    public List<Clazz> getAllClazz() {
        return icd.findAll();
    }

    @Override
    public Clazz getClazzByCid(int cid) {
        return icd.getOne(cid);
    }

    @Override
    public boolean updateClazz(Clazz c) {

        try {
            icd.saveAndFlush(c);

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }
}

4.4controller层

package com.controller;

import com.pojo.Clazz;
import com.service.IClazzServic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("clazz")
public class ClazzController {

    @Autowired
    private IClazzServic ics;

    @GetMapping("all")
    public List<Clazz> getAllClazz(){
        return ics.getAllClazz();
    }
}

5.测试

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值