I have a spring boot application in which i edit a employee database with CRUD operations received from Postman. My problem is that in this case i need to access the database with multiple threads, or with batches. I decided to do a batch update.
This is my DAO in which i make the crud operations with sql connections.
@Repository
public class EmployeeDaoImpl implements EmployeeDao {
public EmployeeDaoImpl(NamedParameterJdbcTemplate template) {
this.template = template;
}
private static int maxCreateBatch = 50;
private static int maxUpdateBatch = 50;
private static int maxDeleteBatch = 50;
NamedParameterJdbcTemplate template;
@Override
public List<Employee> findAll() {
return template.query("select * from employee", new EmployeeRowMapper());
}
@Override
public void insertEmployee(Employee emp) {
try {
Connection conn = DriverManager.getConnection("jdbc:postgresql://10.10.45.147:5432/db", "db",
"pass");
PreparedStatement ps = conn.prepareStatement("insert into employee(employeeId, employeeName ) values(?,?)");
int i = 1, j = 0;
ps.setString(i++, emp.getEmployeeId());
ps.setString(i++, emp.getEmployeeName());
ps.addBatch();
j++;
i = 1;
if (j == maxCreateBatch) {
ps.executeBatch();
j = 0;
}
} catch (SQLException e) {
System.out.println("Connection failure");
e.printStackTrace();
}
}
@Override
public void updateEmployee(Employee emp) {
try {
Connection conn = DriverManager.getConnection("jdbc:postgresql://10.10.45.147:5432/db", "db",
"pass");
PreparedStatement ps = conn.prepareStatement("update employee set employeeName=? where employeeId=?");
int i = 1, j = 0;
ps.setString(i++, emp.getEmployeeName());
ps.setString(i++, emp.getEmployeeId());
ps.addBatch();
i = 1;
j++;
if (j == maxUpdateBatch) {
ps.executeBatch();
j = 0;
}
} catch (SQLException e) {
System.out.println("Connection failure");
e.printStackTrace();
}
}
@Override
public void executeUpdateEmployee(Employee emp) {
final String sql = "update employee set employeeName=:employeeName where employeeId=:employeeId";
Map<String, Object> map = new HashMap<String, Object>();
map.put("employeeId", emp.getEmployeeId());
map.put("employeeName", emp.getEmployeeName());
template.execute(sql, map, new PreparedStatementCallback<Object>() {
@Override
public Object doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
return ps.executeUpdate();
}
});
}
@Override
public void deleteEmployee(Employee emp) {
try {
Connection conn = DriverManager.getConnection("jdbc:postgresql://10.10.45.147:5432/db", "db",
"pass");
PreparedStatement ps = conn.prepareStatement("delete from employee where employeeId=?");
int j = 0;
ps.setString(1, emp.getEmployeeId());
ps.addBatch();
j++;
if (j == maxDeleteBatch) {
ps.executeBatch();
j = 0;
}
} catch (SQLException e) {
System.out.println("Connection failure");
e.printStackTrace();
}
}
}
This is my simple controller
@RestController
@RequestMapping("/postgressApp")
public class ApplicationController {
@Resource
EmployeeService employeeService;
@GetMapping(value = "/employeeList")
public List<Employee> getEmployees() {
return employeeService.findAll();
}
@PostMapping(value = "/createEmp")
public void createEmployee(@RequestBody Employee emp) {
employeeService.insertEmployee(emp);
}
@PutMapping(value = "/updateEmp")
public void updateEmployee(@RequestBody Employee emp) {
employeeService.updateEmployee(emp);
}
@PutMapping(value = "/executeUpdateEmp")
public void executeUpdateEmployee(@RequestBody Employee emp) {
employeeService.executeUpdateEmployee(emp);
}
@DeleteMapping(value = "/deleteEmpById")
public void deleteEmployee(@RequestBody Employee emp) {
employeeService.deleteEmployee(emp);
}
}
As you can see i have a preparedStatement for each operation and i add avery operation to a batch. In this moment, all get sent to the database only when the batch limit is reached.
**But my problem is : ** i need to sent every one of those batches to the database every second. How do i do that ? Cause i cant call the bathes outside of their methods.