springboot和jpa使用的数据源怎么用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot和jpa使用的数据源怎么用相关的知识,希望对你有一定的参考价值。
参考技术A spring boot jpa 相当于是Jdbc的代理,从理念是来说是使用hibernate规范对数据访问层的规划,jpa的原理就是封装了各种jdbc的实现,并提供了你方便扩展的接口。
所以spring boot jpa 没有存在“使用JDBC”这一说,但是如果你仅仅是想表达JPA如何使用sql?你可以关注在Repository中的方法中,利用@Query("……你的sql")来执行sql。
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&autoReconnect=true&connectTimeout=3000&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 操作数据表做复杂查询是非常棒的。具体细节到官网查看吧
搭建的测试代码下载地址: wb54979 / jpa-test · GitCode
下载下来的可能项目里面引入的包结构不对需要自行调整
以上是关于springboot和jpa使用的数据源怎么用的主要内容,如果未能解决你的问题,请参考以下文章
用SpringBoot+MySql+JPA实现对数据库的增删改查和分页