I want to use a function for the update operation. So to create SQL query I must make sure the last element does not get coma(,)
I tried this
public Boolean updateSingleClient(Map map, String id) {
String updateSet = "";
int count = 0;
for (Object key : map.keySet()) {
String value = (String) map.get(key);
System.out.println("Count is " + count);
count = count + 1;
if (count == map.size()) {
updateSet = updateSet + key + "='" + value + "'";
} else {
updateSet = updateSet + key + "='" + value + "',";
}
}
System.out.println(updateSet);
return false;
}
Is there any way to check if this is the last element of HashMap?
Because this code is not working fine for me.
The last element in the iteration will be at map.size() - 1, not at map.size().
But note you can save a lot of this boilerplate code by streaming the map in to Collectors.joining:
String result =
map.entrySet()
.stream()
.map(e -> e.getKey() + " = '" + e.getValue() + "'"
.collect(Collectors.joining(","));
You can use a StringBuilder:
Append elments to StringBuilder
Remove last ,
Sample code:
public Boolean updateSingleClient(Map map, String id) {
StringBuilder updateSet = new StringBuilder();
for (Object key : map.keySet()) {
String value = (String) map.get(key);
updateSet.append(key + "='" + value + "',");
}
updateSet.deleteCharAt(updateSet.lastIndexOf(","));
System.out.println(updateSet);
return false;
}
Related
I have a PostRequest here that I want to be able to save data to different tables. About the #RequestBody I get a JsonString that I want to split to be able to execute an INSERT INTO query.
Here is my PostRequest:
#PostMapping(value = "/config/test/{tableName}/{schemaName}")
public String postValue(#RequestBody String values, #PathVariable("tableName") String tableName, #PathVariable("schemaName") String schemaName) {
String keyString = "";
String valueString = "";
final String sql = "INSERT INTO " + schemaName + "." + tableName + "(" + keyString + ") VALUES(" + valueString + ")";
final Query query = em.createNativeQuery(sql);
query.executeUpdate();
return values;
}
And here's my JSONString:
{
"id": 23,
"indexNummer": 4,
"indexName": "Gewichtung Alter Periode ohne Maßnahmen",
"minVal": 51.0,
"maxVal": 85.0,
"indexWert": 1
}
Is there any way to split my string so that my two strings keyString, valueString are filled as follows?
keyString = "id,indexNumber,indexName,minVal,maxVal,indexValue"
valueString="23,4, "Is there any way to split my string so that my two strings keyString, valueString are filled as follows?
keyString = "id, indexNumber, indexName, minVal, maxVal, indexValue"
valueString="23, 4, "Gewichtung Alter Periode ohne Maßnahmen", 51.0, 85.0, 1"
You can convert JSONString into Map or you can directly read it is map and then do the following
#PostMapping(value = "/config/test/{tableName}/{schemaName}")
public Map postValue(#RequestBody Map<String, Object> values, #PathVariable("tableName") String tableName,
#PathVariable("schemaName") String schemaName) {
String keyString = "";
String valueString = "";
Set<String> keySet = values.keySet();
for (String key : keySet) {
// add comma after first key-value pair only.
if (keyString.length() > 0) {
keyString += ",";
valueString += ",";
}
keyString += key;
Object valueObj = values.get(key);
if (valueObj instanceof String) {
valueString = valueString + "\"" + valueObj.toString() + "\"";
} else if (valueObj instanceof Integer) {
Integer valueInt = (Integer) valueObj;
valueString = valueString + valueInt;
} else if (valueObj instanceof Double) {
Double valueDouble = (Double) valueObj;
valueString = valueString + valueDouble;
}
}
final String sql = "INSERT INTO " + schemaName + "." + tableName + "(" + keyString + ") VALUES(" + valueString + ")";
final Query query = em.createNativeQuery(sql);
query.executeUpdate();
return values;
}
Use com.fasterxml.jackson.databind.ObjectMapper as below:
ObjectMapper mapper =new ObjectMapper();
String string="{\r\n"
+ " \"id\": 23,\r\n"
+ " \"indexNummer\": 4,\r\n"
+ " \"indexName\": \"Gewichtung Alter Periode ohne Maßnahmen\",\r\n"
+ " \"minVal\": 51.0,\r\n"
+ " \"maxVal\": 85.0,\r\n"
+ " \"indexWert\": 1\r\n"
+ "}";
TypeReference<HashMap<String, String>> typeRef = new TypeReference<HashMap<String, String>>() {
};
HashMap<String, String> map = mapper.readValue(string, typeRef);
String keys = map.keySet().stream().collect(Collectors.joining(","));
String values = map.values().stream().collect(Collectors.joining(","));
System.out.println(keys);
System.out.println(values);
Output :
indexNummer,maxVal,minVal,indexName,id,indexWert
4,85.0,51.0,Gewichtung Alter Periode ohne Maßnahmen,23,1
I have record returned by jdbcTemplate in List<Map<k,V>>, i want to fetch only Map<K,V> and then i want to add V in another List and returned that list to controller and show into the jsp
public List<Object> searchByempCodeV2(String tabSuffix, String empCode, String yyyyMm) {
List<Object> targetList = null;
MapSqlParameterSource param = new MapSqlParameterSource();
String tableName = "Salary_detail_report_082018";
String query = "SELECT "
+ " DISTINCT PAY_CODE, "
+ " PAY_CODE_DESC, "
+ " AMOUNT, "
+ " row_number() over (Order by EMP_CODE ) AS ROW_NUM "
+ " FROM " + tableName
+ " WHERE EMP_CODE=" + empCode
+ " AND YYYYMM=" + yyyyMm
+ " AND PAY_CODE NOT IN (997,998,999) "
+ " ORDER BY PAY_CODE ASC ";
List<Map<String, Object>> employees = queryForList(query);
if (employees != null && !employees.isEmpty()) {
for (Map<String, Object> employee : employees) {
targetList = new ArrayList<>(employee.values());
}
}
return targetList;
}
}
right now my targetList returned only the last record,provide me the suggestion
At first create the list instance:
List<Collection<Object>> targetList = new ArrayList<>();
And then fill in the list during the iteration:
for (Map<String, Object> employee : employees) {
targetList.add(employee.values());
}
See the difference: add() call instead of assignment by =.
So at the end you will have List<Collection<Object>>.
Connection conn = SqlConnection.getConnection("jdbc:mysql://localhost:3306/stocks");
Statement statement = conn.createStatement();
File path = new File("/Users/Zack/Desktop/JavaDB/BALANCESHEETS");
for(File file: path.listFiles()) {
if (file.isFile()) {
String fileName = file.getName();
String ticker = fileName.split("\\_")[0];
if (ticker.equals("ASB") || ticker.equals("FRC")) {
if (ticker.equals("ASB")) {
ticker = ticker + "PRD";
}
if (ticker.equals("FRC")) {
ticker = ticker + "PRD";
}
}
//CSVReader reader = new CSVReader(new FileReader(file));
//List entries = reader.readAll();
//ArrayList<String> entry = new ArrayList<String>();
Reader reader = new BufferedReader(new FileReader(file));
StringBuilder builder = new StringBuilder();
int c;
while ((c = reader.read()) != -1) {
builder.append((char) c);
}
String string = builder.toString();
ArrayList<String> stringResult = new ArrayList<String>();
if (string != null) {
String[] splitData = string.split("\\s*,\\s*|\\n");
for (int i = 0; i <splitData.length; i++) {
if (!(splitData[i] == null) || !(splitData[i].length() ==0)) {
stringResult.add(splitData[i].trim());
}
}
}
String columnName = null;
int yearCount = 0;
for (int i = 0; i < stringResult.size(); i++) {
int sL = stringResult.get(i).length();
for (int x = 0; x < sL; x++) {
if (Character.isLetter(stringResult.get(i).charAt(x))) {
yearCount = 0;
System.out.println("index: " + i);
columnName = stringResult.get(i);
columnName = columnName.replace(" ", "_");
System.out.println(columnName);
i++;
break;
}
}
yearCount++;
String value = stringResult.get(i);
System.out.println("Year: " + stringResult.get(yearCount) + " Value: " + value + " Stock: " + ticker + " Column: " + columnName );
if (!(columnName == null)) {
String writeValues = "INSERT INTO BalanceSheet (ticker, Year, " + columnName + ") "
+ "VALUE ('" + ticker + "','" + stringResult.get(yearCount) + "','" + value + "')";
String writeValues2 = "UPDATE BalanceSheet "
+ "SET ticker = '" + ticker + "', "
+ "Year = '" + stringResult.get(yearCount) + "', "
+ columnName + " = '" + value + "' "
+ "WHERE ticker = '" + ticker + "'";
statement.executeUpdate(writeValues2);
}
}
Towards the bottom of the code are two queries I tried, I'm trying to get all data organized by ticker and year into a table, "writeColumns" works but it's making a new row for every new "value" put into "columnName". My second attempt "writeColumns2" doesn't do anything.
I want to update the same row with a certain year for all values and then move onto the next year, then next ticker.
If I have understood your question correctly, you want to insert a row if it doesn't exists but update the values if it already does. You need to use ON DUPLICATE KEY UPDATE
String writeValues = "INSERT INTO BalanceSheet (ticker, Year, " + columnName + ") "
+ "VALUES (?,?,?) "
+"ON DUPLICATE KEY UPDATE " + columnName +"=?";
Statement statement = conn.prepareStatement(writeValues);
statement.setString(1,ticker);
statement.setString(2,stringResult.get(yearCount));
statement.setString(3, value);
This will solve your immidiate problem provided you create a UNIQUE index on ticker,year
However there are lot's of other issues here.
An update for each column - Currently you are doing an insert/update for each column on the table. What you are supposed to do is to insert update all the columns at one.
You are not using prepared statements addressed in my code sample
You shouldn't be doing this at all the best way to batch process data is to use MYSQL's built in LOAD DATA INFILE command. If your data is not in a format that can be easily imported into mysql, what your Java code can do is to transform it into a format that can be. Such a code will be a lot simpler and neater than what you have now
I'm trying to make my own ORM framework. I get the values from object into arrayList and I'm trying to save them in one time. I have to make for loop to save them all, but I'm confused how to make it?
prepareteState = connect.prepareStatement(Query);
for (int y = 1; y <= obs.size() ; y++) {
for(Object obj : obs){
prepareteState.setObject(y, obj);
System.out.println(Query);
System.out.println(prepareteState.toString());
}
}
prepareteState.execute();
thanks for good advices but, i found the solution :) it is a little bit different than the first idea but, works fine for me:) instead of using prepareState and setObject one by one i`m using StringBuilder to make String and execute query
private String makeInsertQuery(List<String> listOfColumnsNames, List<Object> listOfParameters, String tableName){
StringBuilder columns = new StringBuilder();
StringBuilder parameters = new StringBuilder();
String query = null;
if(listOfColumnsNames != null && listOfColumnsNames.size() != 0 && listOfParameters != null && listOfParameters.size() != 0 && tableName != null){
for(String string : listOfColumnsNames){
columns.append(string + ",");
}
columns.deleteCharAt(columns.length() - 1);
for(Object object : listOfParameters){
parameters.append ("'" + object + "'" + ",");
}
parameters.deleteCharAt(parameters.length() - 1);
query = "INSERT " + "INTO " + tableName + " ( " + columns.toString() + " ) " + " VALUES " + "( " + parameters.toString() + " )" ;
}
//TODO if you need check for null
return query;
}
I am wondering if I can access the values I get after iterating the hashmap in the following code (I know they are stored in map but want to use them outside loop). The key and corresponding values are iterated inside a loop. Can concurrent hashmap help me to get the values and use them outside the loop.
Thank You.
public static void main(String[] args) {
Map<String, List<String>> maleMap = new LinkedHashMap<String, List<String>>();
Map<String, List<String>> femaleMap = new LinkedHashMap<String, List<String>>();
try {
Scanner scanner = new Scanner(new FileReader(.txt));
while (scanner.hasNextLine()) {
String nextLine = scanner.nextLine();
String[] column = nextLine.split(":");
if (column[0].equals("male") && (column.length == 4)) {
maleMap.put(column[1],
Arrays.asList(column[2], column[3]));
} else if (column[0].equals("female") && (column.length == 4)) {
femaleMap.put(column[1],
Arrays.asList(column[2], column[3]));
}
}
Set<Entry<String, List<String>>> entries = maleMap.entrySet();
Iterator<Entry<String, List<String>>> entryIter = entries
.iterator();
while (entryIter.hasNext()) {
Map.Entry entry = (Map.Entry) entryIter.next();
Object key = entry.getKey(); // Get the key from the entry.
List<String> value = (List<String>) entry.getValue();
Object value1 = " ";
Object value2 = " ";
int counter = 0;
for (Object listItem : (List) value) {
Writer writer = null;
Object Name = key;
Object Age = null;
Object ID = null;
if (counter == 0) {// first pass assign value to value1
value1 = listItem;
counter++;// increment for next pass
} else if (counter == 1) {// second pass assign value to
// value2
value2 = listItem;
counter++;// so we dont keep re-assigning listItem for
// further iterations
}
}
System.out.println(key + ":" + value1 + "," + value2);
scanner.close();
Writer writer = null;
Object Name = key;
Object Age = value1;
Object ID = value2;
try {
String filename = ".txt";
FileWriter fw = new FileWriter(filename, true);
fw.write("# Table" + Name + "\n" + "map:"+ Name + " a d2rq:ClassMap;" + "\n"
+ " dataStorage map:database;" + "\n"+ "Pattern " +"\""+ Name + "/##"+ Age +
"." + ID + "##\";" + "\n"+ " class :" + Name +";"+"\n"+ " ."+"\n");//
fw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
ConcurrentHashMap is designed to be thread-safe.
If you aren't using multiple threads, it's worse than useless.
You should just use a MultiMap.
You can always access values outside the loop.
ConcorrentHashMap is fail-safe. it won't give any concurrent modification exceptions. it works good for multi threaded operations. The whole implementation of ConcurrentHashMap is same as HashMap but the while retrieving the elements , HashMap locks whole map restricting doing further modifications which gives concurrent modification exception.' But in ConcurrentHashMap, the locking happens at bucket level so the chance of giving concurrent modification exception is not present.