一、Spring Data的简介
1、什么是Spring Data
官网解释为:Spring Data的使命是为数据访问提供一个熟悉且一致的,基于Spring的编程模型,同时仍然保留底层数据存储的特殊特征。它使使用数据访问技术、关系和非关系数据库、map-reduce 框架和基于云的数据服务变得容易。
简单来说,Spring Data是一个用于简化数据库访问,并支持云服务的开源框架。
官网地址为:https://spring.io/projects/spring-data
数据库分为关系型数据库和非关系型数据库,在这里主要考虑对非关系型数据库进行访问
2、Spring Data的特征
-
强大的存储库和自定义对象映射抽象
-
从存储库方法名称派生的动态查询
-
提供基本属性的实现域基类
-
支持透明审核
-
可以集成自定义存储库代码
-
通过JavaConfig和自定义XML命名空间轻松集成Spring。
-
与Spring MVC控制器的高级集成
-
对跨存储持久性的实验性支持
3、常见的模块
-
Spring Data Commons - 支撑每个 Spring 数据模块的核心 Spring 概念。
-
Spring Data JDBC - Spring Data repository 支持 JDBC。
-
Spring Data JPA - Spring Data repository 支持 JPA,用于减少数据访问层的开发量
-
Spring Data MongoDB - 基于Spring的对象文档支持和MongoDB存储库,即是基于分布式数据层的NoSQL 数据库,在大数据层应用较多
-
Spring Data Redis - 轻松配置并从 Spring 应用程序访问 Redis。
-
Spring Data REST - 将 Spring 数据存储库导出为超媒体驱动的 REST 资源。
-
Spring Data Solr-高性能的基于Lucene的搜索功能
二、构建一个JPA项目
1、再IDED中创建项目,加入依赖
2、持久层会涉及数据源的问题,因此加入来连接池依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.18</version>
</dependency>
3、添加数据源配置
#连接池
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#UTC简称世界统一时间
spring.datasource.url=jdbc:mysql:///test?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
#ddl:数据定义语言,自动生成表结构
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
#jpa:是规范、是接口
spring.jpa.hibernate.ddl-auto=update
4、创建实体类
@Data
@Entity //JPA中提供的注解,用于声明当前类是一个实体类,实体类的意思就是有对应的表
@Table(name = "tbl_users") //用于声明当前实体类所对应的表名称
public class User implements Serializable {
@Id //用于表示对应主键id
@GeneratedValue(strategy = GenerationType.AUTO) //用于声明主键的生成策略
private Long id;
@Column(length = 32,unique = true,nullable = false) //如果没有配置,则可写可不写,当前类中所有属性都有对应的同名列
//length同于字符串类型,用于指定字符串长度,unique用于声明当前列上是否有唯一性约束,nullable用于声明列值是否允许为空
private String username;
@Column(length = 32,nullable = false)
private String password;
@Transient //用于声明当前属性没有对应的列
private String repassword;
@Temporal(TemporalType.DATE) //用于声明当前列和属性操作的数据格式模板
@Column(columnDefinition ="timestamp default current_timestamp")
//columnDefinition,用于指定当前列的定义,会导致和底层数据库耦合的问题
private Date hireDate;
@Column(columnDefinition = "boolean default 1")
private Boolean sex;
}
JPA提供的注解:
- @Entity //JPA中提供的注解,用于声明当前类是一个实体类,实体类的意思就是有对应的表
- @Table(name = "tbl_users") //用于声明当前实体类所对应的表名称
- @Id,用于表示对应主键id
- @GeneratedValue(strategy = GenerationType.AUTO) //用于声明主键的生成策略
- @Column(length = 32,unique = true,nullable = false) //如果没有配置,则可写可不写,当前类中所有属性都有对应的同名列
- @Temporal(TemporalType.DATE) //用于声明当前列和属性操作的数据格式模板
- @Column(columnDefinition ="timestamp default current_timestamp") //columnDefinition,用于指定当前列的定义,会导致和底层数据库耦合的问题
5、创建dao接口,继承JPA
package com.example.dao;
import com.example.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
//自动生成sql语句,且为我们提供接口实现
public interface UserRepostory extends JpaRepository<User,Long> {
}
6、创建业务层
6.1 创建业务层接口
package com.example.biz;
import com.example.entity.User;
public interface IUserServ {
User loadById(Long id);
}
6.2创建业务层实现类
package com.example.biz;
import com.example.dao.UserRepostory;
import com.example.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
//创建实现类
@Service
public class UserServImp implements IUserServ{
@Autowired
private UserRepostory userRepostory;
@Override
public User loadById(Long id) {
//判空处理
Assert.notNull(id,"参数不允许为空");
return userRepostory.getById(id);
}
}
6、定义控制器
package com.example.action;
import com.example.biz.IUserServ;
import com.example.domain.JsonResult;
import com.example.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private IUserServ userServ;
//做查询
@GetMapping("/{id}")
public JsonResult load(@PathVariable Long id){
User user=userServ.loadById(id);
if(user!=null)
return JsonResult.success("数据加载成功",user);
return JsonResult.failure("所加载的用户信息不存在");
}
}
7、此时一个项目就创建完成了,创建的项目结构如下图所示
8、在cmd中创建test数据库
9、运行项目,结果如下图所示
其中,针对红框中的信息进行解释
- Hibernate: create table hibernate_sequence (next_val bigint) engine=InnoDBHibernate: insert into hibernate_sequence values ( 1 ) #创建额外表,生成连续值
- Hibernate: create table tbl_users (id bigint not null, hire_date timestamp default current_timestamp, password varchar(32) not null, sex boolean default 1, username varchar(32) not null, primary key (id)) engine=InnoDB #生成自己创建的实体类的表,在关系型数据库中交换任意两行不影响数据库所表达的含义
- Hibernate: alter table tbl_users drop index UK_c190nfu2w5xwvexf9dv08grsq #删除索引
- Hibernate: alter table tbl_users add constraint UK_c190nfu2w5xwvexf9dv08grsq unique (username) #添加索引
10、此时查看结果
select * from tbl_users user0_ where user0_.id=?
11、查询id=1的值时候,会产生报错
报错信息为:Unable to find com.example.entity.User with id 1 (through reference chain: com.example.domain.JsonResult["data"]->com.example.entity.User$HibernateProxy$5IVGwGRl["username"])]
解决办法是:在实体类添加