Storing object array with JDBCTemplate from POST method - Spring Boot - java

How to do you insert an object array into a database by using JDBCTemplate? I have an object array of variable length coming in from my POST method in my controller.
I have looked at these,
http://www.java2s.com/Tutorial/Java/0417__Spring/PassParameterAsObjectArray.htm
How to insert Integer array into postgresql table using jdbcTemplate in Java Springboot?
As well as others and they do not seem to fit to what I need.
Controller
// Service
#Autowired
private DBService tool;
#PostMapping(value = "/foo")
private void storeData(#RequestBody CustomObject[] customObjects) {
// Calls service then DAO
tool.storeData(customObjects);
}
POJO Object
public class CustomObject {
private Integer id;
private String name;
// Getters & Setters for class attributes
...
}
DAO Is this right? Because I want to store each array element separately, with each element having its own row.
#Autowired
private JdbcTemplate temp;
public void storeData(CustomObject[] customObjects) {
String sql = "INSERT INTO FooBar(name) VALUES(\'" + customObjects.toString() + "\');";
temp.update(sql);
}
Expected
I want to store the array of my custom object from POST into my database with each element having its own row.

Ideally you would want to iterate over the array and save each "CustomObject" .
private JdbcTemplate temp;
public void storeData(CustomObject customObject) {
String sql = "INSERT INTO FooBar VALUES(" + customObject.id + ",\'"+ customObject.name +"\');";
temp.update(sql);
}
#PostMapping(value = "/foo")
private void storeData(#RequestBody CustomObject[] customObjects) {
// Save each record individually
customObjects.forEach { customObject ->
tool.storeData(customObjects);
}
}

Related

Spring Boot: Get required columns from API based on user request

I am trying to implement an API endpoint where a user can request required columns from the API
Basically, this is what I want:
This is my products table entity
#Entity
#Table(name ="products")
class product{
private Long id;
private String itemName;
private String itemDesc;
private double quantity;
private double purchaseRate;
private double saleRate;
private double onlineSaleRate;
.
.
.
constructor()
getter & setter
}
***And my endpoint is:
localhost:8080/api/v1/products
Requirement:
I want to write an api endpoint where i request columns based on requirementsa and get those as response
Example: If i only need - itemName, itemPrice and quantity i'll return those as response only.
if some user has requirement of itemName, purchaseRate, saleRate, quantity he will get those as a response only.
Right now i am writing new endpoints as per requirements, but i think there is some way to do this.
I want to implement this in my application, i tried google for this but there is no search query that is resulting me as per my requirement.
Create a class with all the fields of your entity with the field types of nullable boxed Boolean (for the purpose of the request json).
class ProductColumns {
private Boolean itemName;
private Boolean itemDesc;
...
// setters and getters
}
Then, to construct a custom response, you can use a java Map to acheive this:
public ResponseEntity<Object> getFilteredColumns(ProductColumns columns) {
Map<String, Object> map = new HashMap<String, Object>();
if (columns.getItemName() == true) {
map.put("itemName", [your repo/service method for getting the particular value]);
}
if (columns.getItemDesc() == true) {
map.put("itemDesc", your repo/service method for getting the particular value]);
}
...
return ResponseEntity<Object>(map, HttpStatus.OK);
}
Of course you should wrap it in some try-catch to your liking.

Map Custom JdbcTemplate query result in an Object

I new in java and try to use spring framework. I have a question.
By example, I have table :
employee (id_employee, name)
employee_product (id_employee_product, id_employee, product_name)
if I select an employee data from my Employee table, I can map it in a POJO model User and define the tables structure in that model, like this:
public class Employee {
private final int id_employee;
private final String nama;
public Employee(int id_employee, String nama){
this.id_employee = id_employee;
this.nama = nama;
}
public int getId() {
return id_employee;
}
public String getNama() {
return nama;
}
}
And this is the map from jdbcTemplate:
final String sql = "SELECT id_employee, nama FROM employee";
return jdbcTemplate.query(sql, (resultSet, i) -> {
return new Employee(
resultSet.getInt("id_employee"),
resultSet.getString("nama")
);
});
That is clear example for select data from 1 table.
My question is, how to map data from query if my data is custom query? Such us using join and select custom field from that tables, Am I need to create POJO every query?
Sometimes I need to select only employee.id_employee, and employee.name field from my employee table.
And in another controller I need to select employee.id_employee from my employee table.
In another case, I need only select employee.name, and employee_product.product_name
Is there an alternative to map the data without creating POJO for every case?
Create a one POJO combining two tables like this
public class Employee {
private int id_employee;
private String name;
private int id_employee_product.
private String product_name
//getter and setters
//Don't create a constructor its Entiry
}
Now by using a BeanPropertyRowMapper Doc Link write your repository like
public List<Employee> fetchEmployeeProduct(){
JdbcTemplate jdbcTemplate = new JdbcTemplate("Your_DataSource");
StringBuilder query = new StringBuilder();
query.append("Your Query");
List<Employee> employeeProductList =
jdbcTemplate.query(query.toString(), new BeanPropertyRowMapper<Employee>(Employee.class));
}
Make sure SELECT clause in the query and Employee POJO's filed name is same.
Once if you execute your query it will automatically map to POJO. You no need to write a custom mapper BeanPropertyRowMapperwill take care of mapping.

Map additional values via rest controller

