spring boot, jdbcTemplate, Java - java

I have a query that takes one column row from database and I want to set this data to my model. My model name is Pictures and my method is follow:
#Override
public Pictures getPictureList() throws Exception {
JdbcTemplate jdbc = new JdbcTemplate(datasource);
String sql= "select path from bakery.pictures where id=1";
Pictures pcList = jdbc.query(sql, new BeanPropertyRowMapper<Pictures>(Pictures.class));
return pcList;
}
This method returns "a query was Inferred to list".
How can I solve it?

Use JdbcTemplate.queryForObject() method to retrieve a single row by it's primary key.
Pictures p = jdbc.queryForObject(sql,
new BeanPropertyRowMapper<Pictures>(Pictures.class));
JdbcTemplate.query() will return multiple rows which makes little sense if you are querying by primary key.
List<Pictures> list = jdbc.query(sql,
new BeanPropertyRowMapper<Pictures>(Pictures.class));
Picture p = list.get(0);

Related

Dyamic table name for JPQL / Hibernate query

I've a database with many thousands of tables that have been (and continue to be) created with a naming strategy - one table per calendar day:
data_2010_01_01
data_2010_01_02
...
data_2020_01_01
All tables contain sensor data from the same system in the same shape. So a single entity (lets call it SensorRecord) will absolutely map to all tables.
I'd imagined something like this would work:
#Query(nativeQuery = true, value = "SELECT * FROM \"?1\"")
Collection<SensorRecord> findSensorDataForDate(String tableName);
But it does not, and reading around the topic seems to suggest I am on the wrong path. Most posts on dynamic naming seem to state explicitly that you need one entity per table, but generating thousands of duplicate entities also seems wrong.
How can I use JPA (JPQL?) to work with this data where the table name follows a naming convention and can be changed as part of the query?
Parameters are only allowed in the where clause.
You can create custom repository method returns collection of SensorRecord dto. No need to map so many entities. You should get List<Object []> as query result and manually create dto objects.
#Autowired
EntityManager entityManager;
public List<SensorRecord> findSensorDataForDate(LocalDate date) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy_MM_dd");
String tableName = "data_" + date.format(formatter);
Query query = entityManager.createNativeQuery(
"select t.first_column, t.second_column from " + tableName + " t");
List<Object[]> queryResults = query.getResultList();
List<SensorRecord> sensorRecords = new ArrayList<>();
for (Object[] row : queryResults) {
SensorRecord record = new SensorRecord();
record.setFirstParameter((Integer) row[0]);
record.setSecondParameter((String) row[1]);
sensorRecords.add(record);
}
return sensorRecords;
}
Could it be just syntax error?
This has worked for me:
#Query(value = "select * from job where job.locked = 1 and job.user = ?1", nativeQuery = true)
public List<JobDAO> getJobsForUser(#Param("user") String user);

How to include two parameters for jdbctemplate.batchUpdate(String sql, List<Object[]> batchArgs)?

I am trying to perform an UPDATE on a MySQL database where I update only one single column full of values corresponding to the correct index position. Here is my current code:
JdbcTemplate temp = new JdbcTemplate(sqlDataSource);
List<Map<String, Object>> results = temp.queryForList("SELECT last_name FROM actor");
List<Object[]> params = new ArrayList<Object[]>();
for (Map<String, Object> row : results) {
params.add(new Object[]{row.get("last_name"), row.get("actor_id")});
}
String sql = "UPDATE actor SET first_name= ? WHERE actor_id=?";
temp.batchUpdate(sql, params)
In this example, I am trying to update all first names in my table to the last names. My main question is how can I include a parameter for the "SET first_name = ?" as well as the WHERE condition "WHERE actor_id = ?" as well? Is this possible with JdbcTemplate?
I think a simple Google search can solve your problem(s).
If you just look up JdbcTemplate batchUpdate, it should guide you in the right direction.
With that said, have a look at these:
https://www.tutorialspoint.com/springjdbc/springjdbc_jdbctemplate
why spring jdbcTemplate batchUpdate insert row by row

Query not giving solution in DAO class

when i run my query in database visualizer its working perfectly, but i think there are some issues in syntax when i convert it in my DAO class method.
I want to get whole data against the name provided
In Visualizer:
SELECT first_name,last_name,nic,phone,email FROM x_hr_user where (first_name = 'Irum');
Now in Dao
public List<XHrUser> findXHrUserByNameInTable()
{
String name ="Irum";
Query query = em.createQuery("SELECT xHrNewUserObj.firstName,xHrNewUserObj.lastName, xHrNewUserObj.nic, xHrNewUserObj.phone, xHrNewUserObj.emil FROM XHrUser xHrNewUserObj where (xHrNewUserObj.firstName) = (name)");
List<XHrUser> list = query.getResultList();
return list;
}
Instead of showing single row, it displays whole data Table
Thank you
Your current query is not valid JPQL. It appears that you intended to insert the raw name string into your query, which could be done via a native query, but certainly is not desirable. Instead, use a named parameter in your JPQL query and then bind name to it.
String name = "Irum";
Query query = em.createQuery("SELECT x FROM XHrUser WHERE x.firstName = :name")
.setParameter("name", name);
List<XhrUser> list = query.getResultList();
You have to write query as below. where : is used for variable
Query query = em.createQuery("SELECT xHrNewUserObj.firstName,xHrNewUserObj.lastName, xHrNewUserObj.nic, xHrNewUserObj.phone, xHrNewUserObj.emil FROM XHrUser xHrNewUserObj where (xHrNewUserObj.firstName) = :name");

How to refresh Vaadin table related with SQLContainer using ComboBox?

I need help in a simple application based on Vaadin.
I need to have a table bound to SQL query results. SQL query has a parameter which value user chooses from combobox. What I need is to table be refreshed when user change the combobox value.
That is what I have ():
Table table;
JDBCConnectionPool pool;
String query = "select products.product_code, products.name as product_name, clients.client_code, clients.name as client_name from products, clients where products.client_id = clients.id";
FreeformQuery q = new FreeformQuery(query, pool);
SQLContainer container = new SQLContainer(q);
table.setContainerDataSource(container);
So, this simple code selects all data from products and clients tables and puts it to the table. But how can I add filtering by clients.client_id selected from combobox, for example? To implement next query:
select products.product_code, products.name as product_name, clients.client_code, clients.name as client_name from products, clients where products.client_id = clients.id where client_id = ?;
Thank you for your help.
You could add a Property.ValueChangeListener that would change your query parameters:
comboBox.addListener(new Property.ValueChangeListener() {
public void valueChange(ValueChangeEvent event) {
String customQuery = query.replace(":clientId", ((Client)(event.getProperty()).getId(), pks);
table.setContainerDataSource(new SQLContainer(new FreeformQuery(customQuery, pool)));
}
});
And the query would hold the following value: select products.product_code, products.name as product_name, clients.client_code, clients.name as client_name from products, clients where products.client_id = clients.id where client_id = :clientId
But be careful with query.replace, if Id is int there is nothing to worrier about, but if it is string, please addSlashes in order to avoid SQLInjection.

Using Spring Hibernate getHibernateTemplate().find to to select columns

I am using
List<USERS> user =
getHibernateTemplate().find("select uid, username,email from USERS");
to get three columns values from the users TABLE. But I can access no individual column value using the "user" object because the "user" type is an object type and I can't cast it to the USERS.
Is there any ways to use the "user" object and access individual columns value?
Why are you just querying selected columns - just get the whole row(s). Let me know if that helps.
If you are fetching only few columns, the hibernate template will return a list of object arrays.
Your example should look like this,
List<Object[]> userDetails =
getHibernateTemplate().find("select uid, username,email from USERS");
And you should know the first element is a integer and second, third are string and do cast on your own. This is very error prone ofcourse.
Thanks Nilesh and Sean for your suggestions. I always deal with the objects instead of individual columns. But this specific app works with other tables from another app which is not written in Java (That is why I am using USERS table not "User", because it is already created by another app) and is not using hibernate. I created a USERS class that implements UserDetails and has much less columns than the original app USERS table. When I get the whole object I get a formatting error that is why I tried using selected columns instead of the object.Anyhow I wrote this code and was able to get the individual columns:
List user=
getHibernateTemplate().find("select uid, username,email from USERS where uid<>0 AND obj_type=1");
List<USERS> l = new ArrayList<USERS>();
for (int i = 0; i < user.size(); i++) {
USERS du = new USERS();
Object[] obj = (Object[]) user.get(i);
Integer uid = (Integer) obj[0];
du.setUid(uid);
String username = (String) obj[1];
du.setUsername(username);
String email = (String) obj[2];
du.setEmail(email);
l.add(du);
}
My last question: isn't it more expensive to get the whole columns(the object) than getting the individuals ones?
Keep in mind it that...
getHibernateTemplate.find() method returns List of based on passed object.
Then after this you have to take List of Users then you have to separate all resulting object and after specified a object you can access attribute of it.
Its very easy..
If you have any query then tell me
I will try my best.
#Override
public Object findByNo(Object id) throws Exception {
List list = getHibernateTemplate().find(
"select book from Book book " +
"where book.id=?",id);
if (list.size() != 0) {
return list.get(0);
} else {
return new Book();
}
}
I'm guessing your db table is called USERS and the entity class is called User. If that is the case, then you should do something like this:
List<User> users = getHibernateTemplate().find("from User");
for(User user: users){
// you probably don't need the id, so I'll skip that
String email = user.getEmail();
String userName = user.getUserName();
// now do something with username and email address
}
If you use an ORM framework, deal with objects, not with Database Columns!
And about naming:
Java naming conventions suggest that a class name is in TitleCase (or more precisely UpperCamelCase), not UPPERCASE. Also, a class that represents a single user should be called User, not Users.
you can try something like this:
for (TemplateAttributes templateAttributes1 : templateAttributes) {
templateAttributes1.setTemplates(templates);
templateAttributes1.setCreateDate(new Date());
templateAttributes1.setCreateUser(ApplicationConstants.userName);
templateAttributes1.setLastModified(new Timestamp(new Date().getTime()));
templateAttributesNew.add(templateAttributes1);
}
templates.setTemplateAttributes(templateAttributesNew);
templates.setUpdateDate(new Date());
templates.setUpdateUser(ApplicationConstants.userName);
templates.setLastModified(new Timestamp(new Date().getTime()));
getHibernateTemplate().bulkUpdate("delete from TemplateAttributes where templateAttributePK.templates.id="+templates.getId());
getHibernateTemplate().update(templates);
Try this
List<USERS> user =(List<USERS>)(List<?>)
getHibernateTemplate().find("select uid, username,email from USERS");

Categories

Resources