JPA简单练习——通俗易懂

本文介绍了如何在Springboot项目中使用JPA进行快速开发,包括依赖配置、实体类创建、数据库表自动生成、基本操作(增删改查)以及自定义查询(JPQL和原生SQL)。通过实例演示了JPA的便捷性,无需大量编写SQL,提高了开发效率。

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

前言

之前一直使用Mybatis、mplus,最新工作需求,简单学习下Jpa。作为一个ORM框架,JPA给我的感觉是sql粉碎机,你不再需要像mybatis那样频繁的写sql语句了。话不多说,开始整活。


一:依赖配置

本人这里使用的是Springboot项目,管理工具使用的是maven。在pom文件中导入相关依赖。

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

        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <!--数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
            <version>8.0.23</version>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

导入依赖后,还需要添加相关配置。

数据库或jpa其他配置这里先不加,足够练习使用即可。

#配置端口
server:
  port: 8080


#配置数据库
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jpa?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=GMT
    username: root
    password: root
  jpa:
    generate-ddl: true #开发阶段可以设置为true,是否开启逆向工程
    hibernate:
      #create:每次都新建表  create-drop:每次新建,使用完删除
      #none:无效果   update:没有表就新建,有就使用。如果实体类有变化会更新表   validate:实体类和数据库表对比,不一致抛出异常
      ddl-auto: update #常用
    show-sql: true #生成sql
    database-platform: org.hibernate.dialect.MySQL8Dialect  #指定数据库类型

二:代码编写

注意:先不要创建数据库表。这里引入知识点:正向工程和逆向工程。

逆向工程:平时我们先创建数据库表,再创建相应实体类,这种方式可以称为逆向。

正向工程:从代码出发,也就是先创建实体类,再生成数据库。

1:创建实体类

这里使用的是注解方式,比较重要的是@Entity注解,表示对应的表名。@Column表示对应列名。

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity(name = "PET")
public class PetEntity {

    /**
     * @Id 声明主键
     * @GeneratedValue 自增策略
     * @Column 对应列
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private Integer id;

    /**
     * 宠物名
     */
    @Column(name = "P_NAME")
    private String name;

    /**
     * 颜色
     */
    @Column(name = "P_COLOR")
    private String color;

}

将项目启动,(可在springboot启动类或测试类,反正启动就好),数据库即可生成表,列就是实体类定义的属性。

注意:这里从实体类生成数据表是有策略的。ddl-auto:上文的配置文件中有讲到。

2:编写方法及测试

2.1:JAP封装方法。

OK,实体类我们已经创建完毕,表也生成了。接下来我们创建一个mapper。

如同Mybatis-plus一样,JPA也给我们封装好了一些增删改查方法,只需要实现接口即可使用。

 接口和接口之间是继承😀。图上有描述,这里不再赘述。

测试代码:包含增删改查、分页查等一些常用方法。

    @Test
    void jpaInsertTest() {
        PetEntity pet = new PetEntity();
        //如果有id则为修改
        //pet.setId(2);
        pet.setName("小黄");
        pet.setColor("黄色");
        petDao.save(pet);
    }

    @Test
    void jpaSelectByIdTest() {
        //查询单个 得到Optional对象,使用get方法取出
        Optional<PetEntity> optional = petDao.findById(1);
        PetEntity PetEntity = optional.get();
        System.out.println(PetEntity);
    }

    @Test
    void jpaSelectAllTest() {
        //List<PetEntity> petList = petDao.findAll();
        //findAll还可指定参数  Sort:排序
        //注意:desc()里的参数是 实体类 属性,不是列
        List<PetEntity> petList = petDao.findAll(Sort.by(Sort.Order.desc("id")));
        for (PetEntity PetEntity : petList) {
            System.out.println(PetEntity);
        }
    }

    @Test
    void jpaSelectAndPage() {
        //PageRequest.of():填写页码,条目数实现分页
        Pageable pageable = PageRequest.of(0, 1, Sort.Direction.DESC, "id");
        //将pageable放入findAll中,返回分页后的集合数据
        Page<PetEntity> petDaoAll = petDao.findAll(pageable);
        for (PetEntity PetEntity : petDaoAll) {
            System.out.println(PetEntity);
        }

        //petDaoAll.getTotalElements(): 获取总条目数
        System.out.println(petDaoAll.getTotalElements());
        //petDaoAll.getTotalPages(): 获取总页码数
        System.out.println(petDaoAll.getTotalPages());
    }

    @Test
    void jpaDeleteTest() {
        PetEntity PetEntity = new PetEntity();
        PetEntity.setId(1);
        petDao.delete(PetEntity);
    }

