I have this requirement to show the amount with thousand separator. I have this POJO class with these two methods which I call according to my requirements
public Integer getTotalAmount() {
return totalAmount;
}
public String getTotalAmountWithSeparator() {
return String.format("%,d", totalAmount);
}
public void setTotalAmount(Integer totalAmount) {
this.totalAmount = totalAmount;
}
now when I use this method getTotalAmountWithSeparator() in my another class which looks like this and I do a println to see if the amount is being shown properly(which it does).
List<SupplierOrderDetails> list = SupplierOrderDetailBussinessLogic.getInstance().getSupplierOrderDetailsFromsupplierOrder(supplierOrder);
DataProviderBuilder dpb = new DataProviderBuilder();
// add heading data
dpb.add("so", supplierOrder.getSupplierOrderNo());
dpb.add("sn", supplierOrder.getSupplier().getPerName());
dpb.add("sec", supplierOrder.getSection().getAlternateName());
dpb.add("od", supplierOrder.getSupplierOrderCreated().toString());
// add table data
dpb.addJavaObject(list, "data");
here is the actual method getSupplierOrderDetailsFromsupplierOrder(supplierOrder); which gets the data from the db.
#SuppressWarnings("unchecked")
public List<SupplierOrderDetails> getSupplierOrderDetailsFromsupplierOrder(SupplierOrder supplierOrderDetails){
Session hibernateSession = HibernateUtills.getInstance().getHibernateSession();
Criteria criteria = hibernateSession.createCriteria(SupplierOrderDetails.class);
criteria.add(Restrictions.eq("supplierOrderID", supplierOrderDetails));
List<SupplierOrderDetails> models = criteria.list();
System.out.println(" models.size() " + models.size());
for (int i = 0; i < models.size(); i++)
{
if (models.get(i).getId() != null)
{
models.get(i).getProductID().getProductCode();
models.get(i).getProductID().getBrandName();
models.get(i).getPurchasePrice();
models.get(i).getOrderQty();
models.get(i).getTotalAmountWithSeparator();
System.out.println(models.get(i).getProductID().getBrandName() + " TotalAmount " + models.get(i).getTotalAmountWithSeparator());
}
// System.out.println(models.get(i).getPurchasePrice());
}
return models;
}
but when I do a println of the list data here,it does not show the separator in the amount why?????what am I doing wrong
dp = getSupplierOrderData(Long.parseLong(supplierOrderId));
System.out.println("DATA "+dp.getString("data"));
because dp.toString() method uses getTotalAmount() and not getTotalAmountWithSeparator()
Related
I have a String SELECT *FROM USERS WHERE ID = '#userid#' AND ROLE = '#role#'
Now i have replace any string between #...# , with a actual value .
Expected output SELECT *FROM USERS WHERE ID = '4' AND ROLE = 'Admin'
This replace will happen from a method , i have written this logic
public String replaceQueryKeyWithValueFromKeyValues(String query, int reportId) {
try {
REPMReportDao repmReportDao = new REPMReportDao();
int Start = 0;
int end;
if (query.contains("#")) {
boolean specialSymbolFound = false;
for (int i = 0; i < query.length(); i++) {
if (query.charAt(i) == '#') {
if (!specialSymbolFound) {
Start = i + 1;
specialSymbolFound = true;
} else {
specialSymbolFound = false;
end = i;
query = query.replace(query.substring(Start - 1, end + 1), repmReportDao.getReportManagerKeyValue(query.substring(Start - 1, end + 1).replaceAll("#", ""), reportId));
}
}
}
return query;
} else {
return query;
}
} catch (Exception e) {
logger.log(Priority.ERROR, e.getMessage());
return e.getMessage();
}
}
It works fine , but in the case if a single '#' symbol exist instead of start and end it will fail.
Like :
SELECT *FROM USERS WHERE emailid = 'xyz#gmail.com' AND ROLE = '#role#'
Here it should replace the only role '#role#' and should left email as it is.
Expected Output => SELECT *FROM USERS WHERE emailid = 'xyz#gmail.com' AND ROLE = 'Admin'
Complete example with mocked data returned by getReportManagerKeyValue:
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StackOverflow54842971 {
private static Map<String, String> map;
public static void main(String[] args) {
// preparing test data
map = new HashMap<>();
map.put("role", "Admin");
map.put("userid", "666");
// original query string
String query = "SELECT * FROM USERS WHERE ID = '#userid#' AND emailid = 'xyz#gmail.com' AND ROLE = '#role#' ";
// regular expression to match everything between '# and #' with capture group
// omitting single quotes
Pattern p = Pattern.compile("'(#[^#]*#)'");
Matcher m = p.matcher(query);
while (m.find()) {
// every match will be replaced with value from getReportManagerKeyValue
query = query.replace(m.group(1), getReportManagerKeyValue(m.group(1).replaceAll("#", "")));
}
System.out.println(query);
}
// you won't need this function
private static String getReportManagerKeyValue(String key) {
System.out.println("getting key " + key);
if (!map.containsKey(key)) {
return "'null'";
}
return map.get(key);
}
}
It's considered very bad practice to use string substitution to generate database queries, because you leave your code open to SQL Injection attacks. I can't tell from the small code sample you've provided, but the vast majority of large-scale Java projects use the Spring Framework, which allows you to use either JdbcTemplate or (my preference) NamedParameterJdbcTemplate. Both will allow you to substitute variables in a safe manner.
In here I'm trying to return two results as one response and not sure what option may good with it.
In here it return as a list,
List<FixedDeposit> fdList = em.createQuery(sb.toString())
.setParameter("start", dateFrom)
.setParameter("end", dateTo)
.setFirstResult(start).setMaxResults(limit)
.getResultList();
so I have got it as
List<FDSearchResult> searchList = getSearchResult(fdList);
response.setData(searchList);
return response;
And now again I want to return another response. And this is the calculation,
Double sum = 0.0;
sum = (Double) em.createQuery("SELECT SUM(deposit_amount)FROM fd_fixed_deposit where fd.status in ('ACT','REN','WDR') and fd.maturityDate between :start and :end ")
.setParameter("start", dateFrom)
.setParameter("end", dateTo).getSingleResult();
So how can I return the result through response for the sum? Please Help
I will post the full method,
public Response<List<FDSearchResult>> loadMaturedFDByRange(String fromDate, String toDate, final Integer start,
final Integer limit) {
final Response<List<FDSearchResult>> response = new Response<List<FDSearchResult>>();
Date dateFrom = DateUtils.parseDate("dd/MM/yyyy", fromDate, null);
Date dateTo = DateUtils.parseDate("dd/MM/yyyy", toDate, null);
Long count = 0L;
Double sum = 0.0;
try {
count = (Long) em.createQuery("SELECT COUNT(fd) FROM FixedDeposit fd where fd.status in ('ACT','REN','WDR') "
+ "and fd.maturityDate between :start and :end ")
.setParameter("start", dateFrom)
.setParameter("end", dateTo).getSingleResult();
} catch (NoResultException nre) {
count = 0L;
}
StringBuilder sb = new StringBuilder();
sb.append("SELECT fd FROM FixedDeposit fd where fd.status in ('ACT','REN','WDR') and fd.maturityDate between :start and :end ");
List<FixedDeposit> fdList = em.createQuery(sb.toString())
.setParameter("start", dateFrom)
.setParameter("end", dateTo)
.setFirstResult(start).setMaxResults(limit)
.getResultList();
sum = (Double) em.createQuery("SELECT SUM(deposit_amount)FROM fd_fixed_deposit where fd.status in ('ACT','REN','WDR') and fd.maturityDate between :start and :end ")
.setParameter("start", dateFrom)
.setParameter("end", dateTo).getSingleResult();
List<FDSearchResult> searchList = getSearchResult(fdList);
response.setData(searchList);
response.setPagination(new Response().new PaginationInfo(count));
return response;
}
In this instance, I would create an Object Container that holds these two objects and return that object instead.
public class MyContainer
{
List<FixedDeposit> fdList;
List<FDSearchResult> searchList;
public MyContainer()
{
}
}
This is how I would approach this.
You can return all relevant data via result objects.
Just create a new class which can obtain all your needed values.
Two options:
HashMap. Type cast Object to response and Double respectively. This is not a good practice
You can create a custom class which can encapsulate different object types.
Generics is what you need here.
public class MultiReturn<T> {
public final String name;
public final T object;
public NamedObject(String name, T object) {
this.name = name;
this.object = object;
}
}
How to store 2 integer in array list from result set and how to retrieve it.
I am trying to store the 2 integer to my array list and i don't know if get it correctly because when I am trying to retrieve it, it prints something like this
'tryCheckout$checkout#4f4fffa4' Thanks guys. This is my code so far.
public class checkout{
public int roomtypeid,itemid;
}
ArrayList<checkout> returncheckout = new ArrayList<checkout>();
try{
*String query ="select ri.item_id, ri.roomtype_id from roomtype_tb as rt , roomtypeitem_tb as ri , room_tb as r , reserverooms_tb as rr where rt.roomtype_id = r.roomtype_id and rt.roomtype_id = ri.roomtype_id and ri.roomtype_id = r.roomtype_id and r.room_id = rr.room_id and rr.reservation_id = 10";
PreparedStatement pst =conn.prepareStatement(query);
ResultSet rs = pst.executeQuery();
while(rs.next())
{
checkout out = new checkout();
out.roomtypeid = rs.getInt("ri.roomtype_id");
out.itemid = rs.getInt("ri.item_id");
returncheckout.add(out);
}
returncheckout.forEach(System.out::println);
}catch(Exception e)
{
e.printStackTrace();
}*
I didn't see your checkout class. Now I do. Change it to
public class checkout{
public int roomtypeid,itemid;
#Override
public String toString()
{
return "roomtypeid =" + roomtypeid + ", itemid=" + itemid;
}
}
In your checkout class override the toString() method. That is a special method that gets called when an object gets passed to System.out.println. It will look something like this:
#Override
public String toString()
{
return "roomType=" + roomType + ", id=" + id;//Not sure what your variables are. You will need to change this line
}
I think your code is doing what you want, you just need the toString() method to print the result out like you want it.
Java is actually returning the memory address for the object checkout. That is the weird numbers that are output to the screen. Add something like this to the checkout class.
public class checkout{
public int roomtypeid, itemid;
#Override
public String toString()
{
return "Room Type ID: " + roomtypeid + " Item ID: " + itemid";
}
}
The toString() method is called when the object is printed.
I add objects to my arraylist from a database table like this:
private void fillArray() {
for (People temp : peopleList) {
nameT = temp.getFirstName();
IDT = temp.getUserid();
users.add((new User(IDT, nameT) {
#Override
public String toString() {
return ID + "," + name;
}
}));
}
}
Wanting to display the elements of the objects in the arraList I separate them by overriding toString() and then using Scanner with the delimiter ",".
private void fieldSplitter(String object) {
Scanner inline = new Scanner(object).useDelimiter(",");
IDT = inline.next();
nameT = inline.next();
JOptionPane.showMessageDialog(null, IDT + " " + nameT, "Success", JOptionPane.INFORMATION_MESSAGE);
IDT = null;
nameT = null;
}
This should display all the different elements of each object. All I get is the last entry in my database table displayed every time even though there are 4 other entries.
What have I done wrong?
You should use the getters of your class User to have something cleaner :
users.add((new User(IDT, nameT) {
#Override
public String toString() {
return getId() + "," + getName();
}
}));
I need to add some or clauses to query. I need to do it in a loop.
StringTokenizer st = new StringTokenizer(symptoms, ",");
while(st.hasMoreTokens()){
qb.whereOr(Properties.Symptom.like("%" + st.nextToken() + "%"));
}
How I can add those or conditions properly, because this above is not working as expected. I want to add or for every symptom.
If you look at the documentation, you'll see that whereOr() takes an unbounded number of conditions. What you want to do is add them all at once in an array:
StringTokenizer st = new StringTokenizer(symptoms, ",");
ArrayList<WhereCondition> whereConditions = new ArrayList<WhereCondition>();
while(st.hasMoreTokens()){
whereConditions.add(Properties.Symptom.like("%" + st.nextToken() + "%"));
}
// Give the ArrayList an already allocated array to place its contents in.
WhereCondition[] conditionsArray = new WhereCondition[whereConditions.size()];
conditionsArray = whereConditions.toArray(conditionsArray);
qb.whereOr(conditionsArray);
It looks like the method call in the documentation takes two non-array WhereConditions and then an ellipsized argument, which accepts an array or an additional comma-separated list of objects. So you might have to do something like this to get it to work properly:
qb.whereOr(conditionsArray[0], conditionsArray[1], Arrays.copyOfRange(conditionsArray, 2, conditionsArray.length));
ADDENDUM: It looks like you're using APIs that don't match the documentation, possibly an older version of greenDAO. I wrote this solution based off the current documentation. I can't guarantee that it will work for you. I recommend updating if possible.
Try this:
StringTokenizer st = new StringTokenizer(symptoms, ",");
WhereCondition where = null;
while(st.hasMoreTokens()){
if (where != null) {
where = qb.or(where, Properties.Symptom.like("%" + st.nextToken() + "%"));
} else {
where = Properties.Symptom.like("%" + st.nextToken() + "%");
}
}
qb.where(where).list();
I had the same problem so I added my own method in an Util class to perform the same behavior when I have one or several WhereCondition in an array.
Here is my gateway method :
public static QueryBuilder whereOr(QueryBuilder queryBuilder, WhereCondition[] whereConditions){
if(whereConditions == null) return queryBuilder.where(null);
else if(whereConditions.length == 1) return queryBuilder.where(whereConditions[0]);
else return queryBuilder.whereOr(whereConditions[0], whereConditions[1], Arrays.copyOfRange(whereConditions, 2, whereConditions.length));
}
Use : Util.whereOr(queryBuilder, whereConditionsArray);
Default : Can't use the Builder Pattern from the QueryBuilder with this approach
(More later) Here, I share you some code which could spare you time when developping DAO methods.
public class QueryBuilderUtil {
public static final String EQ = "=?";
public static final String NOTEQ = "<>?";
public static final String LIKE = " LIKE ?";
public static final String GE = ">=?";
public static final String LE = "<=?";
public static final String GT = ">?";
public static final String LT = "<?";
public static QueryBuilder whereOrOnSamePropertyWithDifferentValues(QueryBuilder queryBuilder, Property property, String operation, String values, String separator) {
return whereOrOnSamePropertyWithDifferentValues(queryBuilder, property, operation, values.split(separator));
}
public static QueryBuilder whereOrOnSamePropertyWithDifferentValues(QueryBuilder queryBuilder, Property property, String operation, String[] values) {
WhereCondition[] whereConditions = new WhereCondition[values.length];
int i = 0;
for (String value : values) {
whereConditions[i++] = new WhereCondition.PropertyCondition(property, operation, value);
}
return whereOr(queryBuilder, whereConditions);
}
public static QueryBuilder whereOr(QueryBuilder queryBuilder, WhereCondition[] whereConditions) {
if (whereConditions == null) return queryBuilder.where(null);
else if (whereConditions.length == 1) return queryBuilder.where(whereConditions[0]);
else return queryBuilder.whereOr(whereConditions[0], whereConditions[1], Arrays.copyOfRange(whereConditions, 2, whereConditions.length));
}
}
With this class, you can perform a whereOr with the same property on multiples "values string" in one line. It was necessary to clean my code :). However you can only do simple operations like variables declared in the class.
Example :
public List<Block> loadAllByModId(String mods_id) {
synchronized (this) {
QueryBuilder<Block> queryBuilder = queryBuilder();
QueryBuilderUtil.whereOrOnSamePropertyWithDifferentValues(queryBuilder, Properties.ModId, QueryBuilderUtil.EQ, mods_id, ";");
query_list = queryBuilder.build();
}
Query<Block> query = query_list.forCurrentThread();
return query.list();
}
Hope it helps