今天发现一个奇怪的问题:
为什么我用save保存更新的数据后,数据库不更新,但是增加了一条空数据,我的前台也把数据用json传上去了,也成功了,但是数据库没有更新相应行的数据,而是新增了一条数据,我的后端用的接口PagingAndSortingRepository,数据库hibernate+sqlserver。
前端请求代码:
request(selectedRow,'post','<%=basePath%>userManager/save',function(data){console.log("data:"+data);
});
请求明细数据:
后端接口:
public interface UserManagerDAO extends PagingAndSortingRepository<User, Long>{
}
数据库显示:
我准备重现一下这个问题,下面的搭建过程和运行结果。
(Spring Data JPA入门案例,包含mysql、mssql增删改查、分页,主键自动生成)
1.环境准备
首先,确保你的Spring Boot项目已经配置了相关依赖。在pom.xml
中加入以下依赖:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>com.microsoft.sqlserver</groupId><artifactId>mssql-jdbc</artifactId><version>7.4.1.jre8</version></dependency>
</dependencies>
2.应用配置
在application.properties
中配置数据库连接:
# 应用服务 WEB 访问端口
server.port=8080# spring.datasource.url=jdbc:mysql://localhost:3306/award?useSSL=false&serverTimezone=UTC
# spring.datasource.username=root
# spring.datasource.password=123456
# spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
# spring.jpa.hibernate.ddl-auto=update
# spring.jpa.show-sql=truespring.datasource.url=jdbc:sqlserver://127.0.0.1:1433;databaseName=award
spring.datasource.username=sa
spring.datasource.password=A123456
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriverspring.main.lazy-initialization=true
3.实体类 (Entity)
假设我们有一个用户(User)实体,主键自增。
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;@Entity(name = "users")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String username;private String password;private String role;@Column(name = "addtime", insertable = false, updatable = false)private byte[] addtime; // Getters and Setters
}
4.Repository 接口
Spring Data JPA会根据接口方法名自动生成查询语句。
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;@Repository
public interface UserRepository extends PagingAndSortingRepository<User, Long> {List<User> findByUsername(String username);Page<User> findAll(Pageable pageable);
}
5.Service 层
服务层用于业务逻辑处理。
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;@Service
public class UserService {@Autowiredprivate UserRepository userRepository;public User save(User user) {return userRepository.save(user);}public void delete(User user) {userRepository.delete(user);}public User findById(Long id) {return userRepository.findById(id).orElse(null);}public List<User> findByName(String name) {return userRepository.findByUsername(name);}public Page<User> findAllPaged(int page, int size) {Pageable pageable = PageRequest.of(page, size);return userRepository.findAll(pageable);}public User update(Long id, User userDetails) {return userRepository.save(userDetails);}public boolean deleteById(Long id) {userRepository.deleteById(id);return true;}public Page<User> findAllPaged(Pageable pageable) {return userRepository.findAll(pageable);}
}
6.Controller 层
控制器负责接收HTTP请求并响应。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/api/users")
public class UserController {@Autowiredprivate UserService userService;// 创建(新增)@PostMappingpublic ResponseEntity<User> createUser(@RequestBody User user) {User savedUser = userService.save(user);return new ResponseEntity<>(savedUser, HttpStatus.CREATED);}// 查询(读取)@GetMapping("/{id}")public ResponseEntity<User> getUser(@PathVariable Long id) {User user = userService.findById(id);if (user != null) {return new ResponseEntity<>(user, HttpStatus.OK);} else {return new ResponseEntity<>(HttpStatus.NOT_FOUND);}}// 更新@PutMapping("/{id}")public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User userDetails) {User updatedUser = userService.update(id, userDetails);if (updatedUser != null) {return new ResponseEntity<>(updatedUser, HttpStatus.OK);} else {return new ResponseEntity<>(HttpStatus.NOT_FOUND);}}// 删除@DeleteMapping("/{id}")public ResponseEntity<Void> deleteUser(@PathVariable Long id) {boolean isDeleted = userService.deleteById(id);if (isDeleted) {return new ResponseEntity<>(HttpStatus.NO_CONTENT);} else {return new ResponseEntity<>(HttpStatus.NOT_FOUND);}}// 分页查询@GetMappingpublic ResponseEntity<Page<User>> getUsers(@RequestParam(defaultValue = "0") int page,@RequestParam(defaultValue = "10") int size) {Pageable pageable = PageRequest.of(page, size);Page<User> usersPage = userService.findAllPaged(pageable);return new ResponseEntity<>(usersPage, HttpStatus.OK);}
}
7.MySQL
建表语句
CREATE TABLE `users` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键',`username` VARCHAR(100) NOT NULL COMMENT '用户名',`password` VARCHAR(100) NOT NULL COMMENT '密码',`role` VARCHAR(100) NULL DEFAULT '管理员' COMMENT '角色',`addtime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '新增时间',PRIMARY KEY (`id`)
) COMMENT='用户表' ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
8.MSSQL
建表语句
CREATE TABLE [dbo].[users]([id] [int] IDENTITY(1,1) NOT NULL,[username] [varchar](50) NOT NULL,[password] [varchar](50) NOT NULL,[role] [varchar](50) NULL,[addtime] [timestamp] NULL,CONSTRAINT [PK_users] PRIMARY KEY CLUSTERED
([id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]GO
9.启动
成功启动
Tomcat started on port(s): 8080 (http)
Started JpademoApplication in 4.702 seconds (JVM running for 5.149)
10.新增用户
调用成功
11.查询用户
调用成功
12.修改用户
调用成功
所以,我没有重现这个问题,有可能是id传到后台的时候,丢失导致的,当所有可能都已经排除,那只剩这种可能了,网络数据丢包也会导致问题。