手把手搭建springboot项目04-springboot整合JPA-Hibernate + QueryDSL

本文介绍了如何在SpringBoot项目中整合JPA和Hibernate,包括引入依赖、配置数据库、创建实体类、定义数据库接口和服务层。接着,文章讲解了QueryDSL的引入、配置和使用,它是SpringDataJPA的扩展,提供了一种面向对象的查询方式。最后,对比了Mybatis和Hibernate的特点。

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


前言

概念了解

  • ORM:对象关系映射,为了解决面向对象与关系数据库存在的互不匹配的现象的技术。(表字段映射实体类)
  • ORM框架:连接数据库的桥梁,只要提供了持久化类与表的映射关系,ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中
    常用的ORM框架有Mybatis、Hibernate
  • JPA(Java Persistence API):是一种ORM规范。把开发者从繁琐的SQL代码中解脱出来。
  • Hibernate 实现了 JPA 规范
  • Spring Data Jpa: spring 提供的一套简化 JPA 开发的框架,可以在不写接口实现的情况下,实现对数据库的访问和操作。也有如分页、排序、复杂查询等等功能。(Spring Data JPA 可以理解为 JPA 规范的再次封装抽象,底层还是使用了 Hibernate 的 JPA 技术实现。)
  • QueryDSL:在 SpringData JPA 的基础上,更近一步,更面向对象提供了统一的类型安全的查询方式。

提示:以下是本篇文章正文内容,下面案例可供参考

一、SpringBoot整合JPA-Hibernate

1.1 引入依赖

<!--引入jpa-->
<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
</dependency>

在这里插入图片描述

1.2 修改application.properties配置

#连接数据库
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3366/springboot-demo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
 
# jpa的相关配置
# 数据库类型
spring.jpa.database = MYSQL
# 打印sql
spring.jpa.show-sql = true
# 指定数据库的初始化模式
# none不指定、
# create应用运行时,会删除并重新创建数据库(数据清空)
# create-drop 当sessionFactory关闭,表会自动删除
# validate 应用运行时,会检查数据库中的表与java实体类是否匹配。如果不匹配,则运行失败
# update 当在java实体类中新增了一个字段,在应用重新运行时,会将字段添加到数据库表中的新列,但不会移除先前存在的列或约束
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# stripped before adding them to the entity manager)
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

1.3 创建实体类(注解式开发无需.hbm.xml文件)

常用注解:

类注解:

  1. @Entity 标识实体类,被Entity标注的实体类将会被JPA管理控制,在程序运行时,JPA会识别并映射到指定的数据库表
  2. @Table 想生成的数据库表名与实体类名称不同时,使用 @Table(name=“数据库表名”),与@Entity标注并列使用

属性注解:

  1. @Id 映射为数据库主键
  2. @GeneratedValue与@Id一同使用,用于标注主键的生成策略,通过 strategy 属性指定。(DENTITY:主键自增,AUTO:JPA 自动选择合适的策略默认选项。)
  3. @Column 参数:name: 指定映射的字段名,默认不唯一、默认可为空、默认可插入、默认允许更新
  4. @Transient 忽略该属性,不会映射到数据库中
  5. @OneToOne 一对一,targetEntity: 指定关联实体类型、cascade:级联操作策略、fetch:该属性的加载读取策略、mappedBy: 指定关联关系。
  6. @ManyToOne
  7. @OneToMany
  8. @ManyToMany
  9. @Enumerated 希望数据库中存储的是枚举对应的String类型,在属性上加@Enumerated(EnumType.STRING)
@Entity
@Table(name = "school")
public class School {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer id;

  @Column(length = 40)
  private String name;

  @OneToOne(cascade = CascadeType.ALL)
  private SchoolMaster schoolMaster;
  //get、set方法
}

1.4 定义数据库接口

// hibernate的接口,springboot整合hibernate用的是jpa,接口要继承JpaRepository
// 里面已经集成了增删改查方法,额外的查询需要我们手动添加方法HQL
public interface SchoolRepository extends JpaRepository<School,Integer> {
    //JPA方法名命名规则
    public School findTopById(Long id); 
 	// 这是HQL :xx 指传入参数,跟下面注解@Param对应
    //@Query(value = "SELECT s FROM School s WHERE name=:name")     
    //List<School> findByName(@Param("name") String name);
    // 原生SQL   
    @Query(value = "SELECT * FROM School WHERE name=?", nativeQuery = true)   nativeQuery为true代表使用SQL语言
    public School findByName(@Param("name") String name);
}

在这里插入图片描述

1.5 service层

@Service
public class SchoolService {
    @Autowired
    private SchoolRepository schoolRepository;

    public List<School> findByName(String name){
        return schoolRepository.findByName(name);
    }
    
    public void save(School school){
        schoolRepository.save(school);
    }
}

1.6 Controller层

@Controller
public class SchoolController {
 
    @Autowired
    private SchoolService schoolService;
 
    @RequestMapping("/findByName")
    @ResponseBody
    public String findByName(String name){
        return schoolService.findByName(name).toString();
    }
 
    @RequestMapping("/save")
    @ResponseBody
    public String save(){
        School school = new School();
        school.setName("张三");
        schoolService.save(school);
        return "插入成功,id=" + school.getId();
    }
 
}

二、 QueryDSL

SpringData JPA 封装了一些列的类和方法(Specification、Pageable分页),不需要写 SQL,以一种面向对象的方式进行数据的查询。
而QueryDSL 则是在 SpringData JPA 的基础上,更面相对象。

2.1 引入依赖

<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-apt</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-jpa</artifactId>
</dependency>

<!-- 代码生成插件配置 -->
<plugin>
    <groupId>com.mysema.maven</groupId>
    <artifactId>apt-maven-plugin</artifactId>
    <version>1.1.3</version>
    <executions>
        <execution>
            <goals>
                <goal>process</goal>
            </goals>
            <configuration>
                <outputDirectory>target/generated-sources/java</outputDirectory>
                <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
            </configuration>
        </execution>
    </executions>
</plugin>

为了满足 QueryDSL 查询的规范,我们需要为每一个持久化类生成一个对应的 EntityPath,这个过程可通过 maven 插件自动生成。添加该插件,执行 maven compile 后,会在 entity 同名的包下生成 Q 开头的类。
在这里插入图片描述

2.2 配置

1、注入一个 JPAQueryFactory 对象,通过它来执行各种查询操作,可类比 JdbcTemplate。

@Configuration
public class QuerydslConfig {
    @Bean
    public JPAQueryFactory jpaQuery(EntityManager entityManager) {
        return new JPAQueryFactory(entityManager);
    }
}

2.3 使用

@RestController
public class SchoolController {

    @Autowired
    private JPAQueryFactory jpaQueryFactory;

    @GetMapping("/findByName")
    public List<School> findByName(String name){
    	QSchool qSchool = QSchool.school;
        School school = jpaQueryFactory
        		.selectFrom(qSchool)
                .where(qSchool.name.like(name))
                .fetchFirst();
        return school.getName();
    }
}

总结

Mybatis可以进行更细致的SQL优化,数据库的移植性较差,针对不同的数据库编写不同的SQL。

Hibernate对数据库提供了较为完整的封装,封装了基本的DAO层操作,有较好的数据库移植性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值