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
虽然现在慢慢在流行前后端分离开发,但是据松哥所了解到的,还是有一些公司在做前后端不分的开发,而在前后端不分的开发中,我们就会需要后端页面模板(实际上,即使前后端分离,也会在一些场景下需要使用页面模板, ...
随机推荐
- 图形的认识(curve,surface,hypersurface)
平滑函数(smooth function): curve:曲线: 二维平面: surface:曲面: 三维空间: hypersurface:超曲面: 更高维度: 1. surface 是对平面的泛化, ...
- EasyUI-DataGrid多线动态实现选择性合并
jQuery EasyUI有一个非常易于使用的数据列表控件,这是DataGrid控制.某些背景json格式可以传递给在前景中显示的控制,很强大.只要有时需求须要这样即多行合并,如在列表中假设同样的部门 ...
- Android Widget 小工具(两) 使用configure
添加Widget在此之前需要做一些处理操作,可以使用 配置活动 在上一篇的实现基础上,加上配置活动(configure=activity).这时加入Widget时.会先打开一个Activity,进行配 ...
- Angular组件间的数据传输
解法一 概括和流程 定义了两个组件,data-transfer-two和data-transfer-two-child,由data-transfer-two引用data-transfer-two-ch ...
- multi-node和generic-pool两大利器
1.multi-node node只能单进程,单cpu工作,而multi-node则可以让node在多进程下共享内存的工作,实现机制是依靠child_process的sendmsg做到的.想要了解具体 ...
- jquery.cookie.js用法详解
创建一个会话cookie: $.cookie(‘cookieName’,'cookieValue’); 注:当没有指明cookie时间时,所创建的cookie有效期默认到用户浏览器关闭止,故被称为会话 ...
- zend-form笔记
Zend-Form组件包含以下几个对象: 1.Elements:包含了name和attributes, 2.Fieldsets:继承自elements,但允许包含其他fieldset和elements ...
- 利用WIX制作安装包(3)
原文 利用WIX制作安装包(3) 利用WIX安装服务非常简单.只需要短短几句话就可以.当我们创建好一个Windows服务之后.我们在项目中创建一个Service.wxs 文件来安装服务,并且编辑代码如 ...
- 专门用于消息回调窗口的窗口标识HWND_MESSAGE(创建一个非可视、没有z-order的窗口)
HWND_MESSAGE Message-Only Windows A message-only window enables you to send and receive messages. It ...
- 未在本地计算机上注册“microsoft.ACE.oledb.12.0” 解决方法
今日写一个浏览Excel文件的代码,忽然发现提示如下错误,表示很惊讶,因为我的另外一台电脑不会,但是这台就包这个异常. 解决方法: 去http://download.microsoft.com/dow ...