springboot整合JPA+MYSQL+queryDSL数据增删改查

Posted wb54979

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot整合JPA+MYSQL+queryDSL数据增删改查相关的知识,希望对你有一定的参考价值。

Spring Boot Jpa 是 Spring 基于 ORM 框架、Jpa 规范的基础上封装的一套 Jpa 应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data Jpa 可以极大提高开发效率。

 下面对JPA快速入门做个介绍

一:什么是JPA

JPA的英文全称是Java PersistenceAPI, 目的是给Java开发者提供对象关系映射工具用于在

Java应用程序开发中来管理关系数据(RDBMS)。JavaPersistence 包含下面三个部分:

a.      Java持久化API

b.      JPA查询语言

c.      对象关系映射元数据

二:JPA有哪些框架提供了的实现

当前JPA提供厂商有Hibernate, Apache, Eclipse Link等,Google云计算平台 AppEngine也使

用了JPA作为持久层。JPA作为持久层框架有如下优点:

1.      简单易用,帮助开发者提供了生产率

2.      便于维护,减低了维护成本

3.      学习成本相对比较低。

但是JPA的缺点也是显而易见,JPA作为持久层有如下缺点:

1.      将语言与数据库混在一起,导致数据改动以后,配置文件必须更新

2.      对与多数据与大数据量处理很容易产生性能问题。

3.      过度封装,导致错误查找相对与JDBC等传统开发技术而言更加困难

三:标准的JPA规范JSR粗略解读

JPA的最新规范为JSR Java PersistenceAPI Version 2.0

Entity Class – 实体类,必须使用注解@entity标明,同时必须有一个无参数的构造函数,而

且无参数构造函数必须为public或者protected,如果一个entity class被标记为final将导致

出错。

EntityManager – 实体管理者,管理Entity实例的整个生命周期,而且使用Query API来查询

实体与他们的persist状态。

Query Language – 基于字符串的查询语句,用来查询实体(Entity)与他们的状态。

MetaModel API – 通过EntityManagerFactory或者EntityManager的getMetamodel()方法获取,

查看persistence-unit的信息。

实体管理者与持久化上下文(Entity Manager and Persistence contexts)

Persistence Contexts – 一个被管理的实体的实例集合,在一个持久化上下文中的所有实例都

由Entity Manager来管理它们整个生命周期。

持久化单元(Persistence-Unit) – 一个持久化单元是个逻辑分组包括以下部分:

-         一个实体管理者工厂及它的实体管理者

-         被管理的class集合,在persistence unit配置文件中定义

-         映射元数据– 注解定义或者xml定义匹配的类

-          

ORM元数据(MetaData forObject/Relational Mapping) – 坦白的说就annotation的各种解释与

使用。

详细了解请阅读Oracle官方文档 - 《persistence-2_0-final-spec》PDF文档。

四:JPA简单实例说明

1.      使用ObjectDB作为数据库,关于ObjectDB请参考ObjectDB - Object Database for Java (JPA/JDO)

SpringBoot整合JPA简单实例:

1 导入maven依赖jar包:
 

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

2 在application.properties配置JPA属性,数据库连接属性:

# 连接数据库
spring.datasource.url=jdbc:mysql://localhost:3314/dealer?characterEncoding=utf-8&amp;autoReconnect=true&amp;connectTimeout=3000&amp;socketTimeout=60000
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

3 项目结构

 4 定义数据库模型

@Entity
@Table(name = "dealer_role")
public class DealerRole implements Serializable 

    @Id
    @Column(name = "id")
    private String roleId;

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

    @Column(name = "role_create_type")
    private Integer roleCreateType;

    @Column(name = "role_type")
    private Integer roleType;

    @Column(name = "base_id")
    private String baseId;

    @Column(name = "create_time")
    private Date createTime;

    @Column(name = "last_update_time")
    private Date lastUpdateTime;

    @Column(name = "create_user_id")
    private String createUserId;

    @Column(name = "last_update_user_id")
    private String lastUpdateUserId;

   

    public String getRoleId() 
        return roleId;
    

    public void setRoleId(String roleId) 
        this.roleId = roleId;
    

    public String getRoleName() 
        return roleName;
    

    public void setRoleName(String roleName) 
        this.roleName = roleName;
    

    public Integer getRoleCreateType() 
        return roleCreateType;
    

    public void setRoleCreateType(Integer roleCreateType) 
        this.roleCreateType = roleCreateType;
    

    public Integer getRoleType() 
        return roleType;
    

    public void setRoleType(Integer roleType) 
        this.roleType = roleType;
    

    public String getBaseId() 
        return baseId;
    

    public void setBaseId(String baseId) 
        this.baseId = baseId;
    

    public Date getCreateTime() 
        return createTime;
    

    public void setCreateTime(Date createTime) 
        this.createTime = createTime;
    

    public Date getLastUpdateTime() 
        return lastUpdateTime;
    

    public void setLastUpdateTime(Date lastUpdateTime) 
        this.lastUpdateTime = lastUpdateTime;
    

    public String getCreateUserId() 
        return createUserId;
    

    public void setCreateUserId(String createUserId) 
        this.createUserId = createUserId;
    

    public String getLastUpdateUserId() 
        return lastUpdateUserId;
    

    public void setLastUpdateUserId(String lastUpdateUserId) 
        this.lastUpdateUserId = lastUpdateUserId;
    

