How do I create a query to my room database from example the SUM of a database column then convert it to a String to then populate text fields in a different activity? I have 5 activities in my app where I wish to customise the data that is displayed but I wish to pull that data from my Room Database.
Many Thanks
If you want a single value then you simply use an #Query annotated method that returns the the single value. e.g.
#Query("SELECT sum(the_column) FROM the_table")
String getTheSum();
could be an integer type or decimal type, which could be more appropriate
no need to convert to a string just retrieve as a String
However, you may need to format the output e.g. if you wanted a specific precision (round(sum(the_column),2) for 2dp). Some formats could be easier to apply outside of SQLite.
If you wanted many (0-n) you could return a List e.g.
#Query("SELECT sum(the_column) FROM the_table GROUP BY the_column_or_columns_to_group_by")
List<long> getTheSums();
If you want to return multiple values for row then you need a POJO where there are member variables that match the column names that are output. e.g.
#Query("SELECT sum(the_column) AS theSum, min(the_column) AS theMin, max(the_column) AS theMax FROM the_table GROUP BY the_column_or_columns_to_group_by")
List<ThePojo> getSumMinMax();
Could use the POJO :-
class ThePojo {
long theSum;
long theMin;
long theMax;
}
If you wanted all of the columns PLUS the additional columns you could for example have :-
#Query("SELECT the_table.*,sum(the_column) AS theSum, min(the_column) AS theMin, max(ithe_column) AS theMax FROM cities")
List<ThePojoPlus> getSumMinMaxPlus();
Could the the POJO :-
class ThePojoPlus {
#Embedded
TheTable the_table;
#Embedded
ThePojo pojo;
}
or (if there is no ThePojo class)
class ThePojoPlus {
#Embedded
TheTable the_table;
long theSum;
long theMin;
long theMax;
}
Related
I am working on a Spring Boot project using JdbcTemplate to access data and I have the following problem with a single specific field using BeanPropertyRowMapper to map the result of a query on a DTO object.
This is my repository method performing my query and mapping the query result on a DTO object:
#Override
public OneRowReadTrain1DTO getOneRowReadTrain1DTO() {
String SELECT_SINGLE_RECORD_OneRowReadTrain1 = "SELECT * FROM OneRowReadTrain1";
List<OneRowReadTrain1DTO> resultList = jdbcTemplate.query(SELECT_SINGLE_RECORD_OneRowReadTrain1,
BeanPropertyRowMapper.newInstance(OneRowReadTrain1DTO.class));
OneRowReadTrain1DTO result = resultList.get(0);
return result;
}
It works fine except a specific field. The problem is that this field is the only one that doesn't have the same name as DTO class field and column name on my table.
Infact on my OneRowReadTrain1DTO I have:
public class OneRowReadTrain1DTO {
#JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = JsonFormat.DEFAULT_TIMEZONE)
private Date timeStamp;
..........................................................
..........................................................
..........................................................
}
As you can see this class field is named as timeStamp but the related column on my table is Time_Stamp so this field is valorized as null.
There is a way to avoid to write a custom row mapper (the class fields\table columns are hundreds) and to specify that my Time_Stamp have to be mapped on the timeStamp?
I know that I can simply rename this field name in my class but it is pretty ugly.
Instead of using "select *" you can select each field required for the DTO and give it the proper name of the field.
e.g.: "select Time_Stamp as timeStamp, etc... "
is it possible to have and Entity with a field calculated using Formula when the field is a Collection (let's say it's a Set)?
Here's the dummy example of what I'm trying to achive:
#Formula(value =
"SELECT NEW com.example.entity.Person(p.name, p.age) FROM Person p")
lateinit var people :Set<Person>
From the JavaDoc for #Formula:
Defines a formula (derived value) which is a SQL fragment ...
You have to think of the fragment you write as an replacement in the select statement:
SELECT (formulaValue) AS propertyName FROM ....
Everything you can write into formulaValue can be used in #Formula.
Your example is not a valid SQL fragment and as you can see, it is not possible to return more than one value from a #Formula.
But you could use #Subselect and a wrapper object instead:
#Entity
#Subselect("SELECT name, age FROM Person p")
public class PersonWrapper {
#Id
private String name;
private int age;
}
(in Java, as I'm not aware of the correct syntax of Kotlin)
If you really need the collection of these values in another entity, you need something to join on (which is missing in your example) and use that in an #OneToMany or #ManyToMany. Otherwise there is no use to have all these values in your entity, as all entities would have the same collection.
I am setting up criteria for database calls and am having trouble getting understanding how to set up my code. I have put my criteria in and now need to know how I make sure I populate the variables right. This is what I have.
Public class Key extends abstractDAO<key>{
Public List<Key> getKeyValues(){
Criteria c = createCriteria();
c.add(Restrictions.lt("id", 3)).addOrder(Order.asc("id")).list();
return c.list();
Now the table has 2 rows. One is current and the second is a new request row. The database has 3 columns. Column 1 is the I'd, column two is the key, and 3 is a timestamp. I need to populate all the variables in order. I am not sure how to go about this in my key.java file
Key.java
#column(name="id")
private int actualID;
#column(name="key")
private Boolean actualKey;
#column (name="actualTime")
private Date actualTime;
Then repeats with requested, requestKey, and requestTime. Then I have public get and sets for each. Have not added any parameters to any method yet either. I am not sure how to set this file up so the list actually sets the variables when the DAO request the rows of the database.
try the following:
public List<Key> getKeyValues()
{
return createCriteria()
.add( Restrictions.lt( "actualID", 3 ) )
.addOrder( Order.asc( "actualID" ) )
.list();
}
Provided that the rest of the mapping and the implementation of createCriteria() are correct, it should return a list of Key's objects whose ids are less than 3, ordered by id.
Here is the problem i have:
class CurrencyPrice {
#Transient
String pair;
float spotPrice;
Date timeStamp;
}
And I have 3 table the names of which stand for "usd value of euro/gbp/yen respectively": usd_euro, usd_gbp & usd_yen. They all have the same 3 columns: id, spotprice, timestamp.
For some reason i cannot have a single table. The transient instance variable 'pair' will have the following values depending on what it represents: "usd_euro", "usd_gbp" & "usd_yen"
And depending on the value in 'pair' I want to insert a row in one of the tables, eg: if I have the value "usd_yen" in 'pair' then the object should be persisted in usd_yen table.
And when I want to fetch data, I want JPA to decide which table to SELECT from based on the value in 'pair'
This is simple in JDBC but is there a way to do this in JPA?
Thank you.
If I understand your requirements correctly, this might actually be feasible in JPA now (those threads you cite are quite old), if you can use inheritance on your entity and an additional join table and if it's acceptable that the ID for each type is not contiguous.
You could basically define your classes like this then:
#Entity
#Table(name="curr_base") // choose a suitable name
#Inheritance(strategy=InheritanceType.JOINED)
#DiscriminatorColumn(name="currency", discriminatorType=DiscriminatorType.STRING) // your join table needs this column in addition to the id
public abstract class CurrencyPrice {
#Id
private int id;
}
#Entity
#Table(name="usd_euro")
#DiscriminatorValue("usd_euro")
public class UsdEuroPrice extends CurrencyPrice {
float spotPrice;
Date timeStamp;
}
#Entity
#Table(name="usd_gbp")
#DiscriminatorValue("usd_euro")
public class UsdGbpPrice extends CurrencyPrice {
float spotPrice;
Date timeStamp;
}
#Entity
#Table(name="usd_yen")
#DiscriminatorValue("usd_euro")
public class UsdYenPrice extends CurrencyPrice {
float spotPrice;
Date timeStamp;
}
I replicated spotPrice and timeStamp on each subclass so that you don't have to modify your existing table definitions - of course it would be much cleaner to only have them on the superclass/join table.
This mapping allows it for example to perform a EntityManager.persist(new UsdGbpPrice(...)) and have JPA insert a row into the right table. For more information, look here.
I am using objectify-appengine framework for querying. Here is my simplified problem: Consider these 2 classes:-
public class Customer {
#Id private String email;
#Embedded private Account Account = new Account(); // note embedded annotation
}
and
public class Account {
private String number; //example: 1234
}
The following query works & gives me 1 customer:
Objectify ofy = ObjectifyService.begin();
ofy.query(Customer.class).filter("account.number = ", "1234");
Question:
However, if have a List of values (account numbers). Is there a way to fetch them in 1 query? I tried passing a list of account numbers like this:
ofy.query(Customer.class).filter("account.number = ", myAccountNumberList);
But if fails saying:
java.lang.IllegalArgumentException: A collection of values is not allowed.
Thoughts?
filter("account.number IN", theList)
Note that IN just causes the GAE SDK to issue multiple queries for you, merging the results:
The IN operator also performs multiple queries, one for each item in the specified list, with all other filters the same and the IN filter replaced with an EQUAL filter. The results are merged, in the order of the items in the list. If a query has more than one IN filter, it is performed as multiple queries, one for each possible combination of values in the IN lists.
From https://developers.google.com/appengine/docs/java/datastore/queries