Spring Boot学习日志(三)再谈Jpa

  • Spring Boot学习日志(一)Hello World
  • Spring Boot学习日志(二)JPA基本操作
  • Spring Boot学习日志(三)再谈Jpa
  • Spring Boot学习日志(四)使用Mybatis
  • Spring Boot学习日志(五)结合Swagger管理接口

背景

在上一篇JPA基本操作中讲述了SpringBoot Jpa基本的操作,但实际场景中会有很多复杂的场景。下面讲述条件查询,自定义查询以及多表查询。

导入依赖库和数据库配置

与上一篇JPA基本操作设置一致,可直接复制过来。

创建测试用到的表

CREATE TABLE `tb_group` (
  `groupid` int(11) NOT NULL DEFAULT '0',
  `groupname` varchar(20) CHARACTER SET utf8mb4 DEFAULT NULL,
  PRIMARY KEY (`groupid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `tb_user` (
  `id` int(11) NOT NULL,
  `username` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
  `group` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

创建实体类

@Entity
@Table(name = "tb_user")
@SuppressWarnings("serial")
public class UserEntity implements Serializable {
    @Id
    @Column(name = "id")
    private Integer id;

    @Column(name = "username")
    private String username;

    //映射多对一的关联关系
    @JoinColumn(name="group")//关联user表的字段
    @ManyToOne
    private Group group;


    public Integer getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Group getGroup() {
        return group;
    }

    public void setGroup(Group group) {
        this.group = group;
    }
}
@Entity
@Table(name = "tb_group")
public class Group implements Serializable {
    @Id
    @Column(name = "id")
    private String id;

    @Column(name = "groupname")
    private String groupname;

    @Column(name = "group")
    private String group;

    public String getGroup() {
        return group;
    }

    public void setGroup(String group) {
        this.group = group;
    }

    public String getId() {
        return id;
    }

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

    public String getGroupname() {
        return groupname;
    }

    public void setGroupname(String groupname) {
        this.groupname = groupname;
    }

}

UserEntity 为用户实体
Group为用户组所属的分组
用户
用户组
此上可以看出用户和用户组是多对一的关系,比如一个用户属于一个用户组,一个用户组有多个用户。

Jpa自定义简单查询

除了Jpa自动帮我们生成的sql之外,jpa还可以根据方法名自动生成sql,比如findXXX,readXXX,queryXXX,countXXX, getXXX,后面加上属性名称。
以查询为例:

   //根据用户名查找用户
    List<UserEntity> findUserEntityByUsername(String username);

    //根据用户id查找用户
    List<UserEntity> findUserEntityById(Integer id);

这些都是单一条件的查询,也可以复杂条件的查询,比如And、Or,如果希望使用And或者Or关键字,只需要在后面加上Or加属性名
比如:

    //根据用户名和用户id查找用户
    List<UserEntity> findUserEntityByIdAndUsername(Integer id,String username);

    //根据用户名或用户id查找用户
    List<UserEntity> findUserEntityByIdOrUsername(Integer id,String username);

常用的Like、OrderBy都可以使用:

    //排序查询
    List<UserEntity> findUserEntityByUsernameIsNotNullOrderById();

自定义sql查询:

   @Query(value = "select * from tb_user u left join tb_group g on g.group = u.group where u.username=?1", nativeQuery = true)
    @Modifying
    List<UserEntity> findUser(@Param("name")String name);

对应规则

关键字例子对应sql片段
find,queryfindByNameselect … where x.name = ?1
deletedeleteByNamedelete … where x.name = ?1
countcountByNameselect count(x.id) … where x.name=?1
AndfindByLastnameAndFirstname… where x.lastname = ?1 and x.firstname = ?2
OrfindByLastnameOrFirstname… where x.lastname = ?1 or x.firstname = ?2
Is,EqualsfindByFirstname,findByFirstnameIs,findByFirstnameEquals… where x.firstname = ?1
BetweenfindByStartDateBetween… where x.startDate between ?1 and ?2
LessThanfindByAgeLessThan… where x.age < ?1
LessThanEqualfindByAgeLessThanEqual… where x.age <= ?1
GreaterThanfindByAgeGreaterThan… where x.age > ?1
GreaterThanEqualfindByAgeGreaterThanEqual… where x.age >= ?1
AfterfindByStartDateAfter… where x.startDate > ?1
BeforefindByStartDateBefore… where x.startDate < ?1
IsNullfindByAgeIsNull… where x.age is null
IsNotNull,NotNullfindByAge(Is)NotNull… where x.age not null
LikefindByFirstnameLike… where x.firstname like ?1
NotLikefindByFirstnameNotLike… where x.firstname not like ?1
StartingWithfindByFirstnameStartingWith… where x.firstname like ?1 (parameter bound with appended %)
EndingWithfindByFirstnameEndingWith… where x.firstname like ?1 (parameter bound with prepended %)
ContainingfindByFirstnameContaining… where x.firstname like ?1 (parameter bound wrapped in %)
OrderByfindByAgeOrderByLastnameDesc… where x.age = ?1 order by x.lastname desc
NotfindByLastnameNot… where x.lastname <> ?1
InfindByAgeIn(Collection ages)… where x.age in ?1
NotInfindByAgeNotIn(Collection age)… where x.age not in ?1
TruefindByActiveTrue()… where x.active = true
FalsefindByActiveFalse()… where x.active = false
IgnoreCasefindByFirstnameIgnoreCase… where UPPER(x.firstame) = UPPER(?1)

Controller示例

@RequestMapping(value = "/user")
@RestController
public class UserController {
    @Autowired
    private UserJpa jpa;
    @RequestMapping(value = "/findUser")
    public List<UserEntity> findUser(String username){
        return jpa.findUser(username);
    }

    @RequestMapping(value = "/order")
    public List<UserEntity> findUserEntityByUsernameIsNotNullOrderById(){
        return jpa.findUserEntityByUsernameIsNotNullOrderById();
    }

    @RequestMapping(value = "/name")
    public List<UserEntity> findUserEntityByUsername(String username){
        return jpa.findUserEntityByUsername(username);
    }

    @RequestMapping(value = "/id")
    public List<UserEntity> findUserEntityById(Integer id){
        return jpa.findUserEntityById(id);
    }

    @RequestMapping(value = "/and")
    public List<UserEntity> findUserEntityByIdAndUsername(UserEntity userEntity){
        return jpa.findUserEntityByIdAndUsername(userEntity.getId(),userEntity.getUsername());
    }

    @RequestMapping(value = "/or")
    public List<UserEntity> findUserEntityByIdOrUsername(UserEntity userEntity){
        return jpa.findUserEntityByIdOrUsername(userEntity.getId(),userEntity.getUsername());
    }
}

执行结果举例

执行结果举例

总结

虽然可以通过spring boot jpa自动生成很多sql复杂语句,但是在使用中感觉还是很不好用,在很多时候需要夺表查询,写起来还是没有Mybatis那么“舒服”。下面一节就开始记录Mybatis相关内容。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值