什么是JPA?

什么是JDBC知道吧?数据库有Mysql,SQL Server,Oracle,Java为了统一的去操作建立连接,JDBC出现了,有了JDBC,加载注册不同的数据库驱动就完事了。

但是,JDBC好繁琐的啊,每次都要写一堆,烦人,所以一些框架出现了,例如Hibernate,TopLink,但是这些框架也是各种各样的,我每次使用都要按照各自的框架来写,这不行,为了省事,JPA出现了

JPA是规范 JPA不是框架,没有实现的方法,就是规范,提供了一些API接口,你们这些hibernate,TopLink框架啥的,遵循我的JPA规范就成

顺便一提,JPA是Hibernate作者搞出来的,所以JPA和Hibernate一样,不需要你写SQL,有时候必须自己写SQL可以使用JPQL

PS:EJB有三种,分别是会话Bean(Session Bean),实体Bean(Entity Bean)和消息驱动Bean(MessageDriven Bean)。在EJB3.0推出以后,实体Bean被单独分了出来,形成了新的规范JPA。

引入配置

想要使用JPA,就要引入一些配置,我的项目是SpringBoot,其他的框架也行,引入了三个,JPA,Hibernate,MySQL

  <!--JPA,我用的是SpringBoot的-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.1.3.RELEASE</version>
</dependency> <!--Hibernate,说了JPA只是一个规范,我们使用Hibernate作为实现-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.1.Final</version>
</dependency>
<!--数据库不能少-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>

引入的配置完了,接下来是对JPA的一些配置,不能不写,不写不成功

### Java Persistence Api --  Spring jpa 的配置信息
#其实这个hibernate.hbm2ddl.auto参数的作用主要用于:自动创建|更新|验证数据库表结构,有四个值
#create: 每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
#create-drop :每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
#update:最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据 model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等 应用第一次运行起来后才会。
#validate :每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
#dialect 主要是指定生成表名的存储引擎为InneoDB
#show-sql 是否打印出自动生产的SQL,方便调试的时候查看 spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql= true

这个是application.properties里面关于JPA的配置,数据库配置就不贴了,JPA配置的讲解见注释

新建一个Entity Bean类

package com.cache.entity;

import javax.persistence.*;

@Entity
@Table(name="product")
public class Product {
@Id
@GeneratedValue
@Column(name="id")
private Integer id;
private String name;
private Double price;
private String type; public Product() {
} public Product(Integer id, String name, Double price, String type) {
this.id = id;
this.name = name;
this.price = price;
this.type = type;
} 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 getType() {
return type;
} public void setType(String type) {
this.type = type;
} @Override
public String toString() {
return "product{" +
"id=" + id +
", name='" + name + '\'' +
", price=" + price +
", type='" + type + '\'' +
'}';
}
}

这个为啥叫Entity Bean类呢?我讲一下,普通的Java Bean类加上@Entity注解之后就变成了Entity Bean类,这个Entity Bean的意思就是这个类可以映射到数据库

讲解一下上面Entity Bean里面的注解是什么意思

@Entity : 这个注解代表这个Userinfo是一个实体类,也就是说,当你创建实体类时,需要加上@Entity 标志着此类是实体类;

@Table(name=”userinfos”) :这个注解代表对应表的名称,userinfos就是利用jpa要生成的表名称;

@id :表明此属性是主键;

@GeneratedValue :表示的是 主键生成策略,默认主键是自增长的,当然你也可以使用 uuid

@Column :表明此属性在数据库中对应的字段,如果实体中的属性与数据库中的字段一样,可以省略不写。

还有两个注解我没使用,可以了解一下:

@Transient:Entity Bean的属性或字段加上这个注解,该字段便不会映射到数据库表

@Temporal:也是在Entity Bean的属性或字段上加的,这个是对Date时间类型的精度的一个选择,例如生日我就想精确到年月日就行了,下单时间我却想精确到时分秒,这个时候就可以使用这个,有Date,TIMESTAMP,TIME这三种精度

怎么样?爽不爽?没有JDBC的繁琐,我仅仅是写了一个Entity Bean实体类,我就和数据库进行映射关系了,内存中的实体类对象映射到数据库了,这也叫持久化。

