SpringBootJPA详解

一、SpringBootJPA教程

SpringBootJPA是在Spring Boot框架下的Java语言持久化框架。

使用JPA编写数据库访问层,相较于mybatis优点是可以使用JPA(Java Persistence API)的各种特性,比如使用EntityManager直接进行增删改查等。因为JPA api是javax.persistence包下的,和JavaEE耦合度较高,而Hibernate、mybatis等持久化框架是单独的jar包,和JavaEE的耦合度较低,所以开发者可以根据自己项目的特点选择适合的持久化框架。

SpringBootJPA相较于Hibernate框架,提供更简洁的API接口,也更加易于使用。

// 引入Spring Boot starter用于简化pom.xml文件
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

二、SpringBootJPA配置多数据源

在SpringBoot项目中,配置多数据源步骤如下:

1、定义数据源

@Configuration
public class DataSourceConfig {

    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource.one")
    public DataSource dataSourceOne(){
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.two")
    public DataSource dataSourceTwo(){
        return DataSourceBuilder.create().build();
    }

}

2、配置JPA数据源

@Configuration
@EnableJpaRepositories(basePackages = "com.example.demo.repository.one",
        entityManagerFactoryRef = "entityManagerFactoryOne",
        transactionManagerRef = "transactionManagerOne")
public class JpaConfigOne {

    @Autowired
    @Qualifier("dataSourceOne")
    private DataSource dataSourceOne;

    @Bean("entityManagerFactoryOne")
    public LocalContainerEntityManagerFactoryBean setEntityManagerFactoryOne(EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(dataSourceOne)
                .packages("com.example.demo.entity.one")
                .persistenceUnit("persistenceUnitOne")
                .build();
    }

    @Bean(name = "transactionManagerOne")
    PlatformTransactionManager transactionManagerOne(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(setEntityManagerFactoryOne(builder).getObject());
    }
}

3、配置第二个数据源

@Configuration
@EnableJpaRepositories(basePackages = "com.example.demo.repository.two",
        entityManagerFactoryRef = "entityManagerFactoryTwo",
        transactionManagerRef = "transactionManagerTwo")
public class JpaConfigTwo {

    @Autowired
    @Qualifier("dataSourceTwo")
    private DataSource dataSourceTwo;

    @Bean("entityManagerFactoryTwo")
    public LocalContainerEntityManagerFactoryBean setEntityManagerFactoryTwo(EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(dataSourceTwo)
                .packages("com.example.demo.entity.two")
                .persistenceUnit("persistenceUnitTwo")
                .build();
    }

    @Bean(name = "transactionManagerTwo")
    PlatformTransactionManager transactionManagerTwo(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(setEntityManagerFactoryTwo(builder).getObject());
    }
}

三、SpringBootJPA增删改查

通过使用继承JpaRepository接口的方式,JPA会自动根据方法的命名规则创建具体的SQL语句,从而实现基本的CRUD操作。

public interface UserRepository extends JpaRepository<User, Long> {

    // 根据用户名查询用户
    User findByUsername(String username);

    // 根据id删除用户
    void deleteById(Long id);

    // 根据年龄和性别查询用户
    List<User> findByAgeAndGender(Integer age, Boolean gender);

    // 查询年龄大于等于18岁的用户
    @Query("select u from User u where u.age >= ?1")
    List<User> findByAgeGreaterThanOrEqualTo(Integer age);

}

四、SpringBootJPA常用注解

1、@Entity:被映射到数据库表的实体类,必须带有此注解

2、@Table:指定该实体映射的表名。如果表名和实体类名相同,则此注解可省略不写。

3、@Id:指定作为数据表主键的属性,必须带有此注解。如果主键属性不确定,可以尝试使用@IdClass注解。

4、@GeneratedValue:指定主键生成策略,常用的有AUTO(JPA实现依据底层数据库主键自动匹配)、IDENTITY(使用数据库自增长字段)等等。

5、@Transient:指定该属性在数据库中不需要映射到某个具体的数据库字段上。

五、SpringBootJPA和Mybatis

SpringBootJPA和mybatis都可以作为持久化框架,各有优缺点。可以根据具体的情况选择使用。比如在需要高并发情况下,mybatis的性能优势明显;而对于一些简单业务场景,使用SpringBootJPA进行开发,减少了代码的冗余,对开发效率会有较大提升。

六、SpringBootJPA关闭懒加载

在JPA中,使用懒加载可以避免在需要时浪费太多数据库查询次数,但是在某些情况下,需要关闭懒加载。可以通过在查询时使用@Query注解的join fetch语法来解决这一问题。

@Query("select u from User u join fetch u.roles where u.id = ?1")
User findByIdFetchRole(Long id);

七、SpringBootJPA不支持count

在JPA中,查询数据时提供了众多的查询方式,但是唯一的缺憾就是JPA不支持count,只能使用查询全部列表再计算数量的方式进行统计。

// 查询全部数据
List<User> userList = userRepository.findAll();
// 查询数据量统计
int count = userList.size();

八、SpringBootJPA自动生成表自动生成

使用SpringBootJPA可以自动生成表,也可以指定表的生成策略。

表生成策略

Hibernate底层提供很多种生成策略:

1、create:每次都会删除原表,重新创建新表,如果表中有数据会没有。适合测试环境使用。

2、create-drop:每次生成EntityManagerFactory时根据对应的entities和tables进行创建或者删除表。适合测试环境使用。

3、update:Hibernate根据程序的规则映射到数据库,并根据比较生成不同的SQL语句完成表结构的更新,以达到表结构与程序分离,表结构的更新将经过DDL语句完成,此过程被视为覆盖式生成。适合生产环境和开发模式切换使用。

4、validate:校验数据表中字段与entity中定义是否一致,不一致抛出异常;一致时使用。适合生产环境使用。

spring.jpa.hibernate.ddl-auto=update

九、SpringBootJPA OneToMany

在实际项目中,关于一对多关系的建模比较常见。

1、One端(单表):

@Entity
@Table(name = "t_sys_user")
public class User implements Serializable {
    private static final long serialVersionUID = -1220531363291923315L;

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

