本文在个人技术博客【鸟不拉屎】同步发布,详情可猛戳 亦可扫描文章末尾二维码关注个人公众号【鸟不拉屎】

一、前言

今天早上看到一篇微信文章,说的是国内普遍用的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...

最新文章

  1. FineReport:任意时刻只允许在一个客户端登陆账号的插件
  2. Tcl
  3. Microsoft SQL Server Compact 4.0&amp;&amp;ADO.NET Entity Framework 4.1&amp;&amp;MVC3
  4. 日常UVA题目英语积累
  5. FZU 2212 Super Mobile Charger(超级充电宝)
  6. [STL]算法的泛化过程
  7. Camtasia Studio的安装步骤
  8. 虚反矩阵指令pinv之应用
  9. B - The Suspects -poj 1611
  10. struts开发&amp;lt;struts中的action详细配置. 二&amp;gt;
  11. 一道C语言安全编码题目
  12. html5/h5课件如何制作?
  13. 【转】ffmpeg常用基本命令
  14. ganglia使用nagios告警
  15. 使用centos 7安装conpot
  16. Java语言中的值传递与引用传递
  17. 子域名枚举工具Sublist3r
  18. javascript实现的网页打印
  19. sql server 2005 使用Log Explorer查看和恢复数据
  20. 解决Git在Linux 乱码问题

热门文章

  1. 如何将任意文件固定在 Win10 的开始屏幕中
  2. 在运行Hfile的MR如果任务client结束OOM
  3. WPF 悬浮键盘
  4. 2-18-搭建mysql集群实现高可用
  5. WPF Binding的代码实现
  6. JS 密码弱中强显示
  7. WPF Dispatcher的使用
  8. WPF 打印不显示的元素
  9. C++杂记:运行时类型识别(RTTI)与动态类型转换原理
  10. Qt PNG 背景透明