Mysql Stored procedure with java String Array - java

I need a stored procedure to compare mobile number list in my database table.
Example my table contain 100 rows,I pass java String array to stored procedure to get matching row values return.
The array contain multiple mobile numbers.
If any mobile numbers matched in my table mobile number column value it return row values.
Any possibilities available ?
If available please help me..
I have other solution it's working in spring Jdbc with mysql.
private static final String GET_MATCHING_MOBILE_NUMBERS = "SELECT USER_ID, USER_NAME, REGISTRATION_ID, IMEI_CODE, MOBILE_NUMBER FROM USER WHERE MOBILE_NUMBER IN (";
#Override
#Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public List<UserDO> getMatchingExistingUsers(final String[] mobileNumbers) throws UserDataException {
JdbcTemplate jd = this.getJdbctemplate();
Object[] params = mobileNumbers;
List<UserDO> userDOs = jd.query(getSqlQuery(GET_MATCHING_MOBILE_NUMBERS, mobileNumbers), params, new BeanPropertyRowMapper<UserDO>(UserDO.class));
return userDOs;
}
private String getSqlQuery(String query_string, String[] array_values) {
StringBuilder query_builder = new StringBuilder();
query_builder.append(query_string);
for (#SuppressWarnings("unused")
String values : array_values) {
query_builder.append("?,");
}
query_builder.append("*");
String formated_query = query_builder.toString().replace(",*", ")");
return formated_query;
}
I want Mysql stored procedure if possible for above code..
Advance thanks..

Select query is
private static final String GET_MATCHING_MOBILE_NUMBERS = "SELECT USER_ID, USER_NAME, REGISTRATION_ID, IMEI_CODE, MOBILE_NUMBER FROM USER WHERE FIND_IN_SET(MOBILE_NUMBER,?);";
Jdbc code is
List<UserDO> userDOs = jd.query(GET_MATCHING_MOBILE_NUMBERS, new Object[] { formatedSqlText }, new BeanPropertyRowMapper<UserDO>(UserDO.class));
It's working fine without using String Builder and Stored procedure.

Related

NamedParameterJdbcTemplate substituing values with single quotes

#Autowired
NamedParameterJdbcTemplate namedParameterJdbcTemplate;
public List<Contact> findByPhoneWithNamedParameters(String phone) {
MapSqlParameterSource namedParameters = new
MapSqlParameterSource().addValue("phone", phone);
String sqlQ = getSqlQuery(namedParameters);
namedParameters.addValue("anotherCondition", sqlQ);
String sql = "select * from Contact c where c.phone=:phone
:anotherCondition";
return namedParameterJdbcTemplate.query(sql, namedParameters, new ContactRowMapper());
}
private String getSqlQuery(MapSqlParameterSource namedParameters) {
return " and c.name='Saman'";
}
The above one is generating the query like below:
select * from Contact c where c.phone='09137390432' ' and c.name=''Saman'''
getSqlQuery() return value is embeddigng within single quotes, with that query is not working as expected.
I tried to concatenate the value directyle instead of namedParams;
But in my case, I have to avoid the SQL Injection.
How to resolve this?
You should only use named parameters with the actual values you want to pass to the query, not with whole SQL sub-parts. Otherwise it will escape also the valid SQL quotes.
So you should change your code to something like this:
private String getAdditionalSqlConditions(MapSqlParameterSource namedParameters) {
namedParameters.add("name", "Saman");
return "c.name = :name";
}
public List<Contact> findByPhoneWithNamedParameters(String phone) {
MapSqlParameterSource namedParameters = new MapSqlParameterSource().addValue("phone", phone);
String conditions = getAdditionalSqlConditions(namedParameters);
String sql = "select * from Contact c where c.phone=:phone and " + conditions);
return namedParameterJdbcTemplate.query(sql, namedParameters, new ContactRowMapper());
}

How to execute multi batch delete in JdbcTemplate?

