spring-boot 从零开始-03

spring-boot中的JPA

这里不介绍数据库如何安装,如需要安装请自行百度

1.什么是JPA?JPA用来干什么?
2.有哪些JPA的实现?
3.如果在spring boot如何实现JPA

1.什么是JPA?JPA用来干什么?

JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。
持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在的数据库中,或者存储在磁盘文件中、XML数据文件中等等。
持久化是将程序数据在持久状态和瞬时状态间转换的机制。
JDBC就是一种持久化机制。文件IO也是一种持久化机制。

题外话:换言之,JPA就是一个储存的标准,太规范了数据持久化的标准,用于数据持久化

1.1什么是Spring data

Spring Data是一个用于简化数据库访问,并支持云服务的开源框架。其主要目标是使得数据库的访问变得方便快捷,并支持map-reduce框架和云计算数据服务。此外,它还支持基于关系型数据库的数据服务,如Oracle RAC等。对于拥有海量数据的项目,可以用Spring Data来简化项目的开发,就如Spring Framework对JDBC、ORM的支持一样,Spring Data会让数据的访问变得更加方便。

2.有哪些JPA的实现?

Hibernate,EclipseLink(曾经的toplink),OpenJPA等可供选择,所以使用JPA的一个好处是,可以更换实现而不必改动太多代码

3.如果在spring boot如何实现JPA--spring boot JPA

(1)在pom.xml添加mysql,spring-data-jpa依赖;
(2)在application.properties文件中配置mysql链接配置文件
(3)在application.properties文件中配置JPA配置信息;
(4)编写测试例子

(1)在pom.xml添加mysql,spring-data-jpa依赖
    <!-- 数据库mysql依赖包 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.13</version>
    </dependency>
    
    <!-- 配置spring-data-jpa依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
(2)在application.properties文件中配置mysql链接配置文件

新建文件夹src/main/resources,在resources目录下new->file, 取名字为application.properties固定写法。一定要在指定的路径下面新建,否则无法找到该文件。

(3)在application.properties文件中配置JPA配置信息

输入配置数据库配置信息

##################################
# 数据库基本配置
# 数据库username和password
# 驱动,链接方式
# 最大连接
# 初始大小
##################################
spring.datasource.url=jdbc:mysql://localhost:3306/avalanching_crm
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.max-active=20
spring.datasource.max-idle=8
spring.datasource.min-idle=8
spring.datasource.initial-size=10

##################################
# 数据库基本配置
# 数据库类型
# 是否现实sql语句
# 最大连接
# 初始大小
##################################
spring.jpa.database = MYSQL
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

注意:spring.datasource.driverClassName,很多教程里面都是写com.mysql.jdbc.Driver,而非com.mysql.cj.jdbc.Driver,这里需要根据你当前mysql和驱动版本决定的,如果无法确定两者都尝试一下即可

(4)编写测试例子

新建package


image.png

model:随意创建的,名字自己取,后面都是这个package的子包
bean:是用来存放我们数据库实体类的,里面属性为private(私有的),提供public(公开的)setting和getting方法供外部调用
controller:处理请求类,控制器类,处理外部的请求,完成相应的操作,把结果返回给请求者
repository:这里需要一个接口类,这个定义了JPA的基本操作,例如增删查改
service:提供外部调用数据库操作

具体代码如下:
在bean package下创建:Dog实体类

package com.avalanching.spring_hellow.model.JPADemo.bean;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 * 创建一个实体类
 * 1.使用@Entity进行实体类的持久化操作,当JPA检测到 
 * @Entity 将在数据库中创建表结构
 */
@Entity
public class Dog {
    /**
     * @id 指定主键
     * @GeneratedValue(strategy=GenerationType.AUTO) 指定主键的生成规则
     * mysql默认自增长
     **/
    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id; // 主键
    private String name;
    private int age;
    private String remark;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getRemark() {
        return remark;
    }
    public void setRemark(String remark) {
        this.remark = remark;
    }
}

repository package下创建:DogRepository接口

package com.avalanching.spring_hellow.model.JPADemo.repository;

import org.springframework.data.repository.CrudRepository;
import com.avalanching.spring_hellow.model.JPADemo.bean.Dog;

/**
 * DogRepository这个接口继承与CrudRepository
 * 源码定义:
 * public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID>
 * <T, ID extends Serializable>
 * T:是一个范型,这里传入的类型是一个实体类,需要操作那个数据实体就传入,
 *   这里需要操作Dog,所以传入Dog
 * ID extends Serializable: 这里传入的是主键的类型,Dog的主键是id,然后定义的是int
 *                          这里最好将组件定义为Integer,int长度非常有限
 * 此处为一个接口,暂无需要写方法,这里主要是一种规范行为
 */
public interface DogRepository extends CrudRepository<Dog, Integer> {

}

在service package下创建:DogService类

