架构小白到砖家-07-【数据存储问题】-JpaRepository解决单表固定查询

终于把用户请求问题处理完毕了,接下来可以解决web应用第二个问题,数据存储问题。咱们在应用框架发展历史中已经知道了,数据存储框架经过了纯JDBC,到EJB重量级框架,在到springAOP切面编程+spring的轻量级容器,然后到ORM框架hibernate,最后到JPA统一ORM标准。那么springJPA到底是怎么使用呢?
架构小白到砖家-07-【数据存储问题】-JpaRepository解决单表固定查询_第1张图片
根据面向对象编程思想,java操作数据库,应该使用对象操作的方式,而不是直接使用sql的方式。那么就需要解决如何将数据库的表转化成java对象的问题?目前spring的用法就是注解,那么JPA肯定也是用注解来关联java对象和表的映射关系。
首先我们还是先把JPA整合到springboot中,老规矩第一步告诉maven引入jpa的jar;第二步告诉springboot关于数据库的信息,在application.properties中配置jpa和datasource的信息;第三步创建javabean和数据库表映射关系。在ORM技术中,javabean不光能映射表关系,还能通过javabean创建和修改数据库表结构。

pom.xml文件中加入

		
		
			org.springframework.boot
			spring-boot-starter-data-jpa
			${spring.boot.version}
		

		
		
			com.alibaba
			druid
			1.0.20
		
		
		
			mysql
			mysql-connector-java
			5.1.13
		

application.properties文件中加入

#数据库相关配置
spring.jpa.show-sql=false
#spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.ddl-auto=update
#spring.jpa.hibernate.ddl-auto=create

# 数据库访问配置
# 主数据源,默认的
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=${app.datasource.url}
spring.datasource.username=${app.datasource.username}
spring.datasource.password=${app.datasource.password}

# 下面为连接池的补充设置,应用到上面所有数据源中
# 初始化大小,最小,最大
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=60
# 配置获取连接等待超时的时间
spring.datasource.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 
spring.datasource.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒 
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
# 打开PSCache,并且指定每个连接上PSCache的大小 
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=40
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 
spring.datasource.filters=stat,wall,log4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合并多个DruidDataSource的监控数据
spring.datasource.useGlobalDataSourceStat=true

创建一个User.java

@Entity()
@Table(name="P_USER")
public class User {
	@TableGenerator(
			name="ID_GENERATOR",//该主键生成策略的名称,与 @GeneratedValue 的 generator 属性值对应
			table="jpa_id_generators",// 指明根据哪个表生成主键
			pkColumnName="PK_NAME",// 使用 pkColumnName pkColumnValue valueColumnName 三个属性唯一的定位一个点
			pkColumnValue="p_user_id",//实体的主键名称
			valueColumnName="PK_VALUE",//实体的主键值
			allocationSize=1,//指定每次增加的数量
			initialValue=1)//初始化主键值
	@GeneratedValue(strategy=GenerationType.TABLE, generator="ID_GENERATOR")
	@Id
	private long id;
	//账号
	private String username;
	//密码
	private String password;
	//电子邮件 
	private String email;
	//可用性
	private boolean available = true;
	//真实姓名
	private String realName;
	//电话
	private String phone;
	//添加时间
	private Date createTime; 	
	//更新时间
	private Date updateTime; 

启动应用后,我们查看数据库,就会生成对应的P_USER这张表。
在这里插入图片描述

相关的配置文件信息大家看看注释,我们还是主要关注spring-jpa的注解,首先需要告诉spring我们的User.java是一个数据库表的实体@Entity();然后告诉jpa我们的User是对应数据库中的那张表@Table(name=“P_USER”);最后得给表设置一个唯一主键约束,我们采用了可以跨数据库的方案@TableGenerator和@GeneratedValue(),使用创建一张主键表来让JPA管理每张表的主键自增逻辑。详细配置大家也自己看看注释。

OK,咱们已经迈出了第一步,搞定了数据库和java对象的关联问题,那么下面我们就来存储数据吧。JPA的基本想法很厉害,就是让开发人员忘记数据库的存在。怎么实现这个想法呢?首先JPA提供了常用的操作数据库工具,叫做Repository,直接继承这个接口工具,无需实现接口,就能操作数据库了。听上去很神奇,只创建接口,不做实现,怎么可能?其实jpa还是有实现的,只是不需要大家自己去实现了,这里我截取了jpa的继承关系。
架构小白到砖家-07-【数据存储问题】-JpaRepository解决单表固定查询_第2张图片
Repository默认是没有功能的,通过面向对象思想的继承特性,扩展出了数据库表的基本增删改查操作的CrudRepository,又继续扩展了分页和排序能力PagingAndSortingRepository,最后统一成了JpaRepository工具。默认jpa提供了SimpleJpaRepository实现类。

那么我们就创建一个自己的UserRepository接口,来进行数据库操作吧。

public interface UserRepository extends JpaRepository 

为了验证方便,咱们就采用单元测试的方式来操作数据库。
架构小白到砖家-07-【数据存储问题】-JpaRepository解决单表固定查询_第3张图片
架构小白到砖家-07-【数据存储问题】-JpaRepository解决单表固定查询_第4张图片

我们可以看到没有写任何实现和一句SQL,咱们就可以通过操作对象的方式,往数据库里面插入了这么多数据。其他的修改和删除,这里就写下案例,就不运行结果了。jpa真的实现了让我们忘记数据库的存在,完全是操作java对象的方式在处理数据存储。
架构小白到砖家-07-【数据存储问题】-JpaRepository解决单表固定查询_第5张图片

但是这些简单的单表操作,怎么解决带查询条件的SQL查询呢?还能不写sql可以做到吗?JPA还真提供了一种方法,那就是通过在接口声明查询方法,方法的名称按特定的格式,就可以让jpa自动生成查询sql。让我们来看看这种方法吧。

UserRepository文件中加入
架构小白到砖家-07-【数据存储问题】-JpaRepository解决单表固定查询_第6张图片
单元测试中添加
架构小白到砖家-07-【数据存储问题】-JpaRepository解决单表固定查询_第7张图片
架构小白到砖家-07-【数据存储问题】-JpaRepository解决单表固定查询_第8张图片

厉害了,真的能查询出来,它是怎么做到的?底层原因我们就不深度探究了,来看看我们声明的方法,到底写了什么?

	User findByRealName(String realName);
	User findByUsernameOrEmail(String username,String email);

findByRealName,我们就写了一句英语,大概意思就是告诉jpa用realName这个条件,给我们找出一个User来。没错,就是用英文的大白话,让jpa查询数据。那还有哪些查询条件用法呢?我去spring官网获取了一张说明。
架构小白到砖家-07-【数据存储问题】-JpaRepository解决单表固定查询_第9张图片

好吧,我佩服。难道jpa真的就能无敌到能解决所有sql查询的情况吗?这个问题,咱们下一篇在探讨吧。

总结回顾,数据存储通过jpa框架来实现,它是面向对象的思想来操作数据库,想让开发人员忘记数据库的存在,并且还想让开发人员不写代码实现,就声明数据操作接口方法,用最简单的英文大白话告诉jpa去查询数据。总结下springjpa的常用注解。

@Table,映射表
@Entity,映射实体
@Id,主键
@GeneratedValue,主键生成策略
@Column,字段映射
@Transient,忽略映射
@Cacheable,是否使用二级缓存
@NamedQuery,提前准备JPQL
@Query,Repository方法指定查询JPQL
@Modifying,配合 @Query 可以完成 UPDATE 和 DELETE 操作
@Transactional,事物

你可能感兴趣的:(单应用框架)