I want to delete multiple database entries at once. Each entry should only be deleted if 3 fields match (here: name, email, age).
If I'd just wanted to delete by a single property, I'd go for:
String sql = "DELETE FROM persons WHERE (email) IN (?)";
JdbcTemplate template;
template.execute(sql, Arrays.asList(emails...));
But what if my condition is formed by multiple fields?
String sql = "DELETE FROM persons WHERE (name, email, age) IN (?, ?, ?)";
JdbcTemplate template;
template.execute(sql, ...); ???
The condition should always match all 3 fields (AND)!
Use the batchUpdate(sql, batchArgs, argTypes) method.
String sql = "DELETE FROM persons WHERE name = ? AND email = ? AND age = ?";
int[] argTypes = { Types.VARCHAR, Types.VARCHAR, Types.INTEGER };
List<Object[]> batchArgs = new ArrayList<>();
batchArgs.add(new Object[] { "John Doe", "john#example.com", 42 });
batchArgs.add(new Object[] { "Jane Smith", "jane#example.com", 47 });
. . .
JdbcTemplate template = ...;
int[] rowCounts = template.batchUpdate(sql, batchArgs, argTypes);
A batchUpdate is what you are looking for here. You would need to change/tweak your query a little bit though.
If you can pass a list of objects (you must match the class members with the values on the SQL query), it can be done automatically:
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
// class People { String name; String email; Integer age; }
final String sql = "DELETE FROM persons WHERE name = :name AND email = :email AND age = :age";
final SqlParameterSource[] batchArgs = SqlParameterSourceUtils.createBatch(people.toArray()); // List<People>
final int[] results = namedParameterJdbcTemplate.batchUpdate(sql, batchArgs);
logger.debug("{} record(s) inserted successfully", results.length);
The other approach would be what #Andreas proposed.
I would also recommend to use, always, parameterized queries: DELETE FROM persons WHERE name = :name AND email = :email AND age = :age.

How to query database with in IN statement in Java?

I have a small app in which a user uploads a file which carries bunch of id's. I read the file and store all those id's in a list. Now for each id I need to query database so that I could select some other other info. My question is that how to incorporate those id's as part of select statement?
Currently I am querying manually just by typing the id and I want to know how to use getter() as part of query?
Method to select from database
public List<NYProgramTO> getLatestNYData() throws Exception {
String query = "SELECT REQ_XMl, SESSIONID, EXPIRATION_DATE, QUOTE_DATE, POLICY_EFFECTIVE_DATE, TARGET_CREATED, RATING_TRANSACTION_ID, SOURCE_LASTMODIFIED, PREM_WHEN_RERATED FROM dbo.XML_SESSIONS with (nolock) WHERE XML_SESSIONS.LOB = 'PersonalAuto' AND XML_SESSIONS.RATING_STATE = 'NY' AND XML_SESSIONS.ID IN ('72834052') ORDER BY XML_SESSIONS.SOURCE_LASTMODIFIED DESC";
return this.sourceJdbcTemplate.query(query, (rs, rowNum) -> {
NYProgramTO to = new NYProgramTO();
to.setRequestXML(rs.getString("REQ_XML"));
to.setExpirationDate(rs.getDate("EXPIRATION_DATE"));
return to;
});
}
Thanks
You can use MapSqlParameterSource to map the parameter.
public void selectExample(Car car){
String query = "select * from car where id_car = :id and color = :color";
this.sourceJdbcTemplate.query(query, new MapSqlParameterSource("id", car.getId()).addValue("color", car.getColor()), new CarRowMapper());
}

Using Spring JdbcTemplate to extract one string

Can't seem to find a way to get one string from table using JdbcTemplate query.
This is the table my sql returns:
ID | STREET_NAME
------------------------
1 | Elm street
Now how am I supposed to get the value of STREET_NAME. SQL always returns one row, so no need to worry about returning more than one row.
For some background info:
INNER JOIN and COUNT in the same query
Using Tony Stark answer to get my table.
But how can I extract "Elm street" from it using JdbcTemplate?
It would help a lot to know what your SQL query looks like, but assuming it's something like SELECT STREET_NAME FROM table WHERE ID=1;
CODE:
public String getStreetNameById(int id) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "SELECT STREET_NAME FROM table WHERE ID=?";
String streetName = (String) jdbcTemplate.queryForObject(
sql, new Object[] { id }, String.class);
return streetName;
}
The class JdbcTemplate implements JdbcOperations.
If you look at the queryForObject javadocs in JdbcOperations it states:
Deprecated. as of 5.3, in favor of queryForObject(String, Class, Object...)
Basically, they have changed the method signature to get rid of Object[] arguments in the method signatures in favor of varargs. Please, see the relevant Github issue.
You can rewrite answer of #jlewkovich with the new method signature like this:
public String getStreetNameById(int id) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "SELECT STREET_NAME FROM table WHERE ID=?";
String streetName = (String) jdbcTemplate.queryForObject(
sql, String.class, id);
return streetName;
}
If you want to get only one column "string" from your table (or any query with joins), you have to say the name of the column.
Using SELECT * FROM TABLE is a very-very bad practice by the way. I bet you did this.
#JLewkovich modified code:
public String getStreetNameById(int id) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "SELECT STREET_NAME FROM table WHERE ID=?";
String streetName = (String) jdbcTemplate.queryForObject(
sql, new Object[] { id }, String.class);
return streetName;
}
But what if there is 0 or more than one result?
Think about it!
But to getting a sequence value (in Oracle), this should work.
public Long getSequence() {
Long seq;
String sql = "select SEQ_XY.NEXTVAL from dual";
seq = jdbcTemplateObject.queryForObject(sql, new Object[] {}, Long.class);
return seq;
}
As per latest specification queryForObject with below syntax is now deprecated
<T> T queryForObject(String sql, Object[] args, Class<T> requiredType)
New method uses varargs.
<T> T queryForObject(String sql, Class<T> requiredType, Object... args)
Updated Solution: We have to replace the class type with Object args and vice-versa.
Sql Query: SELECT STREET_NAME FROM table WHERE ID=1;
public String getStreetNameById(int id) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "SELECT STREET_NAME FROM table WHERE ID=?";
String streetName = (String) jdbcTemplate.queryForObject(
sql, String.class, new Object[] { id });
return streetName;
}
I usually do this way:
String result = DataAccessUtils.singleResult(
jdbcTemplate.queryForList(
"SELECT street_name FROM table WHERE id = :id",
Collections.singletonMap("id", id),
String.class
)
)
queryForList is used instead of queryForObject for handling empty results. queryForObject throws EmptyResultDataAccessException for empty results. Often it is not desired behavior.
DataAccessUtils.singleResult + queryForList:
returns null for empty result
returns single result if exactly 1 row found
throws exception if more then 1 rows found. Should not happen for primary key / unique index search
DataAccessUtils.singleResult

