how to map query result to string array in java - java

select id,name,salary,city,state,country from employee where name like '%a%';
I need to map above query result to String array, position 0 always id, position 1 always name ...... position 5 always country.
Using JPA or MyBatis is there a way we can dynamically map the select query values into fixed position string array ?

I've never personally used JPA, but - after reading through it a bit - believe this should be correct.
TypedQuery<Object[]> query = entityManager.createQuery(
"SELECT id,name,salary,city,state,country FROM employee WHERE name LIKE '%a%'", Object[].class);
List<Object[]> results = query.getResultList();
where (Integer) results.get(index)[0] = id, (String) results.get(index)[1] = name, etc.
You can change Object[] to String[] if you would like an array of Strings.

Why do you want to use String array?
It is better to use an object list instead. It will be easier to get city of an employee using employee.getCity() versus array[3].
It makes for more readable code as well.
To use an object list, you need to create a model for your employee and annotate with #Entity and create a repository for that entity. JPA documentation should help do this easily

Related

Spring JPA Query to get Sub-List of provided IDs not in Table

Is there a way using a Spring JPA Repository Query to get a sub-list of the IDs that were not present in our table given a list of IDs?
Something like this:
#Query(value = "Some query returning a sublist of orderIds not in TABLE")
List<String> orderIdsNotInTable(#Param("orderIds") List<String> orderIds);
I found a link here but I cant think of how to make that a JPA Query.
EDIT: The goal here is to save on running memory so if there are thousands of ids and many calls happening at once I would like it to be handled without creating a second copy of all the ids potentially.
As from what your questions asks, my solution would be:
retrieve the list of IDs present in your database:
#Query("select t.id from Table t")
List<String> findAllIds();
Loop through the list of IDs you have and look up if the list of IDs from the database table does not contain your id.
List<String> idsNotContained= orderIds.stream()
.filter(!findAllIds()::contains)
.collect(Collectors.toList());
Building on #Pawan.Java solution, I would look for the ids and then apply the filtering.
List<String> findByIdIn(List<String> ids);
The list which is returned will contain the ids which exist, it is then just a matter of removing those ids from the original list.
original.stream().filter(i ->
!existingIds.contains(i)).collect(Collectors.toList());
If there is a large number of ids being passed in, then you might want to consider splitting them into parallel batches.
If your list is not too big, then an easy and efficient solution is to retrieve the IDs from the list that are in the table:
select t.id from Table t where t.id in (id1, id2, ...)
Then a simple comparison between initial and returned lists will give you the IDs that are not in the table.
#Query(value = "SELECT t.id FROM TABLE t WHERE t.id NOT IN :orderIds")
List<String> orderIdsNotInTable(#Param("orderIds") List<String> orderIds);
I don't know if I understood you correctly but can you try the solution above.

JPQL query for item in list stored with AttributeConverter

As Tobias Liefke suggested here, I have implemented an AttributeConverter to store list values into a single string column separated by commas.
Converter Class:
public class ListNumbersConverter implements AttributeConverter<List<Long>, String>
Field in Entity class:
#Column(name = "user_ids", nullable = false)
#Convert(converter = ListNumbersConverter.class)
private List<Long> userIds;
It is working fine but I can't query the records for specific list items. I tried using IN operator in JPQL query like below:
? in userIds
With this I get only a result if input param is the first element in the DB value. e.g: DB value is "1,2,3". I am able to retrieve this record if input param value is 1 for above mentioned query, but not able to retrieve if value is either 2 or 3. How do I have to write my query to retrieve all records that contain a specific item?
My database is MySQL.
Hibernate doesn't know how the converter maps the list to the column. It can't build a mapping from the JPQL ? in userIds to the matching SQL fragment, as it would need to know how your converter is implemented.
But you can always build that SQL fragment yourself, for example:
WHERE concat(',', entity.userIds, ',') LIKE concat('%,', ?, ',%')
The first concat is to ensure that the expression matches even the first and last value of the list (which wouldn't start or end with the separator).
There are other DB specific functions that could be used, but this example works on all database types I know of.
Another remark: You should not try to join userIds in the query - as it is of a basic type, even if it is a list. See the JavaDoc of #Convert:
The Convert annotation is used to specify the conversion of a Basic field or
property.
Nevertheless Hibernate will complain if you compare your attribute directly with a literal (entity.userIds = '1') because the type of the attribute doesn't match the type of the literal. But as long as you use a function like above for either side of the comparison it won't complain.

Entity Manager ORDER BY query with Sort Object

I am using the Entity-Manager and want to append the "ORDER BY" query comming from the Sort (org.springframework.data.domain.sort) Object.
The Sort object contains something like "id: DESC".
i can parse the Sort object as a String removing the condition and appending it to my query. the query would looks like this "SELECT p FROM projects ... ORDER BY p.id DESC"
Is there a better way to tackle this problem, any suggestions?
Sorry maybe my description is a bit missleading but i have a REST api and my method gets the Sort object inlcuding the field i need to order by and the direction. I cant easily order it ASC or DESC. its depending on the Sort object i own with the method usage.
Last week, i was checked for the same issue and changed my code as like below: it was worked Fine;sharing the same to you.
StringBuilder strBuilder = "SELECT p FROM projects";
entityManager.createQuery(strBuilder.toString());
Iterator<Order> orderIterator = sort.iterator();
Order order = orderIterator.next();
strBuilder.append(" Order By ").append(order.getProperty()).append(" ")
.append(order.getDirection().name());
Simply use the descending method on you Sort object to get what you need.
query.orderBy(mySort.descending());

Get single row in JPA

How to get single row from entity in JPA?
Table: Employee
#Id
private int empId;
private String empName;
...
JPA by default return List. I`m trying to fetch single row.
EmployeeRepository :-
public Employee findByEmpName(String empName);
Another way is to do it, #Query should be use.
#Query(value="select e from Employee e where empName = ?1 limit 1", nativeQuery=true)
public Employee findByEmpName(String empName);
How can i ensure that it return single row and correct result.
Any help appreciated.. Thanks in advance.
There is an out of the box solution, in repository you can name method as findFirstBy... or findTopBy..., that should do the thing.
You can find more in Spring reference documentation
You don't need to "ensure" anything.
If you dont have a collection of sort specified as return (e.g. List<Employee> instead of Employee ) and your query return more than one result it will launch a javax.persistence.NonUniqueResultException: result returns more than one elements.
If your query return more rows and you want only one of those either add a condition to differentiate which one of those rows you actually want or, if they are the same, add a good old distinct
How can i ensure that it return single row and correct result.
That's your job when writing the query
JPA have a method to fetch a single row getSingleResult, but it's recommended to fetch a list and extract the first element over getResultList.
See: Example
If you want to select only one row from the result set then you can limit number of records by using the query.setMaxResults method:while creating the jpa query.
example : criteria.setMaxResults(25); : it only fetch 25 records out of 100 records.
In case someone wants just a single row from a database using JpaRepository (spring-data-jpa), I found this very useful:
repository.findAll().stream().findFirst().orElseThrow(...)
Since this is a stream, I suppose that rows (or rather: Objects) are fetched row by row.

How to do a search based on number of fields that has been filled

I am implementing a search in which users need to fill different fields to do the search, but I am not sure how to search if user does not fill some of the fields.
Lets say I am asking them to fill name,family,age,city and country
User may leave any of these blank so I should make a search based on the filled one.
For example if name and family are filled just search for name AND family and if name, family and country are filled, search for records that has all of these three.
I am using prepared statement, How about if I use Persitance API?
ps.setString(1, "Name");
ps.setString(2, "Family");
ps.setint(3, "age");
ps.setString(4, "city");
ps.setString(5,"country");
Query
SELECT * FROM Customer WHERE name = ? AND family = ? AND age = ? AND city = ? AND country = ?
You'll want to remove the expressions that reference unspecified fields.
You can have a SortedMap<String, Object> which contains only the requested fields. Iterate over that and build the SQL where clause using a StringBuilder along with setting the parameter values.
Some ORM's will do this for you.
If very complex, this sort of scenario seems to call for something like the Hibernate Criteria Query API.
The Squiggle SQL Builder might work well for you for simpler cases.

Categories