zoukankan      html  css  js  c++  java
  • 使用SpringBoot-JPA进行自定义的保存及批量保存

    更多精彩博文,欢迎访问我的个人博客


    说明

    SpringBoot版本:2.1.4.RELEASE

    java版本:1.8

    文中所说JPA皆指spring-boot-starter-data-jpa

    使用JPA保存一个Student对象

    在JPA中保存一个对象,仅需要该对象,一个仓储即可。
    StudentDO实体类:

    @Getter
    @Setter
    @Entity
    @Table(name = "t_student")
    public class StudentDO {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column
        private Long id;
        @Column
        private String seq;
        @Column
        private String name;
        @Column
        private int sex;
    }
    

    JPA仓储:

    @Repository
    public interface StudentRepo extends JpaRepository<StudentDO, Long> {
    }
    

    一般的,我们只需要调用StudentRepo.save()方法即可完成对实体对象的保存操作。

        @Test
        public void testSave() {
            StudentDO student = new StudentDO();
            student.setName("张三");
            student.setSex(1);
            student.setSeq("123456");
            studentRepo.save(student);
            Assert.assertNotNull(student.getId());
        }
    

    在插入过程中使用mysql函数

    如果我们希望student的seq值由系统自动生成,且生成规则为“yyMMdd + 8位自增序列”(例如19060310000000)又该如何实现呢?

    首先想到的是该如何生成这一串序列,mysql不像oracle自身支持sequence,因此在这里可以借用函数以及额外的sequence表来实现这一操作,网上有很多实现方式,这里就不再赘述。

    现在已经有了函数getseq('student_seq')可以获取到该序列,该如何将其应用到保存对象的方法中?显然的一个问题是,像上面那样再直接调用save方法已经行不通了,应该得需要自定义插入的sql实现。

    一个容易想到的办法是,在StudentDO类上使用注解@SQLInsert来定义insert的实现,它写起来应该会像这个样子:

    @SQLInsert(sql = "INSERT INTO t_student(seq, name, sex) VALUES (getseq('student_seq'), ?, ?")
    

    这条sql语句本身并没有什么问题,再次调用save()方法也确实能够执行。但是很可惜,它确会抛出一个sql异常:

    java.sql.SQLException: Parameter index out of range (3 > number of parameters, which is 2).
    

    显然是程序认为有多少个参数,就得有多少个“?”与之匹配,目前我并没有找到解决这个问题的方案,所以这种方法宣告失败。

    既然@SQLInsert行不通,或许可以考虑使用@Query注解来自定义一个实现。我们可以在StudentRepo中定义这样一个方法:

        @Transactional
        @Modifying
        @Query(value = "INSERT INTO t_student(seq, name, sex) VALUES (getseq('student_seq'), :#{#student.name}, :#{#student.sex})", nativeQuery = true)
        int insert(@Param("student") StudentDO student);
    

    试着运行一下,结果很成功,对象被正常的存储到数据库中,并且seq的取值也正常。看上去我们的问题已经得到了解决,但事实真的如此么?

    自定义的批量存储

    上面的例子中,我们成功通过JPA调用了mysql函数将对象存储到数据库中。但上面的例子只提供了单个保存的方法,如果我们想批量保存呢?@Query里面的sql能够进行改造么?我并没有找到@Query中使用List

  • 相关阅读:
    Mysql中判断一个点是否落在多边形内
    Linux进阶之环境变量文件/etc/profile、/etc/bashrc、/etc/environment
    gitlab打开group_member页面500错误
    jenkins连接k8s集群
    svn备份迁移
    npm管理nodejs版本
    linux远程执行shell脚本或者python脚本无法获取远程主机的环境变量
    ansible-playbook对服务器安装阿里云日志服务agent--ilogtail
    linux安装Arachni进行web网站扫描
    nginx使用免费ssl证书
  • 原文地址:https://www.cnblogs.com/jptangchina/p/11023041.html
Copyright © 2011-2022 走看看