2.2:自定义查询(方法)

当JPA封装的方法不足以我们使用时,(如业务字段查询),这时JPA(Mybatis-plus也有)给我们提供的有自定义方法查询。按照固定的格式创建方法名,也可实现不写sql的查询。

    /**
     * 根据名称查询
     *
     * @param pName 宠物名
     * @return 宠物集合
     */
    List<PetEntity> findByName(String pName);

    /**
     * 根据颜色查询
     *
     * @param color 颜色
     * @return 宠物集合
     */
    List<PetEntity> findByColor(String color);

    /**
     * 根据名称颜色查询
     * 注意:方法名不能乱写,根据sql语句写
     *
     * @param name  宠物名
     * @param color 颜色
     * @return
     */
    List<PetEntity> findByNameAndColor(String name, String color);

注意:类似findBy这种就是固定格式,后面跟实体类属性名即可完成对应字段查询。其他增删改大家可以自己探索。

测试代码:这里只展示代码,不展示运行结果了。

    @Test
    void jpaCustomTest() {
        List<PetEntity> byName = petDao.findByName("小黄");
        System.out.println(byName);
        List<PetEntity> byColor = petDao.findByColor("黄色");
        System.out.println(byColor);
    }

    @Test
    void jpaSelectAllByNameAndColorTest() {
        List<PetEntity> byName = petDao.findByName("小黄");
        System.out.println(byName);
        List<PetEntity> byColor = petDao.findByColor("黄色");
        System.out.println(byColor);
        List<PetEntity> byPnameAndColor = petDao.findByNameAndColor("小黄", "黄色");
        System.out.println(byPnameAndColor);
    }

2.3:自定义查询(JPQL)

不想使用固定名字创建方法,那第二种自定义查询就是使用JPQL语句,它和sql的区别是:

sql针对的是数据库表和列

jpql针对的是实体类和属性

使用也很简单,方法上添加@Query注解,里面写JPQL语句即可。

①无参的:

Tips:from实体类的全路径,id,name等都是实体类属性

    /**
     * * jpql查询所有
     * * sql: select * from t_pet
     * * jpql:
     * from com.jpatest.entity.PetEntity
     * select pet from com.jpatest.entity.PetEntity pet
     *
     * @return
     */
    @Query(value = "select pet from com.jpatest.entity.PetEntity pet")
    List<PetEntity> selectPetAll();


    /**
     * 注意:查列返回封装Object[]数组,用实体接收会转换异常
     * select id,name,color from com.changhui.eo.PetEntity
     *
     * @return
     */
    @Query(value = "select id,name,color from com.jpatest.entity.PetEntity")
    List<Object[]> selectAllColumnList();

    /**
     * 查询列且返回实体类接收
     * new 对象,使用实体类的参数构造器
     *
     * @return
     */
    @Query(value = "select new com.jpatest.entity.PetEntity(id,name,color) from com.jpatest.entity.PetEntity ")
    List<PetEntity> selectAllPetListForColumn();

②带参数的话,会有两种参数使用方式:顺序参数具名参数

顺序参数:?参数位置

/**
 * 使用jpql顺序查询,根据名称查询
 *
 * @param name 名称
 * @return
 */
@Query(value = "from com.jpatest.entity.PetEntity where name =?1")
List<PetEntity> selectPetByName(String name);

 具名参数: :Param指定的名字

/**
 * 使用jpql具名查询,根据颜色查询
 *
 * @param color 颜色
 * @return
 */
@Query(value = "from com.jpatest.entity.PetEntity where color = :color")
List<PetEntity> selectPetByColor(@Param("color") String color);

注意:JPQL不支持新增,但可以使用HIbernate实现伪新增,有兴趣的可以了解一下。使用JPQL语句增删改,需要添加@Modifying:告诉JPA此方法是增删改方法。切记。

③如果不想使用JPQL,还可以使用原生Sql语句,在注解后面添加一个属性。

     /**
     * 使用原生sql查询
     * 添加 nativeQuery = true,即代表使用原生sql,不再使用类,使用数据库
     *
     * @param color 颜色
     * @return
     */
    @Query(value = "SELECT * FROM pet WHERE p_color = :color", nativeQuery = true)
    List<PetEntity> selectPetByColorForTable(@Param("color") String color);

测试就不要贴了,就是普通的dao层方法调用。


好了,其实jpql还可以使用createQuery等实现,练习到这里了,有兴趣的可以自行检索。项目已同步至gitee,大家可以去拉取代码,希望留下你的小星星。

tu.gitee/jpa-exercisehttps://gitee.com/aaaaaafdf/jpa-exercise

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值