Spring Boot2(九):整合Jpa的基本使用
本文在个人技术博客【鸟不拉屎】同步发布,详情可猛戳 亦可扫描文章末尾二维码关注个人公众号【鸟不拉屎】
一、前言
今天早上看到一篇微信文章,说的是国内普遍用的Mybatis,而国外确普遍用的是Jpa。我之前也看了jpa,发现入门相当容易。jpa对于简单的CRUD支持非常好,开发效率也会比Mybatis高出不少,因为JpaRepository
会根据你定制的实体类,继承了JpaRepository
会有一套完整的封装好了的基本条件方法。减少了很多开发量。你只需要写SQL就行了。可能我才刚入门Jpa,对一些认识还是很浅显。我觉得Jpa对于多表查询,开发起来有点吃力。。
这是我开始玩Jpa的最初的感受,但是Jpa却受到了极大的支持和赞扬,在国外Jpa远比Mybatis流行得多得多。国内却还是在流程用Mybatis,估计也是收到很多培训机构或者大V的带领下,很多国内优秀的开源项目也是用的Mybatis,因为已经用得非常熟练了。
话不多说,先看看SpringBoot如何整合使用Jpa吧!
这里具体讲一讲Jpa的搭建,几种常见的场景的使用:增删改查、多表查询,非主键查询这几种情况的一个学习总结。
二、代码部署
1、添加Maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
其实Jpa关键用到的是最下面两块
2、配置application
application.yml
server:
port: 8081
#指定配置文件为test
spring:
profiles:
active: test
application-test.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jpatest?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
username: root
password: root
jpa:
# 数据库类型
database: mysql
#打印SQL
show-sql: true
hibernate:
ddl-auto: update #第一次启动创建表,之后修改为update
application-test.yml
需要了解的是jpa分支,如果需要通过jpa在数据库中建表,就将spring.jpa.hibernate.ddl-auto
改为create
,建完表之后,建议改为update,否则你再次重启,表会回炉重造,数据相应的会丢失。可得注意啦。
3、创建实体类
用户表sys_user的实体类
@Data
@Entity
@Table(name = "sys_user")
public class SysUser implements Serializable {
@Id
private String userId;
@Column(nullable = false)
private String userName;
@Column(nullable = false)
private String passWord;
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false, unique = true)
private String salt;
@Column(nullable = false)
private Date regTime;
}
用户角色对照表sys_user_role的实体类
@Entity
@Data
@Table(name = "sys_user_role")
public class SysUserRole implements Serializable {
@Id
@GeneratedValue
private int id;
// 用户ID
private String userId;
// 角色ID
private int roleId;
}
4、Dao层
用户表SysUserDao
public interface SysUserDao extends JpaRepository<SysUser, Integer> {
}
用户角色对照表SysUserRoleDao
public interface SysUserRoleDao extends JpaRepository<SysUserRole, Integer> {
}
5、Controller层
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private SysUserDao sysUserDao;
@Autowired
private SysUserRoleDao sysUserRoleDao;
/**
* 用户表sys_user,用户角色对照表sys_user_role。数据初始化
*/
//发送get请求进行数据添加:127.0.0.1:8081/user/init
@RequestMapping(value = "/init", method = RequestMethod.GET)
public String initData() {
for (int i = 1; i < 6; i++) {
// 根据时间戳生成userId
String userId = String.valueOf(System.currentTimeMillis());
// new出用户表和用户角色表的对象
SysUser sysUser = new SysUser();
SysUserRole sysUserRole = new SysUserRole();
// 新增用户表
sysUser.setUserId(userId);
sysUser.setUserName("username_num" + i);
sysUser.setPassWord("password_num" + i);
sysUser.setEmail("email_num" + i + "@qq.com");
sysUser.setSalt(i + "");
sysUser.setRegTime(new Date());
sysUserDao.save(sysUser);
// 暂时规定小于3的,角色为1,新建用户角色表
if (i < 3) {
sysUserRole.setId(i);
sysUserRole.setUserId(userId);
sysUserRole.setRoleId(1);
sysUserRoleDao.save(sysUserRole);
} else {
// 大于3的,角色为2
sysUserRole.setId(i);
sysUserRole.setUserId(userId);
sysUserRole.setRoleId(2);
sysUserRoleDao.save(sysUserRole);
}
}
return "init data success";
}
/**
* 删除
*/
// 发送get请求:127.0.0.1:8081/user/delete/1562486017644
@RequestMapping(value = "/delete/{userId}", method = RequestMethod.GET)
public String deleteUser(@PathVariable("userId") String userId) {
sysUserDao.deleteByUserId(userId);
return "delete success";
}
/**
* 查询全部
* @return
*/
// 发送get请求:127.0.0.1:8081/user/list
@RequestMapping(value = "/list", method = RequestMethod.GET)
public List<SysUser> getUsers() {
return sysUserDao.findAll();
}
/**
* 根据id查询
*/
// 发送get请求:127.0.0.1:8081/user/info/1562486017644
@RequestMapping(value = "/info/{userId}", method = RequestMethod.GET)
public Optional<SysUser> getUserById(@PathVariable("userId") String userId) {
return sysUserDao.findByUserId(userId);
}
/**
* 更新
*/
// 发送post请求:127.0.0.1:8081/user/update
// 发送报文体如下
/*
{
"userId":"1562486017551",
"passWord": "231231231212312",
"userName":"Tom",
"email": "1111111@qq.com"
}
*/
@RequestMapping(value = "/update", method = RequestMethod.POST)
public String updateAccount(@RequestBody HashMap<String, String> map) {
// 根据Id更新用户信息
sysUserDao.updateOne(
map.get("email"),
map.get("userName"),
map.get("passWord"),
map.get("userId"));
return "update success";
}
/**
* 关联查询用户的角色信息
*/
// 发送post请求:127.0.0.1:8081/user/getUserRole
// 发送报文体如下
/*
{
"userId":"1562486017629"
}
*/
@RequestMapping(value = "/getUserRole", method = RequestMethod.POST)
public List<SysUserInfo> getUserRole(@RequestBody HashMap<String, String> map) {
return sysUserDao.findUserRole(map.get("userId"));
}
/**
* 根据非主键username模糊查询
*/
// 发送post请求:127.0.0.1:8081/user/getUserByUserName
// 发送报文体如下
/*
{
"userName":"username"
}
*/
@RequestMapping(value = "/getUserByUserName", method = RequestMethod.POST)
public List<SysUser> getUserByUserName(@RequestBody HashMap<String, String> map) {
return sysUserDao.findUserName(map.get("userName"));
}
}
代码有点多,只是我写的例子多了点
6、补充Dao
public interface SysUserDao extends JpaRepository<SysUser, Integer> {
/**
* 根据userId删除数据
*/
@Transactional
@Query(value = "delete u from sys_user u where u.user_id = ?1", nativeQuery = true)
@Modifying
void deleteByUserId(String userId);
/**
* 根据UserId查询
* @param userId
* @return
*/
@Query(value = "select u.* from sys_user u where u.user_id = ?1", nativeQuery = true)
Optional<SysUser> findByUserId(String userId);
/**
* 根据Id更新用户相关信息
* nativeQuery = true 添加该属性等于true则是原生SQL语句查询,不添加则是HQL语句
*/
@Transactional
@Query(value = "update sys_user set email=?1, user_name=?2, pass_word=?3 where user_id=?4", nativeQuery = true)
@Modifying
public void updateOne(String email, String userName, String passWord, String userId);
/**
* 查询用户角色
* @param userId
* @return
*/
@Query(value = "SELECT " +
"t.user_id AS userId, " +
"t.user_name AS userName, " +
"t.email AS email, " +
"t.pass_word AS passWord, " +
"r.role_id AS roleId " +
"FROM sys_user t LEFT JOIN sys_user_role r " +
"ON r.user_id = t.user_id " +
"WHERE t.user_id = ?1", nativeQuery = true)
List<SysUserInfo> findUserRole(String userId);
/**
* 根据username查询用户信息
* @return
*/
@Query(value = "select u.* from sys_user u where u.user_name like CONCAT('%',?1,'%')", nativeQuery = true)
List<SysUser> findUserName(String nickName);
}
这里需要注意的在findUserRole
方法,是联表查询,其结果集在SysUserInfo
中
public interface SysUserInfo {
String getUserId();
String getUserName();
String getEmail();
String getPassWord();
int getRoleId();
}
三、测试
启动项目之前,将spring.jpa.hibernate.ddl-auto
改为create
。启动完成之后改为update或者none。
会生成两张表sys_user用户表,sys_user_role用户角色对应表
然后通过controller里的一个接口init,发送get请求
生成一些数据。
之后可以进行具体的数据库接口操作啦。
四、总结
在学习过程中,敲代码也遇到不少坑,感觉Jpa还行,确实比Mybatis快了不少,不需要建立mapper.xml文件。
可是在项目中不可能都是一些简单的查询SQL呀,肯定会遇到许多复杂的SQL,如果用Jpa的话,感觉并不是那么好用。当然我还没有深入去学习它。肯定有许多我不太明白的技术。肯定可以解决不复杂SQL。
我在网上也搜索了,有些人会建议将Jpa和Mybatis结合使用。我也感觉这点子不错。后续会继续研究
源码
github源码地址:Spring Boot2(九):整合Jpa的基本使用
原文地址:https://niaobulashi.com/archives/springboot-jpa.html
To be continued...
Spring Boot2(九):整合Jpa的基本使用的更多相关文章
- 玩转spring mvc(四)---在spring MVC中整合JPA
关于在Spring MVC中整合JPA是在我的上一篇关于spring mvc基本配置基础上进行的,所以大家先参考一下我的上一篇文章:http://blog.csdn.net/u012116457/ar ...
- Spring Boot2.0 整合 Kafka
Kafka 概述 Apache Kafka 是一个分布式流处理平台,用于构建实时的数据管道和流式的应用.它可以让你发布和订阅流式的记录,可以储存流式的记录,并且有较好的容错性,可以在流式记录产生时就进 ...
- Spring Boot2.X整合消息中间件RabbitMQ原理简浅探析
目录 1.简单概述RabbitMQ重要作用 2.简单概述RabbitMQ重要概念 3.Spring Boot整合RabbitMQ 前言 RabbitMQ是一个消息队列,主要是用来实现应用程序的异步和解 ...
- 手把手教你Spring Boot2.x整合Elasticsearch(ES)
文末会附上完整的代码包供大家下载参考,码字不易,如果对你有帮助请给个点赞和关注,谢谢! 如果只是想看java对于Elasticsearch的操作可以直接看第四大点 一.docker部署Elastics ...
- 基于Redis的消息队列使用:spring boot2.0整合redis
一 . 引入依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="ht ...
- 手把手教你Spring Boot2.x整合kafka
首先得自己搭建一个kafka,搭建教程请自行百度,本人是使用docker搭建了一个单机版的zookeeper+kafka作为演示,文末会有完整代码包提供给大家下载参考 废话不多说,教程开始 一.老规矩 ...
- Spring Boot2 系列教程(二十五)Spring Boot 整合 Jpa 多数据源
本文是 Spring Boot 整合数据持久化方案的最后一篇,主要和大伙来聊聊 Spring Boot 整合 Jpa 多数据源问题.在 Spring Boot 整合JbdcTemplate 多数据源. ...
- Spring Boot2 系列教程 (九) | SpringBoot 整合 Mybatis
前言 如题,今天介绍 SpringBoot 与 Mybatis 的整合以及 Mybatis 的使用,本文通过注解的形式实现. 什么是 Mybatis MyBatis 是支持定制化 SQL.存储过程以及 ...
- Spring Boot2 系列教程(九)Spring Boot 整合 Thymeleaf
虽然现在慢慢在流行前后端分离开发,但是据松哥所了解到的,还是有一些公司在做前后端不分的开发,而在前后端不分的开发中,我们就会需要后端页面模板(实际上,即使前后端分离,也会在一些场景下需要使用页面模板, ...
随机推荐
- JQuery在一个简单的表单验证的例子
html代码例如以下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/ ...
- 期刊(Journal)、会议(Conference)及其影响因子(Impact Factor)
CNCC:China National Computer Congress,中国计算机大会 0. 会议 计算机视觉(CV)三大顶级会议: ICCV: IEEE International Confer ...
- mac系统下虚拟机parallels安装ubuntu 14.04
mac系统很棒,mac下的开发环境也很棒,但有时你还得需要ubuntu开发环境,比如进行嵌入式Linux交叉编译,使用Linaro toolchain… 其实mac系统下使用parallels虚拟机安 ...
- JDK10下安装Eclipse photon 提示Java for Windows Missing
这两天把服务器清理了一下,操作系统也重新装了,没办法啊,就是喜欢倒腾...在重新安装软件的时候,我又到各个官网去看了软件的最新版本,其中就去了JDK和Eclipse的官网溜达了一圈. 很久没有更新过自 ...
- docker ubuntu 不选时区
在用ubuntu:18.04基本镜像进行构建的时候.出现啦选择时区的地方,然后会卡住. FROM ubuntu:18.04 #env 环境变量 ENV AUTHOR="xianyunyehe ...
- WPF中的图像处理简介
原文:WPF中的图像处理简介 和Winform中的GDI+相比,WPF提供了一组新的API用于显示和编辑图像.新API特点如下: 适用于新的或专用图像格式的扩展性模型. 对包括位图 (BMP).联合图 ...
- ASP.NET MVC 学习笔记1 Talk about controller & route
For the sake of learning programming better, I'd like to increase the frequency of using English. So ...
- asp.net文件流下载的代码摘要
try { var workbook = new XLWorkbook(); if (Workbook != null) { workbook = Workbook; } if (this.Expor ...
- Cindy components(配色很不错)
https://sourceforge.net/projects/tcycomponents/
- asp.net core2.0中网站发布的时候,视图文件不被打包成dll
项目csproj文件里面加 <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <Target ...