持久化是位于 JDBC 之上的一个更高层抽象。持久层将对象映射到数据库,以便在查询、 装载、 更新, 或删除对象的时候, 无须使用像 JDBC 那样繁琐的 API。

JPA的增删改查

新建操作接口

使用Entity Bean实体类,我们已经映射出了一个数据库表,现在要存储数据了,我们需要新建一个接口

package com.cache.repository;

import com.cache.entity.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import javax.transaction.Transactional; public interface ProductRepository extends JpaRepository<Product,Integer> { //由于JPA没有更新方法,所以需要自己写更新方法,我这里只写一个更新name的方法,如果想更新全部,可以第一个参数写类
@Transactional
@Modifying
@Query("update Product set name=?1 where id=?2")
int updateNameById(String name,Integer id);
}

我来好好的讲解一下这个接口,首先ProductRepository这个接口继承了

JpaRepository这个类,这个类里面有JPA的操作方法,所以只要我们的接口继承了这个类,我们也就有方法可以调用了,不需要自己写。

但是,JPA只有正删查,没有更改的方法,所以我们可以在接口里面自己写,我就写了一个更新Product实体类的name属性的方法

@Transactional 开启事务

@Modifying 修改方法专用注解

这两个注解

@Query(“update Product set name=?1 where id=?2”)

此注解书写JPql语句 其中 Product 是实体类名,name和 id 是实体类的属性名,?1代表是第一个参数 ?2是第二个参数

注意:JPql里面必须是实体类的类名,可不是你的数据库表名,如果写错了会报 XXX is not mapped 错误

新建测试类

在我们的ProductRepository接口上新建一个测试类,这个步骤不会的就太菜了

我直接贴出代码了,我已经写好了增删改查的代码了

package com.cache.repository;

import com.cache.entity.Product;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import java.util.List;
import java.util.Optional; @RunWith(SpringRunner.class)
@SpringBootTest
public class ProductRepositoryTest { @Autowired
private ProductRepository productRepository; //增加数据
@Test
public void save(){
Product product=new Product();
product.setId(1);
product.setName("魅族16s");
product.setPrice(2899.0);
product.setType("手机类");
//调用save方法保存一个对象的时候,会返回该对象
Product p=productRepository.save(product);
//断言返回对象的值就是我们存进去的值
Assert.assertEquals(p.getName(),"魅族16s");
} //删除一个数据
@Test
public void delete(){
productRepository.deleteById(1);
} //更新,使用的是我们自己写的更新name方法
@Test
public void update(){
productRepository.updateNameById("魅族16s Plus",2);
} //查找数据
@Test
public void selectAll(){
List<Product> lists=productRepository.findAll();
for (Product product : lists) {
System.out.println(product);
}
}
@Test
public void selectOne(){
Optional<Product> product=productRepository.findById(2);
System.out.println(product);
} }

我都执行了一遍,都是ok的

总结

由于JPA是Hibernate实现的,所以不需要我们写SQL,都是自动的(除了JPQL)

简单的说,JPA对比Mybatis,还是简单的很多,没有配置文件了,不需要自己写SQL了,连操作方法都有JpaRepository类帮我们写好了

如果不是需要性能优化什么的,简单的使用来说,还是JPA好用

