springboot集成spring data jpa使用原生sql实现增删改查(gradle)

JPA

Spring Data JPA 是 spring data 项目下的一个模块。提供了一套基于 JPA标准操作数据库的简化方案。底层默认的是依赖 Hibernate JPA 来实现的。

JPA的出现主要是为了简化持久层开发以及整合ORM技术,结束Hibernate、TopLink、JDO等ORM框架各自为营的局面。JPA是在吸收现有ORM框架的基础上发展而来,易于使用,伸缩性强。总的来说,JPA包括以下3方面的技术:

  • ORM映射元数据: 支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系
  • API: 操作实体对象来执行CRUD操作
  • 查询语言: 通过面向对象而非面向数据库的查询语言(JPQL)查询数据,避免程序的SQL语句紧密耦合

版本环境

java:jdk-14.0.1
springboot:v2.3.4.RELEASE
gradle:gradle-6.7-rc-4
IntelliJ IDEA:2020.1.2
spring-boot-starter-data-jpa:v2.3.4.RELEASE

数据源的配置

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mytest?useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=rootroot
spring.jpa.database=MySQL
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update

create:每次运行程序时,都会重新创建表,故而数据会丢失

create-drop:每次运行程序时会先创建表结构,然后待程序结束时清空表

upadte:每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新(推荐使用)

validate:运行程序会校验数据与数据库的字段类型是否相同,字段不同会报错

none: 禁用DDL处理

实体类

@NoArgsConstructor
@ApiModel(value = "用户实体", description = "用户实体类")
@Data
@Table(name = "user")
@Entity
public class User implements Serializable {

    private static final long serialVersionUID =  4728506793752030545L;

    @ApiModelProperty(value = "用户名")
    @Column(name = "name" )
    private String name;

    @JsonIgnore
    @ApiModelProperty(value = "用户密码")
    @Column(name = "pass" )
    private String pass;

    @ApiModelProperty(value = "用户年龄")
    @Column(name = "age" )
    private Integer age;

    @Column(name = "email" )
    @ApiModelProperty(value = "用户邮件")
    private String email;

    @ApiModelProperty(value = "用户id")
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id" )
    private Integer id ;
}

数据库

create table mytest.user
(
    id    int auto_increment
        primary key,
    name  varchar(30) not null,
    pass  varchar(30) not null,
    age   int         null,
    email varchar(30) null,
    constraint user_name_uindex
        unique (name)
);

Repository

@Repository
public interface UserRepository extends JpaRepository<User, Integer> {

    //增
    @Transactional(rollbackFor=Exception.class)
    @Modifying
    @Query(nativeQuery = true, value ="insert into user(name,pass,age,email) values(?1,?2,?3,?4)")
    int addUserByName(String name,String pass,int age,String email);
    
    //删
    @Transactional(rollbackFor=Exception.class)
    @Modifying
    @Query(nativeQuery = true, value ="delete from user where name =?1")
    int deleteUserByName(String name);
    
    //改
    @Transactional(rollbackFor=Exception.class)
    @Modifying
    @Query(nativeQuery = true, value ="update user set pass=?2 where name =?1")
    int updateUserPassByName(String name,String pass);

    //查单例
    @Query(nativeQuery = true, value ="select id,name,pass,age,email from user where name =?1")
    User getUserByName(String name);

    //查集合
    @Query(nativeQuery = true, value ="select id,name,pass,age,email from user where age <=?1")
    List<User> getUsersByAgeMax(int age);
}

测试调用

@RunWith(SpringRunner.class)
@SpringBootTest
public class GradleSpringBootApplicationTests {

    @Autowired
    UserRepository userRepository;

    @Test
    public void contextLoads() {
        System.out.println(userRepository.deleteUserByName("lzc"));
        System.out.println(userRepository.updateUserPassByName("lzc", "960929"));
        System.out.println(userRepository.getUserByName("lzc").toString());
        System.out.println(userRepository.addUserByName("lzc", "123", 123, "aksjlaklsdf"));
        userRepository.getUsersByAgeMax(30).forEach(System.out::println);
    }
}

遇到的坑

@Modifying和@Transactional

​ 增删改等操作数据库改变的操作必须加@Modifying和@Transactional(rollbackFor=Exception.class)这两个注解。

​ 当我们要通过自已写的更新、插入、删除SQL语句来实现更新、插入、删除操作时,至少需要用两个步骤:1)@Query来注入我们自定义的sql;2)使用@Modifying来标注是一个更新类的自定义语句。

​ @Modifying的主要作用是声明执行的SQL语句是更新(增删改)操作,@Transactional的主要作用是提供事务支持(提供例如隔离性等事务特性,JPA默认会依赖JDBC默认隔离级别)。

​ @Modifying只是声明了这个操作是一个修改操作,但却没有修改这个方法的事务等级,因此这个方法依然不能进行修改操作。只有声明了@Transactional,本质上是声明了@Transactional(readOnly=false),这样覆盖了默认的@Transactional配置便可以执行修改操作了。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值