0

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.

  • Why aren't you using the **NamedParameterJdbcTemplate** for all the CRUD-operations? – Meziane Nov 14 '19 at 11:36
  • That does not answer my question... I used straight up sql code because that was how someone wanted it done. – Cazan Bogdan Nov 14 '19 at 15:52
  • It was not an answer. You can and shall use the **NamedParameterJdbcTemplate** for all your CRUD-operations. – Meziane Nov 14 '19 at 19:22
  • Ok, i sure will, but do you have any ideea how can i implement that batch updates tough ? – Cazan Bogdan Nov 15 '19 at 09:38
  • Why don't you use a timer like so: Timer timer = new Timer(); timer.schedule(batchUpdate(),10, 100); But if I were you, I would use one of **NamedParameterJdbcTemplate**'s method **batchUpdate(..)** – Meziane Nov 18 '19 at 08:42

0 Answers0