Spring JPA学习笔记的更多相关文章

  1. spring jpa 学习笔记(一) 之集成

    一.pom 配置 <?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apa ...

  2. Spring MVC 学习笔记12 —— SpringMVC+Hibernate开发(1)依赖包搭建

    Spring MVC 学习笔记12 -- SpringMVC+Hibernate开发(1)依赖包搭建 用Hibernate帮助建立SpringMVC与数据库之间的联系,通过配置DAO层,Service ...

  3. Spring Boot学习笔记2——基本使用之最佳实践[z]

    前言 在上一篇文章Spring Boot 学习笔记1——初体验之3分钟启动你的Web应用已经对Spring Boot的基本体系与基本使用进行了学习,本文主要目的是更加进一步的来说明对于Spring B ...

  4. Spring框架学习笔记(1)

    Spring 框架学习笔记(1) 一.简介 Rod Johnson(spring之父) Spring是分层的Java SE/EE应用 full-stack(服务端的全栈)轻量级(跟EJB比)开源框架, ...

  5. 【转】Spring.NET学习笔记——目录

    目录 前言 Spring.NET学习笔记——前言 第一阶段:控制反转与依赖注入IoC&DI Spring.NET学习笔记1——控制反转(基础篇) Level 200 Spring.NET学习笔 ...

  6. Spring MVC 学习笔记一 HelloWorld

    Spring MVC 学习笔记一 HelloWorld Spring MVC 的使用可以按照以下步骤进行(使用Eclipse): 加入JAR包 在web.xml中配置DispatcherServlet ...

  7. SpringBoot + Spring Security 学习笔记(五)实现短信验证码+登录功能

    在 Spring Security 中基于表单的认证模式,默认就是密码帐号登录认证,那么对于短信验证码+登录的方式,Spring Security 没有现成的接口可以使用,所以需要自己的封装一个类似的 ...

  8. SpringBoot + Spring Security 学习笔记(三)实现图片验证码认证

    整体实现逻辑 前端在登录页面时,自动从后台获取最新的验证码图片 服务器接收获取生成验证码请求,生成验证码和对应的图片,图片响应回前端,验证码保存一份到服务器的 session 中 前端用户登录时携带当 ...

  9. spring揭密学习笔记

    spring揭密学习笔记 spring揭密学习笔记(1) --spring的由来 spring揭密学习笔记(2)-spring ioc容器:IOC的基本概念

随机推荐

  1. web scraper——安装【一】

    准备工作 工欲善其事必先利其器,既然是要安装web scraper一些***的工具是必然不可缺少的,如果没有的话,先下载个蓝灯用用吧. 蓝灯最新版下载地址 下载安装完成后双击打开即可,这时候会弹出一个 ...

  2. 【BZOJ4061】[Cerc2012]Farm and factory(最短路,构造)

    [BZOJ4061][Cerc2012]Farm and factory(最短路,构造) 题面 BZOJ 然而权限题QwQ. 题解 先求出所有点到达\(1,2\)的最短路,不妨记为\(d_{u,1}, ...

  3. [luogu4479][BJWC2018]第k大斜率【二维偏序+二分+离散化+树状数组】

    传送门 https://www.luogu.org/problemnew/show/P4479 题目描述 在平面直角坐标系上,有 n 个不同的点.任意两个不同的点确定了一条直线.请求出所有斜率存在的直 ...

  4. [SDOI2011]计算器(BSGS)

    洛古题面 对于操作一,用快速幂算即可 代码如下 int quickpow(int a,int b,int k) { int r=1; while(b) { if(b&1) r=(r*a)%k; ...

  5. 20165223 实验四 Android开发基础

    实验四 Android开发基础 目录 一.实验报告封面 二.具体实验内容 (一)Android Stuidio的安装测试 (二)Activity测试 (三)UI测试 (四)布局测试 (五)教材代码测试 ...

  6. Ocean的游戏(前缀和)

    题目链接:http://oj.ismdeep.com/contest/Problem?id=1284&pid=1 B: Ocean的游戏 Time Limit: 1 s      Memory ...

  7. AITP

    AITP AITP比较简单,适合刚毕业,即将开始IT生涯的学生.接受CIPS认证课程的毕业生可以自动获得AITP证书,并获得一年的免费的CIPS会员资格. 接受非CIPS认证课程的毕业生需要申请,另外 ...

  8. fopen() 返回 NULL, 奇葩原因:当前进程打开多个句柄,忘记关闭。(bug)

    今天在测试一个程序的时候,突然第一次弹出错误对话框,提示: 创建新文件失败. fopen() 返回 NULL 我又重启程序测试,还是提示同样的错误. 经过几分钟的检查,发现一个规律:当处理到500多个 ...

  9. MongoDB 学习记录(二)yum安装

    前言:接着上篇继续学习MongoDB,这次学习的是在Linux下安装MongoDB 环境:centos7.3 安装版本:MongoDB4.0 官网安装教程地址 https://docs.mongodb ...

  10. C语言进阶--DAY3

    主要讲解数组和指针有关问题 1. 数组名的本质是一个常量指针 2. 内存编址的最小单位是字节,对于变量来说,一个变量可以取1.2.4.8等字节,对变量取地址来说,取的是低位字节的地址,在32位机中其对 ...