前言:之前一直都是直接使用JPA没有想过它内部封装的sql语言,然后看到了一篇文章 JPA踩坑系列之save方法,才发现这个框架并不好用。
验证save()的使用pom文件
4.0.0 org.springframework.boot spring-boot-starter-parent2.6.1 com.example demo0.0.1-SNAPSHOT demo demo 11 org.springframework.boot spring-boot-starter-data-jpamysql mysql-connector-javaruntime org.projectlombok lomboktrue org.springframework.boot spring-boot-starter-testtest org.springframework.boot spring-boot-maven-pluginorg.projectlombok lombok
yml文件
spring: datasource: url: jdbc:mysql://127.0.0.1:3306/springboot_db?useUnicode=true&characterEncoding=UTF-8&useSSL=false driverClassName: com.mysql.cj.jdbc.Driver username: root password: root1234 jpa: show-sql: true database-platform: org.hibernate.dialect.MySQL5InnoDBDialect hibernate: use-new-id-generator-mappings: false properties: hibernate.format_sql: true
show-sql: true 可以展示调用过程中的sql语句。
create table user ( user_id varchar(20) null, enabled tinyint(1) not null, id int auto_increment primary key, role_code varchar(50) not null, name varchar(10) null, constraint dealer_id_role_code_idx unique (user_id, role_code) ) charset = utf8;
项目结构
user文件
package com.example.demo.entity; import lombok.*; import javax.persistence.*; import java.io.Serializable; @Builder @NoArgsConstructor @AllArgsConstructor @Entity @Getter @Setter @Table(name = "user") public class User implements Serializable { @Id @GeneratedValue @Column(name = "id") private int id; @Column(name = "user_id", length = 50, nullable = false) private String userId; @Column(name = "enabled", length = 1, nullable = false) private Boolean enabled; @Column(name = "role_code", length = 50, nullable = false) private String roleCode; private String name; }
UserRepository文件
package com.example.demo.repository; import com.example.demo.entity.User; import org.springframework.context.annotation.ComponentScan; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository @ComponentScan public interface UserRepository extends JpaRepository{ User findByUserIdAndRoleCode(String userID, String roleCode); }
UserService文件
package com.example.demo.service; import com.example.demo.entity.User; import com.example.demo.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class UserService { @Autowired private UserRepository userRepository; public int addUser(String userId) { User user = User.builder() .id(45747) .userId(userId) .enabled(false) .roleCode("Sup") .name("haha").build(); return userRepository.save(user).getId(); } }
调用的mysql语句
Hibernate: select user0_.id as id1_0_0_, user0_.enabled as enabled2_0_0_, user0_.name as name3_0_0_, user0_.role_code as role_cod4_0_0_, user0_.user_id as user_id5_0_0_ from user user0_ where user0_.id=? Hibernate: insert into user (enabled, name, role_code, user_id) values (?, ?, ?, ?)
因为创建user对象的时候涉及到了主键id,所以在save之前会进行一次select *** 作,以主键id为依据。
UserService文件
public int addUser(String userId) { User user = User.builder() .userId(userId) .enabled(false) .roleCode("Sup") .name("haha").build(); return userRepository.save(user).getId(); }
调用的mysql语句
Hibernate: insert into user (enabled, name, role_code, user_id) values (?, ?, ?, ?)
当没有涉及主键的 *** 作后,会直接调用insert *** 作。
UserService文件
public int addUser(String userId) { User user = userRepository.findByUserIdAndRoleCode(userId,"Sup"); user.setEnabled(true); return userRepository.save(user).getId(); }
调用的mysql语句
Hibernate: select user0_.id as id1_0_, user0_.enabled as enabled2_0_, user0_.name as name3_0_, user0_.role_code as role_cod4_0_, user0_.user_id as user_id5_0_ from user user0_ where user0_.user_id=? and user0_.role_code=? Hibernate: select user0_.id as id1_0_0_, user0_.enabled as enabled2_0_0_, user0_.name as name3_0_0_, user0_.role_code as role_cod4_0_0_, user0_.user_id as user_id5_0_0_ from user user0_ where user0_.id=? Hibernate: update user set enabled=?, name=?, role_code=?, user_id=? where id=?
会按照查询条件先查一遍,然后再根据主键进行查找,发现值发生变化后,再进行update *** 作,没有变化不再进行 *** 作,如下所示。
UserService文件
public int addUser(String userId) { User user = userRepository.findByUserIdAndRoleCode(userId,"Sup"); user.setEnabled(false); return userRepository.save(user).getId(); }
调用的mysql语句
Hibernate: select user0_.id as id1_0_, user0_.enabled as enabled2_0_, user0_.name as name3_0_, user0_.role_code as role_cod4_0_, user0_.user_id as user_id5_0_ from user user0_ where user0_.user_id=? and user0_.role_code=? Hibernate: select user0_.id as id1_0_0_, user0_.enabled as enabled2_0_0_, user0_.name as name3_0_0_, user0_.role_code as role_cod4_0_0_, user0_.user_id as user_id5_0_0_ from user user0_ where user0_.id=?
当给方法加上事务的注解(@Transactional)后,
UserService文件
@Transactional public int addUser(String userId) { User user = userRepository.findByUserIdAndRoleCode(userId,"Sup"); user.setEnabled(false); return userRepository.save(user).getId(); }
调用的mysql如下:
Hibernate: select user0_.id as id1_0_, user0_.enabled as enabled2_0_, user0_.name as name3_0_, user0_.role_code as role_cod4_0_, user0_.user_id as user_id5_0_ from user user0_ where user0_.user_id=? and user0_.role_code=?
但是当加上事物注解@Transactional,save前没有查询的话还是会先调用select语句
UserService文件
@Transactional public int addUser(String userId) { User user = User.builder() .id(123) .userId(userId) .enabled(false) .roleCode("Sup") .name("haha").build(); return userRepository.save(user).getId(); }
调用的mysql如下:
Hibernate: select user0_.id as id1_0_0_, user0_.enabled as enabled2_0_0_, user0_.name as name3_0_0_, user0_.role_code as role_cod4_0_0_, user0_.user_id as user_id5_0_0_ from user user0_ where user0_.id=? Hibernate: insert into user (enabled, name, role_code, user_id) values (?, ?, ?, ?)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)