在springboot中使用JPA 笔记

本文详细介绍SpringBoot中使用JPA进行数据库操作的方法,涵盖环境搭建、基本注解使用、实体映射、数据访问接口定义及控制器编写,适合初学者快速入门。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近,在学习jhipster过程中看到JPA,因为之前没结果或者说接触过了也不知道,所以专门记录一下。

定义

Java Persistence API :用于对象持久化的 API

Java EE 5.0 平台标准的 ORM规范,使得应用程序以统一的方式访问持久层

JPA 是 hibernate 的一个抽象(就像JDBC和JDBC驱动的关系)
JPA是规范,Hibernate 是实现

JPA 包括 3方面的技术

  1. ORM  映射元数据:JPA 支持 XML 和  JDK 5.0 注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中。
  2. JPA 的 API:用来操作实体对象,执行CRUD操作,框架在后台完成所有的事情,开发者从繁琐的 JDBC和 SQL代码中解脱出来。
  3. 查询语言(JPQL):这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序和具体的  SQL 紧密耦合。
JPA基本注解

JPA 基本注解:@Entity, @Table, @Id, @GeneratedValue, @Column, @Basic,@Transient, @Temporal, 用 table 来生成主键详解。具体使用时大家可以查询搜索引擎,也可以在使用的查看源代码了解。

springboot 中使用JPA

环境:windows7+idea+jdk8
步骤:

  1. 使用idea创建一个springboot项目,勾选JPA,thymeleaf等,最终项目生成的pom.xml中要包含:
<!--JPA-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
    <!--mysql数据库jdbc驱动(也可以选oracle数据库jdbc驱动)-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.40</version>
        </dependency>

  1. 配置数据库相关的属性

    # 驱动
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    # 数据库地址
    spring.datasource.url=jdbc:mysql://localhost:3306/jpatest
    # 数据库用户
    spring.datasource.username=root
    # 数据密码
    spring.datasource.password=123456
    # 配置了实体类维护数据库表结构的具体行为:
    # update表示当实体类的属性发生变化时,表结构跟着更新,
    # create表示启动的时候删除上一次生成的表,并根据实体类重新生成表,这个时候之前表中的数据就会被清空;
    # create-drop表示启动时根据实体类生成表,但是当sessionFactory关闭的时候表会被删除;
    # validate表示启动时验证实体类和数据表是否一致;
    # none表示啥都不做。
    spring.jpa.hibernate.ddl-auto=update
    # 表示hibernate在操作的时候在控制台打印真实的sql语句
    spring.jpa.show-sql=true
    # 表示格式化输出的json字符串
    spring.jackson.serialization.indent_output=true
    
  2. 定义映射实体

    
    /**
     * 定义TabProject实体
     * 所有的实体类似
     */
    @Entity
    @Table(name = "tab_project")
    public class TabProject implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @Column(name = "pro_name")
        private String proName;
    
        @Column(name = "pro_creater")
        private String proCreater;
    
        @Column(name = "createtime")
        private LocalDate createtime;
    
        @Column(name = "pro_update")
        private String proUpdate;
    
        @Column(name = "updatetime")
        private LocalDate updatetime;
    //set,get方法省略
    }
        
    
  3. 定义数据访问接口

    之前有用过springMVC,大概要分成domain,service,controller这几层,sprinBoot也是一样的,起初我还认为有了JPA之后,只需要中间的repository这一层,就代替了service。所以觉得就可以不需要service这一层,dan其实,在项目中,这一层还是不可少的,因为要写与业务相关的内容在这一层写是最合适的,后期维护也非常方便,repository这一层还是直接与底层数据库交互。

    关于数据访问接口的几点

    1. 继承JpaRepository接口,就自动具备部分数据访问方法,具体可查源码。

    2. 自定义方法可以按照属性名来查询,但是方法的命名方式是固定的,比如第一个方法和第二个方法,第一个方法表示根据一个属性查询,第二个方法表示根据多个属性查询,findBy、And等可以算作是这里的查询关键字了,如果写作其他名称则系统不能识别,类似的关键字还有Like、Or、Is、Equals、Between等,而这里的findBy关键字又可以被find、read、readBy、query、queryBy、get、getBy等来代替。

    3. 在查询的过程中我们也可以限制查询结果,这里使用的关键字是top、first等

    4. 使用NamedQuery来查询,就是直接在实体类上使用@NamedQuery注解来定义查询方法和方法名,一个名称对应一个查询语句。

    5. 也可以向第三个方法那样添加@Query注解,当我调用这个方法的时候使用这个注解中的sql语句进行查询,方法的参数则是注解中的占位符的值。

    6. 注意HQL和SQL语句的区别(建议简单的可以学习使用HQL,如果是比较复杂的可以使用SQL)

    @Repository
    public interface TabProjectRepository extends JpaRepository<TabProject, Long> {
        /**
         * 使用内部定义方法名称获取数据,不写sql语句
         * @param proName
         * @return
         * */
        TabProject findByProName(String proName);
    
    
        /**
         *自定义,使用HQL语句
         * @param name
         * @return
         * */
        @Query("select * from TabProject p where p.proName=:name ")
        TabProject withNameQuery(@Param("name") String name);
        
         /**
         *自定义,使用SQL语句
         * @return
         * */
        @Query("select proName,count(id)  as total from TabProject p group by  proName ",nativeQuery = true)
         List<Map<String,Object>> getProjectCount();
    
    
    }
    
  4. 编写controller

    @RestController
    @RequestMapping("/api")
    public class ProjectController {
        @Autowired
        TabProjectRepository tabProjectRepository;
    
        @GetMapping("/tab-projects/name/{proname}")
        public TabProject findByName(@PathVariable("proname") String proName ){
            return tabProjectRepository.findByProName(proName);
    
        }
    
        @GetMapping("/tab-projects/proname/{proname}")
        public TabProject withNameQuery(@PathVariable("proname") String proName ){
            return tabProjectRepository.withNameQuery(proName);
    
        }
        
        @GetMapping("/tab-projects/project/count")
        public TabProject getProjectCount(){
            return tabProjectRepository.getProjectCount();
    
        }
    }
    
  5. 后记

    至于测试这些东西,就自己去弄了,写单元测试也行,或者直接在浏览器里输入要访问地址,比如http://localhost:8080/api/tab-projects/name/122, 看结果。

  6. 参考文档

    1. _江南一点雨
    2. liucw_cn
    3. 杂七杂八
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值