How to insert a java ArrayList in postgresql Array (integer[] ) type column using #InsertProvider

I Have a mapper method which is defined as following
#InsertProvider(type = ActivityMapperSQLBuilder.class, method = "insertIntoActivityComment")
public int insertIntoActivityComment(#Param("activityComment")ActivityComment activityComment);
the corresponding SQLBuilder method is defined as
public String insertIntoActivityComment(Map<String, Object> params) {
ActivityComment activityComment = (ActivityComment) params
.get("activityComment");
params.put("fileIds", activityComment.getFileIds());
params.put("commentType",activityComment.getCommentType());
params.put("commentText",activityComment.getCommentText());
params.put("commentingUserId",activityComment.getCommentingUser().getId());
params.put("attachments",activityComment.getAttachments());
params.put("activityId",activityComment.getActivity().getId());
StringBuilder builder = new StringBuilder(
"insert into activityComment (commenttype, commenttext, commentdate, commentinguser_id, attachments, activity_id, fileids) VALUES "
+ " (#{commentType}, #{commentText}, now(), #{commentingUserId}, #{attachments}, #{activityId}, #{fileIds} )");
return builder.toString();
}
whenever I call my mappermethod as following
getActivityMapper().insertIntoActivityComment(activityComment);
I encountered following error.
error updating database. Cause: org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of java.util.ArrayList. Use setObject() with an explicit Types value to specify the type to use.
The error may involve ActivityMapper.insertIntoActivityComment-Inline
The error occurred while setting parameters\n### SQL: insert into activityComment (commenttype, commenttext, commentdate, commentinguser_id, attachments, activity_id, fileids) VALUES (?, ?, now(), ?, ?, ?, ? )\n### Cause: org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of java.util.ArrayList. Use setObject() with an explicit Types value to specify the type to use."
the structure of my ActivityComment Object is
public class ActivityComment implements Serializable, IsSerializable {
private static final long serialVersionUID = 1L;
private int id;
private ActivityCommentType commentType;
private String commentText;
private Timestamp commentDate;
private Assignment activity;
private User commentingUser;
private String attachments;
private List<Integer> fileIds = new ArrayList<Integer>();
/*getters and setters*
}
Can anyone help me inserting ArrayList into the postgresql database?
What you will have to do is, get the data to be inserted.
Then you will have to add them in an arrayList.
Then am assuming you will be passing the arrayList to a function that does the job of inserting the data into the DB.
To insert the arraylist u need to frame the query dynamically.
I will write an example code for you, do some changes if you need to.
//Adding data into an ArrayList
ArrayList<String> data=new ArrayList<String>();
data.add(value1);
data.add(value2);
data.add(value3);
data.add(value4);
insertIntoMyDatabase(data); // function that will take this arraylist form a query and do the insertion.
//insertIntoMyDatabase :
public void insertIntoMyDatabase(ArrayList<String> data) {
PreparedStatement p;
String newdata="";
for(i=0;i<data.size();i++){ // This loop will take care of framing the query dynamically
if(i==data.size()-1){
newdata+="'"+data.toArray()[i]+"'";
}else{
newdata+="'"+data.toArray()[i]+"',";
}
String query="insert into table values("+newdata+")"; // This is the framed query for inserting data
try{
p=con.prepareStatement(query);
ResultSet r=pr.executeQuery();
}catch(SQLExecption e){
e.printStacktrace();
}
}

Categories