5 定义Repository接口的使用

@Repository
public interface DealerRoleRepository extends JpaRepository<DealerRole,String> 

    /**
     * 根据角色类型查询
     * @param roleType
     * @return
     */
    List<DealerRole> findDealerRoleByRoleType(Integer roleType);

    /**
     * 自定义查询
     * @param roleName
     * @param roleType
     * @return
     */
    @Query(value="SELECT * from dealer_role where role_type=?1 AND role_name=?2",nativeQuery=true)
    List<DealerRole> selectDealerRole(Integer roleType,String roleName);

6 定义调用接口

@Service
public class DealerRoleService 

    @Autowired
    private DealerRoleRepository dealerRoleRepository;

    /**
     * 测试新增
     * @param dealerRole
     */
    public void testSave(DealerRole dealerRole)
        System.out.println("dealerRole:"+JSON.toJSONString(dealerRole));
        dealerRoleRepository.save(dealerRole);
    

    /**
     * 测试查询
     * @param id
     */
    public void testQuery(String id)
        System.out.println("query param is:"+id);
        Optional<DealerRole> role = dealerRoleRepository.findById(id);
        System.out.println(JSON.toJSONString(role));
    

    /**
     * 查询返回集合
     * @param roleType
     */
    public void testQueryList(Integer roleType)
        System.out.println("query param is:"+roleType);
        List<DealerRole> roles = dealerRoleRepository.findDealerRoleByRoleType(roleType);
        System.out.println(JSON.toJSONString(roles));
    

    /**
     * 分页查询
     * @param role
     * @param pageNum
     * @param pageSize
     */
    public void  testPageQueryList(DealerRole role,Integer pageNum,Integer pageSize)
        if(pageNum == null || pageNum < 1)
            pageNum = 1;
        
        if(pageSize == null)
            pageSize = 10;
        
        int firstResult = (pageNum -1) * pageSize;
        PageRequest pageReques=PageRequest.of(firstResult,pageSize);
        ExampleMatcher matcher = ExampleMatcher.matching();
        if (!StringUtils.isEmpty(role.getRoleName()))
            matcher = matcher.withMatcher("role_name" , ExampleMatcher.GenericPropertyMatchers.contains());
        
        if (role.getRoleType() != null)
            matcher = matcher.withMatcher("role_type" , ExampleMatcher.GenericPropertyMatchers.exact());
        
        Example<DealerRole> example = Example.of(role ,matcher);
        Page<DealerRole> filmPage = dealerRoleRepository.findAll(example, pageReques);
        System.out.println("page:"+JSON.toJSONString(filmPage));
    

    /**
     * 自定义查询返回
     * @param roleType
     */
    public void testCustomQueryList(Integer roleType,String roleName)
        System.out.println("query param is:"+roleType+"-"+roleName);
        List<DealerRole> roles = dealerRoleRepository.selectDealerRole(roleType,roleName);
        System.out.println(JSON.toJSONString(roles));
    

7 单元测试调用

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringjpaTestApplication.class)
@ActiveProfiles(value = "dev")
public class DealerRoleServiceTest 


    @Autowired
    public DealerRoleService dealerRoleService;

    @Test
    public void testSave() 
        DealerRole dealerRole = new DealerRole.Builder()
                .baseId("11111").createTime(new Date()).createUserId("22222")
                .lastUpdateTime(new Date()).lastUpdateUserId("222222").roleCreateType(1)
                .roleId("11111").roleName("vvvvv").roleType(2).builder();
        dealerRoleService.testSave(dealerRole);
    

    @Test
    public void testQuery() 
        dealerRoleService.testQuery("1111");
    

    @Test
    public void testQueryList() 
        dealerRoleService.testQueryList(2);
    

    @Test
    public void  testPageQueryList()
        DealerRole dealerRole = new DealerRole.Builder().roleType(2).builder();
        dealerRoleService.testPageQueryList(dealerRole,0,10);
    

    @Test
    public void testCustomQueryList()
        dealerRoleService.testCustomQueryList(2,"AAAA");
    