package com.avalanching.spring_hellow.model.JPADemo.service;

import javax.annotation.Resource;
import javax.transaction.Transactional;

import org.springframework.stereotype.Service;
import com.avalanching.spring_hellow.model.JPADemo.bean.Dog;
import com.avalanching.spring_hellow.model.JPADemo.repository.DogRepository;
/**
 * @Service对应的是业务层Bean 
 * 告诉spring这是一个业务层
 * 相当于在.xml文件配置如下代码
 * <Bean class="com.avalanching.spring_hellow.model.JPADemo.service.DogService">
 *  ........
 * </Bean>
 */
@Service
public class DogService {
    /**
     * @Resource(这个注解属于J2EE的),
     * 默认安照名称进行装配,名称可以通过name属性进行指定。  
     * 简单来说就是自动new DogRepository的对象,并赋值给dogRepository这个属性
     * 自动装配属性
     */
    @Resource
    private DogRepository dogRepository;
    
    /**
     * @Transactional 标签进行事务绑定
     * 可以简单理解,只要对数据库里面的内容操作就最好绑定事务
     * insert, update, delete等操作
     **/
    @Transactional
    public void save(Dog dog) {
        dogRepository.save(dog);
    }
    
    @Transactional
    public void delete(int id) {
        dogRepository.delete(id);
    }
    
    @Transactional
    public void deleteAll() {
        dogRepository.deleteAll();
    }
    
    public Iterable<Dog> getAll() {
        return dogRepository.findAll();
    }
}

在controller package下创建:DogController类

package com.avalanching.spring_hellow.model.JPADemo.controller;

import javax.annotation.Resource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.avalanching.spring_hellow.model.BaseJSONEntity;
import com.avalanching.spring_hellow.model.JPADemo.bean.Dog;
import com.avalanching.spring_hellow.model.JPADemo.service.DogService;

@RestController
@RequestMapping("/dog")
public class DogController {
    
    @Resource
    private DogService dogservice;
    
    @RequestMapping("/save")
    public String save() {
        Dog dog = new Dog();
        dog.setAge(3);
        dog.setName("不二");
        dog.setRemark("666");
        dogservice.save(dog);
        return "success";
    }
    
    @RequestMapping("/delete") 
    public String delete() {
        dogservice.delete(1);       
        return "success";
    }
    
    @RequestMapping("/clean")
    public String clean() {
        dogservice.deleteAll();
        return "success";
    }
    
    @RequestMapping("/find")
    public BaseJSONEntity findDog() {
        Iterable<Dog> list = dogservice.getAll();
        BaseJSONEntity entity = new BaseJSONEntity();
        entity.setCode(0);
        entity.setData(list);
        entity.setMessage("success");
        return entity;
    }
}

启动程序: 输入网址测试,或打开数据库查看

这里建议:使用Postman去测试,safari浏览器修改一次网址它就能自动调用一次,会出现重复调用的现象

自定义Repository

package com.avalanching.spring_hellow.model.JPADemo.repository;

import org.springframework.data.repository.Repository;
import com.avalanching.spring_hellow.model.JPADemo.bean.Dog;


public interface Dog2Repository extends Repository<Dog, Integer> {
    
    /**
     * 1.查询方法以get | find | read 开头 
     * 2.条件的属性用关键字链接,要注意条件属性以首字母大写
     */
    public Iterable<Dog> findByName(String name);
    
}

相应的service和controller添加相应代码

/**
 * DogService代码
 */
// 添加一个Dog2Repository类属性
@Resource
private Dog2Repository dog2Repository;

// 创建一个方法供controller调用
public Iterable<Dog> findDogByName(String name) {
    return dog2Repository.findByName(name);
}
// 在controller中添加一个方法
@RequestMapping("/findname")    
public BaseJSONEntity findDogByName(String name) {
    Iterable<Dog> dog = dogservice.findDogByName(name);
    BaseJSONEntity entity = new BaseJSONEntity();
    entity.setCode(0);
    entity.setData(dog);
    entity.setMessage("success");
    return entity;
}

启动程序之后输入网址:localhost:8080/dog/findname?name="Dog名字"
这里需要注意的是findBy后面必须给查询到属性名,并且首字母大写

编写JPQL语句查询:

/**
     * 如果编写JPQL语句
     * Hibernate --HQL语句
     * JPQL 语句与HQL语句相似
     * @Query标示一个查询语句
     * :name此处为一个占位符,可以任选书写
     **/
    @Query("from Dog where name=:name")
    public Dog findMyDogByName(@Param("name")String name);

如果你的表名为user_table,请换成UserTable,首字母大写,并且没有下划线,后面遵循驼峰命名法

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,490评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,581评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,830评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,957评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,974评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,754评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,464评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,847评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,995评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,137评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,819评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,482评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,023评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,149评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,409评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,086评论 2 355

推荐阅读更多精彩内容