同福

JPA Hibernate关联数据表的操作技巧【20211103】

介绍

介绍

前面我们已经学会了使用JPA实现数据表的常规CRUD功能的开发技巧,还学会了使用JPA完成数据列表的展示的开发技巧,这时候如果我们做一个简单的单表小项目已经完全够用了。

不过,稍微复杂一点点的项目都不会只有单表处理情况,关联表是一定会用到的。那么如何使用JPA处理关联数据表呢?其实就福哥的了解,JPA是对单表的封装,多表还得自己码逻辑。

教程

数据表

福哥使用的是TFUMS项目的数据库tfums的用户表user_profile。

CREATE TABLE `user_profile` (
  `userID` int(11) NOT NULL,
  `nickName` varchar(45) DEFAULT NULL,
  `iconFileName` varchar(45) DEFAULT NULL,
  `gender` tinyint(4) DEFAULT NULL,
  `birth` date DEFAULT NULL,
  `topEdu` tinyint(4) DEFAULT NULL,
  `descript` text,
  PRIMARY KEY (`userID`)
)

实体JpaUserProfile

建立一个实体对象JpaUserProfile,使用JpaUser实体对象映射物理表user_profile。

@Data
@Entity
@Table(name = "user_profile")
@EntityListeners(AuditingEntityListener.class)
public class JpaUserProfile {

    @Id
    @Column(name = "userID")
    Long userId;

    @Column(name = "nickName")
    String nickName;

    @Column(name = "iconFileName")
    String iconFileName;

    @Column(name = "gender")
    Integer gender;

    @Column(name = "birth")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    Date birth;

    @Column(name = "topEdu")
    Integer topEdu;

    @Column(name = "descript")
    String descript;
}

数据层UserProfileRepository

建立UserProfile的数据层对象,还是一个空对象。

public interface UserProfileRepository extends JpaRepository<JpaUserProfile, Long> {

}

逻辑层UserService

因为UserProfile是User的附属表,福哥就不单独建立一套逻辑层对象了,还是使用UserService对象实现。

addProfile

福哥添加了addProfile方法,用来创建UserProfile数据。

JpaUserProfile addProfile(JpaUserProfile profile);

modProfile

福哥添加了modProfile方法,用来修改UserProfile数据。

JpaUserProfile modProfile(JpaUserProfile profile);

delete

删除UserProfile不需要单独的新方法,直接在delete里面一并处理就可以了。

void delete(Long id);

getProfile

福哥添加了getProfile方法,用来获取UserProfile数据。

JpaUserProfile getProfile(Long id);

逻辑层UserServiceImpl

通用的UserProfile的ServiceImpl对象也共享UserServiceImpl不再单独创建了。

addProfile

@Override
public JpaUserProfile addProfile(JpaUserProfile profile) {
    return profileRepository.save(profile);
}

modProfile

@Override
public JpaUserProfile modProfile(JpaUserProfile profile) {
    return profileRepository.save(profile);
}

delete

@Override
public void delete(Long id) {
    repository.deleteById(id);
    profileRepository.deleteById(id);
}

getProfile

@Override
public JpaUserProfile getProfile(Long id) {
    return profileRepository.findById(id).orElse(null);
}

测试

创建用户

这次创建用户的操作需要先调用add方法,然后把新的userId传递给UserProfile后,再调用addProfile方法。

user = new JpaUser();
user.setUserName("福哥教我学JPA关联表");
user.setPasswd(TFMD5.encode("abcdef"));
user.setUserFlag(7);
user.setUserState(1);

user = userService.add(user);

userProfile = new JpaUserProfile();
userProfile.setUserId(user.getUserId());
userProfile.setNickName("福哥");
userProfile.setIconFileName("2021/1104/10/abcd.jpg");
userProfile.setGender(1);
userProfile.setBirth(Calendar.getInstance().getTime());
userProfile.setTopEdu(1);
userProfile.setDescript("福哥说了,跟他学Java准没错!");

userProfile = userService.addProfile(userProfile);

map.put("id", user.getUserId());
map.put("name", user.getUserName());
map.put("nick", userProfile.getNickName());
map.put("birth", userProfile.getBirth().toString());
map.put("descript", userProfile.getDescript());

home/topic/2021/1104/11/7c6962d926755364f576aac8e690e75c.pnghome/topic/2021/1104/11/d3e190379e4a71215803a83356cad52b.png

修改用户

修改用户的时候也是需要先调用mod方法,再调用modProfile方法。

user = userService.get(Long.valueOf(31));
user.setUserEmail("tfjpa@tongfu.net");
user = userService.mod(user);

userProfile = userService.getProfile(user.getUserId());
userProfile.setBirth(Calendar.getInstance().getTime());
userProfile = userService.modProfile(userProfile);

map.put("id", user.getUserId());
map.put("name", user.getUserName());
map.put("email", user.getUserEmail());
map.put("birth", userProfile.getBirth());

home/topic/2021/1104/11/94b1d6426f1d363ebc899861ec4e2c47.pnghome/topic/2021/1104/11/80364516b6c10201c464f1148a6c471f.png

删除用户

删除用户方法还是delete没有变化。

userService.delete(Long.valueOf(31));

home/topic/2021/1104/11/0867a63614fce49a687bf724f0a707af.png

home/topic/2021/1104/11/cc53c131ea70e55c616abd7d0cc6d07a.png

获取用户

获取用户需要通过get方法和getProfile方法。

user = userService.get(Long.valueOf(31));
userProfile = userService.getProfile(user.getUserId());

map.put("id", user.getUserId());
map.put("name", user.getUserName());
map.put("birth", userProfile.getBirth());

home/topic/2021/1104/11/0962d60dbbe5f29f9085c0997e4e18b6.png

总结

今天福哥带着童鞋们把JPA实现关联数据表的处理技巧学习了一遍,可以看出这个关联数据表的处理和单表的处理基本上是一样的,模型的附属表越多,处理的方法也就越多。

不知道JPA可不可以在一个实体对象里面定义多张物理数据表的字段的映射关系,如果可以这样的话,那么关联处理就要方便多了。

福哥会进一步去研究JPA的高级使用技巧,并且会在研究出成果之后把它分享给大家,敬请期待~~