Spring Boot学习笔记二:使用JPA

前面已经初步搭建好了SpringBoot,那么在日常开发中不可避免的会用到数据库,那么现在我们开始在SpringBoot上使用JPA吧。

那么什么是JPA(Java Persistence API),中文名Java持久层API。是一套Sun公司Java官方制定的ORM 方案

ORM是什么

ORM(Object Relational Mapping)对象关系映射。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。

ORM有什么用?

在操作数据库之前,先把数据表与实体类关联起来。然后通过实体类的对象操作(增删改查)数据库表,这个就是ORM的行为!

所以ORM是一个实现使用对象操作数据库的设计思想。

所以JPA只是一套实现ORM理论的接口,我们必须要有具体的实现者(Hibernate,TopLink,JDO)才可以完成ORM操作功能的实现。

使用流程

首先在pom.xml文件中添加依赖:

<dependency>
        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-data-jpa</artifactId>

</dependency>

<dependency>

            <groupId>mysql</groupId>

            <artifactId>mysql-connector-java</artifactId>

</dependency>

接下来需要我们在application.properties中配置数据源和jpa的基本的相关属性,如下:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://填写自己的机器:3306/填写自己的库?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
spring.datasource.username=填写自己的
spring.datasource.password=填写自己的

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jackson.serialization.indent_output=true

1.第一行表示驱动的名称,这个和具体的数据库驱动有关,视情况而定,我这里使用了MySql数据库,所以驱动名为com.mysql.cj.jdbc.Driver
2.第二行表示数据库连接地址,当然也是视情况而定
3.第三四行表示数据库连接的用户名和密码
4.第五行则配置了实体类维护数据库表结构的具体行为,update表示当实体类的属性发生变化时,表结构跟着更新,这里我们也可以取值create,这个create表示启动的时候删除上一次生成的表,并根据实体类重新生成表,这个时候之前表中的数据就会被清空;还可以取值create-drop,这个表示启动时根据实体类生成表,但是当sessionFactory关闭的时候表会被删除;validate表示启动时验证实体类和数据表是否一致;none表示啥都不做。
5.第六行表示hibernate在操作的时候在控制台打印真实的sql语句
6.第七行表示格式化输出的json字符串
以上就是我们在application.properties中对JPA进行的一个简单配置。

然后定义相应的实体类,在Project启动时,系统会根据实体类创建相应的数据表

@Entity
@Table(name="t_user",catalog = "hd_text")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    private Integer age;

    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 Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

@Entity注解:这个表示这是一个和数据库表映射的实体类
@Table:声明此对象映射到数据库的数据表,通过它可以为实体指定表(talbe),name 用来命名当前实体类 对应的数据库表的名字,catalog用于设置表所属的数据库目录或模式,通常为数据库名
@Id注解:表示该字段是一个id
@GeneratedValue注解:则表示该字段自增

接下来我们定义数据访问接口了,我们的数据访问接口需要继承JpaRepository类

public interface UserRepository extends JpaRepository<User,Integer> {

    User findByName(String name);

    List<User>findByAge(Integer age);

    @Query("select u from t_user u where u.age=:age order by u.age  desc")
    List<User>findByAgeSort(Integer age);

}

1.当我们继承JpaRepository接口后,我们就自动具备了如下数据访问方法:

List<T> findAll();
List<T> findAll(Sort var1);
List<T> findAll(Iterable<ID> var1);
<S extends T> List<S> save(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);

2.我们可以在接口中定义查询方法,可以按照属性名来查询,但是方法的命名方式是固定的,比如第一个方法和第二个方法,第一个方法表示根据一个属性查询,第二个方法表示根据多个属性查询,findBy、And等可以算作是这里的查询关键字了,如果写作其他名称则系统不能识别,类似的关键字还有Like、Or、Is、Equals、Between等,而这里的findBy关键字又可以被find、read、readBy、query、queryBy、get、getBy等来代替。
3.在查询的过程中我们也可以限制查询结果,这里使用的关键字是top、first等
4.我们也可以向第三个方法那样添加@Query注解,就是使用原生的sql语句(根据数据库的不同,在sql的语法或结构方面可能有所区别)进行查询数据库的操作

接下来就差一个Controller了,我们写一个简单的Controller,用来测试一下上文中的数据访问接口是否正确

@Controller
public class TextController {

    @Autowired
    UserRepository userRepository;

    @RequestMapping("/save")
    public User save(String name,Integer age) {
        User user = new User();
        user.setAge(age);
        user.setName(name);
        userRepository.save(user);
        return user;
    }
}

然后发现启动的时候一直报错:Validation failed for query for method public abstract


image.png

去网上找,发现使用原生sql要加上nativeQuery = true

@Query(value = "select u from t_user u where u.age=:age order by u.age desc",nativeQuery = true)
List<User>findByAgeSort(Integer age);

OK,启动成功

用Postman测试一下


image.png

OK,这样我们就可以使用JPA了

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