8 这里演示一下分页调用查询返回数据的结果


    "content":[
        
            "baseId":"2222",
            "createTime":1648609921000,
            "createUserId":"2",
            "lastUpdateTime":1648609921000,
            "lastUpdateUserId":"2",
            "roleCreateType":1,
            "roleId":"1111",
            "roleName":"3333",
            "roleType":2
        ,
        
            "baseId":"11111",
            "createTime":1648627427000,
            "createUserId":"2222",
            "lastUpdateTime":1648627427000,
            "lastUpdateUserId":"2222",
            "roleCreateType":1,
            "roleId":"2222",
            "roleName":"AAAA",
            "roleType":2
        ,
        
            "createTime":1628057662000,
            "createUserId":"67537",
            "lastUpdateTime":1645771499000,
            "lastUpdateUserId":"4793278492964201783",
            "roleCreateType":1,
            "roleId":"7768960383212294069",
            "roleName":"管理员",
            "roleType":2
        
    ],
    "empty":false,
    "first":true,
    "last":true,
    "number":0,
    "numberOfElements":3,
    "pageable":
        "offset":0,
        "pageNumber":0,
        "pageSize":10,
        "paged":true,
        "sort":
            "empty":true,
            "sorted":false,
            "unsorted":true
        ,
        "unpaged":false
    ,
    "size":10,
    "sort":
        "$ref":"$.pageable.sort"
    ,
    "totalElements":3,
    "totalPages":1


下边简单介绍Spring Boot 中使用QueryDSL

1.Query DSL介绍
      Querydsl定义了一个通用的静态类型语法,用于查询持久化域模型数据。 JDO和JPA是Querydsl的主要集成技术。 本指南介绍如何结合使用Querydsl和JPA。
       针对JPA的Querydsl是JPQL和Criteria查询的替代方案。 它将Criteria查询的动态特性与JPQL的表现力以及完全类型安全的方式相结合。

2.maven集成
 

     <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>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <!--  将生成对应的实例类的操作类  -->
                            <outputDirectory>target/generated-sources/java</outputDirectory>
                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

3:maven仓库插件引入完成双击此处生成Querydsl实体对应的查询Q类记录

4:添加queryDSL配置类


import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.persistence.EntityManager;

/**
 * @Title QueryDSLConfig
 * @Description 添加QueryDSL的配置类
 * @Author wb
 * @Date 2022/3/31 11:24
 **/
@Configuration
public class QueryDSLConfig 

    @Autowired
    private EntityManager entityManager;

    @Bean
    public JPAQueryFactory getQueryFactory() 
        return new JPAQueryFactory(entityManager);
    

5:在调用的service里面注入JPAQueryFactory ,我这里直接注入到上面jpa测试调用的service里面


    @Autowired
    private JPAQueryFactory queryFactory;

6:简单的写两个查询调用,我在上面jap测试类中添加的调用

    @Test
    public void testQuerydslList()
        dealerRoleService.testQuerydslList();
    

    @Test
    public void testQuerydsl()
        dealerRoleService.testQuerydsl();
    

service中添加对应调用方法

    /**
     * 测试querydsl 根据名字查询返回
     */
    public List<DealerRole> testQuerydslList()
        QDealerRole qDealerRole = QDealerRole.dealerRole;
        List<DealerRole> list = queryFactory.selectFrom(qDealerRole).where(qDealerRole.roleName.eq("AAAA")).fetch();
        System.out.println(JSON.toJSONString(list));
        return list;
    

    /**
     * 测试querydsl返回对象
     */
    public DealerRole testQuerydsl()
        QDealerRole qDealerRole = QDealerRole.dealerRole;
        DealerRole role = queryFactory.selectFrom(qDealerRole).where(qDealerRole.roleId.eq("1111")).fetchOne();
        System.out.println(JSON.toJSONString(role));
        return role;
    

7:我这里执行的是根据名字调用queryDSL查询返回数据

 :8:总结
QueryDSL 操作数据表做复杂查询是非常棒的。具体细节到官网查看吧

queryDSL官方文档

搭建的测试代码下载地址: wb54979 / jpa-test · GitCode

下载下来的可能项目里面引入的包结构不对需要自行调整

以上是关于springboot整合JPA+MYSQL+queryDSL数据增删改查的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot整合Spring Data JPA多数据源

springboot整合JPA+MYSQL+queryDSL数据增删改查

springboot整合JPA+MYSQL+queryDSL数据增删改查

springboot整合JPA+MYSQL+queryDSL数据增删改查

SpringBoot整合JPA

springBoot整合JPA