    @Column(name = "username")
    private String username;

    @Column(name = "password")
    private String password;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List<Role> roles;
} 

2、Many端(多表):

@Entity
@Table(name = "t_sys_role")
public class Role implements Serializable {
    private static final long serialVersionUID = 7601217352332679224L;

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

    @Column(name = "role_name")
    private String roleName;

    @Column(name = "role_code")
    private String roleCode;

    @Column(name = "remark")
    private String remark;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;
} 

user端有一个List<Role> roles,表示该user对应多个Role实体,@OneToMany表示一对多的关系。mappedBy = “user”表示该关系由Role实体的user属性维护。

Role端则包含了一个User类型的属性,表示该Role所对应的User实体。

可以通过user.getRoles()获取该用户对应的多个角色信息。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/189894.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝的头像小蓝
上一篇 2024-11-29 13:52
下一篇 2024-11-29 13:52

相关推荐

  • 神经网络代码详解

    神经网络作为一种人工智能技术,被广泛应用于语音识别、图像识别、自然语言处理等领域。而神经网络的模型编写,离不开代码。本文将从多个方面详细阐述神经网络模型编写的代码技术。 一、神经网…

    编程 2025-04-25
  • Linux sync详解

    一、sync概述 sync是Linux中一个非常重要的命令,它可以将文件系统缓存中的内容,强制写入磁盘中。在执行sync之前,所有的文件系统更新将不会立即写入磁盘,而是先缓存在内存…

    编程 2025-04-25
  • Java BigDecimal 精度详解

    一、基础概念 Java BigDecimal 是一个用于高精度计算的类。普通的 double 或 float 类型只能精确表示有限的数字,而对于需要高精度计算的场景,BigDeci…

    编程 2025-04-25
  • Python安装OS库详解

    一、OS简介 OS库是Python标准库的一部分,它提供了跨平台的操作系统功能,使得Python可以进行文件操作、进程管理、环境变量读取等系统级操作。 OS库中包含了大量的文件和目…

    编程 2025-04-25
  • Python输入输出详解

    一、文件读写 Python中文件的读写操作是必不可少的基本技能之一。读写文件分别使用open()函数中的’r’和’w’参数,读取文件…

    编程 2025-04-25
  • git config user.name的详解

    一、为什么要使用git config user.name? git是一个非常流行的分布式版本控制系统,很多程序员都会用到它。在使用git commit提交代码时,需要记录commi…

    编程 2025-04-25
  • C语言贪吃蛇详解

    一、数据结构和算法 C语言贪吃蛇主要运用了以下数据结构和算法: 1. 链表 typedef struct body { int x; int y; struct body *nex…

    编程 2025-04-25
  • MPU6050工作原理详解

    一、什么是MPU6050 MPU6050是一种六轴惯性传感器,能够同时测量加速度和角速度。它由三个传感器组成:一个三轴加速度计和一个三轴陀螺仪。这个组合提供了非常精细的姿态解算,其…

    编程 2025-04-25
  • nginx与apache应用开发详解

    一、概述 nginx和apache都是常见的web服务器。nginx是一个高性能的反向代理web服务器,将负载均衡和缓存集成在了一起,可以动静分离。apache是一个可扩展的web…

    编程 2025-04-25
  • Linux修改文件名命令详解

    在Linux系统中,修改文件名是一个很常见的操作。Linux提供了多种方式来修改文件名,这篇文章将介绍Linux修改文件名的详细操作。 一、mv命令 mv命令是Linux下的常用命…

    编程 2025-04-25

发表回复

登录后才能评论