I have this Rest endpoint which returns table with IDs:
#GetMapping("pages")
public Page<ContractDTO> pages(#RequestParam(value="page") int page, #RequestParam(value="size") int size) {
return contractService.findAll(page, size).map(mapper::toDTO);
}
ContractDTO DTO:
public class ContractDTO {
private Integer id;
private String name;
private Integer gateway;
private Integer reseller_id;
private Integer acquirer_id;
private Integer terminal_id;
private Integer merchant_id;
private String descriptor;
...
}
I store into database table the ID's of each additional component like acquirer_id, terminal_id and etc.
I need to do additional SQL request like SELECT * FROM acquirers WHERE id = 3.
How I can make this after I convert the DTO object with Java?

How to execute query that will separate by certain symbol in Repository Springboot using java

I want to separate the result data with query by "~" within the same entity, to separate another entity data by ","
My code
mainRepository.java
public interface mainRepository extends CrudRepository<Error, Long> {
#Query(value= "SELECT * FROM Error t where t.applicationID = :applicationid", nativeQuery= true)
List<Error> findListByApp(#Param("applicationid") String applicationid);
}
and in another class I call that function
String cb = errorRepository.findListByApp("application1").toString();
System.out.println(cb);
the result if i execute cb is
[com.info.main.Error#6ec8b40e, com.info.main.Error#6ec8b40e, com.info.main.Error#6ec8b40e]
I want to keep it sorted by app first, then name, then email.
the result that i want to achieve is just like this :
[app1~name1~email1, app2~name2~email2, app3~name3~email3]
Why you are using toString with the result List?
String cb = errorRepository.findListByApp("application1").toString();//why toString?
Instead you have to use a List like so :
List<Error> result = errorRepository.findListByApp("application1");
//this will print the list or Error it will call to String for each error
System.out.println(result);
to show the result you need just override toString method in your Error entity with the format you want for example.
#Entity
public class Error {
private String app;
private String name;
private String email;
//getter setter
#Override
public String toString() {
return app + "~" + name + "~" + email;
}
}

Nested json structure

I want to create a dynamodb which has following features
PK: orderId
RK: date
shipped: Y|N
details: <nested json structure>
Point 4 is the one which i am really confused about. If i keep details field as a string and try to store json as string, AWS escape " characters i.e., {"onlineStore" : "283"} becomes {\"onlineStore\": \"283\"}
This get's retrieved properly from dynamodb with details as string mappings but if i have to convert it to a pojo using jackson, I have to take care of those \.
So as an alternative, I thought that i could create details a POJO i.e.,
public class OrderDetail{
private int onlineStore;
// rest of the JSON properties
#JsonCreator
public OrderDetail (#JsonProperty("onlineStore") int onlineStore, ...){
this.onlineStore = onlineStore;
}
}
With the above implementation, i get error that DynamoDBMappingException: Couldn't convert attribte.
The OrderDetail type is a common type which is being used between my JSON REST Response as well so i want to avoid putting DynamoDB specific annotation here.
Now the question is what should be proper way to implement it.
If you are using DynamoDB Mapper class to perform the CRUD operation, you can use the annotation #DynamoDBTypeConvertedJson to save the order details.
DynamoDBTypeConvertedJson - Check this link for more details
DynamoDBMapper class:-
The AWS SDK for Java provides a DynamoDBMapper class, allowing you to
map your client-side classes to DynamoDB tables. To use
DynamoDBMapper, you define the relationship between items in a
DynamoDB table and their corresponding object instances in your code.
The DynamoDBMapper class enables you to access your tables, perform
various create, read, update and delete (CRUD) operations, and execute
queries.
Sample Implementation:-
#DynamoDBTable(tableName = "Order")
public class Order implements Serializable {
private static final long serialVersionUID = -3534650012619938612L;
private String orderId;
private OrderDetail orderDetail;
#DynamoDBHashKey(attributeName = "orderId")
#DynamoDBAutoGeneratedKey
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
#DynamoDBTypeConvertedJson
public OrderDetail getOrderDetail() {
return orderDetail;
}
public void setOrderDetail(OrderDetail orderDetail) {
this.orderDetail = orderDetail;
}
}
public class OrderDetail implements Serializable {
private static final long serialVersionUID = 7312390212027563305L;
private Integer onlineStore;
public Integer getOnlineStore() {
return onlineStore;
}
public void setOnlineStore(Integer onlineStore) {
this.onlineStore = onlineStore;
}
#Override
public String toString() {
return "OrderDetail [onlineStore=" + onlineStore + "]";
}
}
public Order loadOrder(String orderId) {
DynamoDBMapper dynamoDBMapper = new DynamoDBMapper(dynamoDBClient);
Order order = dynamoDBMapper.load(Order.class, orderId,
new DynamoDBMapperConfig(DynamoDBMapperConfig.ConsistentReads.CONSISTENT));
System.out.println("Order : " + order.toString());
System.out.println("Order Id : " + order.getOrderId());
System.out.println("Order Detail : " + order.getOrderDetail());
System.out.println("Online store : " + order.getOrderDetail().getOnlineStore());
return order;
}
Output:-
Order Id : 0beced28-f1de-4c44-8094-6de687d25e97
Order Detail : OrderDetail [onlineStore=1]
Online store : 1
Data in DDB:-
As you mentioned, the order detail will be stored with escape characters. However, when you get the data using DynamoDB mapper, it will be in deserialized form (i.e. as POJO object).

Categories