从零学 spring cloud第3-7课:数据库基础之JPA复杂用法

    项目的DEMO代码:https://github.com/heyu52/-spring-cloud
    Spring Data JPA 的使用方式和基本查询,常用的增、删、改、查需求 Spring Data JPA 已经实现了。但对于复杂的数据库场景,动态生成方法不能满足,对此 Spring Data JPA 提供了其他的解决方法,下面我们就来看看还有哪些用法。此节课我们使用上节课的代码,来继续本节内容。

自定义SQL 查询
使用 Spring Data 大部分的 SQL 都可以根据方法名定义的方式来实现,但是由于某些原因必须使用自定义的 SQL 来查询,Spring Data 也可以完美支持。 在 SQL 的查询方法上面使用 @Query 注解,在注解内写 Hql 来查询内容。
我们在UserRepository中新增一个查询方法

 @Query("select u from User u")
 Page<User> findAllUser(Pageable pageable);

在UserController增加

    @RequestMapping("/findAllUser")
    public Page<User> findAllUser()
    {
        int page=0,size=10;
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        Pageable pageable = PageRequest.of(page, size, sort);
        return userRepository.findAllUser(pageable);
    }

运行项目,在浏览器输入:http://127.0.0.1:8080/findAllUser
在这里插入图片描述
上面的代码,实现了分页了,这里有几个问题是要注意的,记得页码是从0开始,并不是从1开始,如果你的表中的行数少,你又从1开始查数据,那么你可能是看不到数据的。@Query里面的脚本,并不是我们平时写的脚本,这种叫Hql ,注意,没有带*,如果写得不对,IDE工具会有提示的。为了解决这个恶心的脚本问题,还有一种写法,是可以完全和我们平时的脚本一致的,看下面的例子:

    @Query( value="select * from user u where u.name = ?1",nativeQuery = true)
    Page<User> findByUserName(String nickName, Pageable pageable);

在UserController增加

@RequestMapping("/findByUserName")
public Page<User> findByUserName(String name)
 {
        int page=0,size=10;
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        Pageable pageable = PageRequest.of(page, size, sort);
        return userRepository.findByUserName(name,pageable);
}

运行项目,在浏览器输入:http://127.0.0.1:8080/findByUserName?name=csdn
在这里插入图片描述
注意,及nativeQuery这里的值为true,nativeQuery表示使用原生SQL。
上面使用了参数,参数是按顺序来处理的,如果有多个参数也可以按照这个方式添加 1、2、3…。我们也可以使用名字来识别,使用@Param,写法如下

 @Query( value="select * from user u where u.name = :name",nativeQuery = true)
  Page<User> findByUserName2(@Param("name") String name, Pageable pageable);

在UserController增加

@RequestMapping("/findByUserName2")
public Page<User> findByUserName2(String name)
{
        int page=0,size=10;
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        Pageable pageable = PageRequest.of(page, size, sort);
        return userRepository.findByUserName2(name,pageable);
}

运行项目,在浏览器输入:http://127.0.0.1:8080/findByUserName2?name=csdn
在这里插入图片描述
前面说了查,接下来我们说更新:

    @Transactional(timeout = 10)
    @Modifying
    @Query("update User set Name = ?1 where id = ?2")
    int updateUserNameById(String  name, Long id);

在UserController增加

    @RequestMapping("/updateUserNameById")
    public int updateUserNameById(String name,Long id)
    {
        return userRepository.updateUserNameById(name,id);
    }

运行项目,在浏览器输入:http://127.0.0.1:8080/updateUserNameById?name=csdn2019&id=64
在这里插入图片描述
在这里插入图片描述
注意上面我们使用了 @Transactional(timeout = 10)及 @Modifying,其中事务还设置了超时时间。

使用已命名的查询
其实这种写法不推荐,这里只做简单说明。我们可以把脚本都写在model中
我们在User中增加代码

package com.csdn.demo.model;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@NamedQueries({
        @NamedQuery(name = "User.findBySex3", query = "select u from User u where u.sex = ?1"),
        @NamedQuery(name = "User.findByName3", query = "select u from User u where u.name = ?1") })
public class User {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
    @Column(nullable = false)
    private String name;
    @Column(nullable = false)
    private String sex;
    @Column(nullable = false)
    private int age;

    public User() {
    }

    public User(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(String age) {
        this.sex = age;
    }


    @Override
    public String toString() {
        return this.getId() + "," + this.getName() + "," + this.getSex() + "," + this.getAge();
    }
}

在UserRepository中增加方法

    List<User> findBySex3(String sex);
    List<User> findByName3(String name);

在UserController增加

@RequestMapping("/findBySex3")
    public  List<User> findBySex3(String sex)
    {
        return userRepository.findBySex3(sex);
    }

    @RequestMapping("/findByName3")
    public  List<User> findByName3(String name)
    {
        return userRepository.findByName3(name);
    }

运行项目,在浏览器输入:http://127.0.0.1:8080/findBySex3?sex=男
在这里插入图片描述
在浏览器输入:http://127.0.0.1:8080/findByName3?name=csdn
在这里插入图片描述
上述写法,其实是NamedQueries中定义了接口的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值