I am trying to get the last ID inserted on the Java Derby DataBase.
This is a little program that i did, but i think that could be better ways to do that:
Query queryUsuarios = em.createNamedQuery("Usuario.findAll");
List<Usuario> listUsuario = queryUsuarios.getResultList();
int i=0;
for (i = 0; i < listUsuario.size(); i++) {
Usuario verUsuario = em.find(Usuario.class, i);
if(verUsuario != null) {
System.out.println(i+")"+verUsuario.getNombres());
}
}System.out.println("The last ID is "+i);
The main question is, there is a better and more secure way to do this?. Because i think on this way i could get errors in the future...
Thank you!.
You can do it using LIMIT and order by.Check below:
SELECT * FROM `table_name` ORDER BY `table_id` desc LIMIT 1;
Related
I have a select SQL that may get many rows of data.
And I only want the first 5 rows.
Besides adding rownums = 5 or adding statement.setMaxRows(5).
Can I get the result from using java coding?
Thanks.
I tried for loop and while(rs.next() && i < 5). all of them does not work.
try (Connection connection = abc.getConnection();
PreparedStatement statement = connection.prepareStatement(sql))
{
statement.setString(1,idNum);
ResultSet rs = statement.executeQuery();
for (int i = 0; i < 5; i++) {
while (rs.next()) {
itemList.add(rs.getString("idName"));
}
}
}
It shows all of the result in the itemList from the select SQL.
Currently, a single iteration of your loop exhausts the whole resultset.
You may want to add up end conditions like :
for (int i = 0; i < 5 && rs.next(); i++) {
itemList.add(rs.getString("idName"));
}
Note that your attempt with while(rs.next() && i < 5) should also work, you were probably just missing the increment of i .
You can read only the first 5 rows from the resultSet on the client side, but ideally you should be limiting number of rows returned by the database. Use limit 5 in the query.
This will avoid a lot of unnecessary work needed to return those extra rows from the database to client.
Your query is responsible to fetch data from DB , so better to control retrieve rows from db itself, this will avoid your java code checks. use limit 5 in your query based on your requirements.
This is not the rare question on the net, but I does a few optimization work with MySQL server for solve this problem and did not get results. So at first I use maven's package mysql:mysql-connector-java:6.0.6.
I try just to run this code:
try {
mysqlConnection = DriverManager.getConnection(DatabaseUtils.mysqlUrl, DatabaseUtils.mysqlUser, DatabaseUtils.mysqlPassword);
PreparedStatement valuesStatement = "SELECT * FROM `test` ORDER BY `id`"
ResultSet cursor = valuesStatement.executeQuery();
double value = 0;
if (cursor.next())
value = cursor.getDouble("value");
} catch (SQLException sqlEx) {
sqlEx.printStackTrace();
} finally {
cursor.close();
pricesStatement.close();
}
I have a lot records in the table. It's about million but every day add about thousand records. So I was very surprised when this simple example executed 30 seconds. I googled my problem and I find only "using pool", "tune mysql server", "try to EXPLAIN SELECT". But I've noticed that execution time related with rows count. So I looked into driver's code and found that:
TextResultsetReader::read():
while(true) {
if(row == null) {
rows = new ResultsetRowsStatic(rowList, cdef);
break;
}
if(maxRows == -1 || rowList.size() < maxRows) {
rowList.add(row);
}
row = (ResultsetRow)this.protocol.read(ResultsetRow.class, trf);
}
This means that even if I want to fetch only one row driver fetches all queried rows and get me first of it. Manuals suggest to use "setFetchSize" for fetching only n records. But it doesn't work. Driver code fetching all data anyway. So then I found that there is two recordsets: ResultRowsStatic and ResultSetStreaming. Second seems to be fetching data only when I need query it. How to use ResultRowsStreaming? I found it only into code. Parameter "fetchSize" must to equal -2147483648. I did try and it worked! Execution time of "executeQuery()" now if about 0.0007 sec. It's very fast for me. But wait.. My script anyway takes 30 seconds. Why? I debugged code after executing query. There's only two "close" methods after that. What's can go wrong? And that's true, "cursor.close()" takes the rest of time. I looked into library code again and reached ResultsetRowsStreaming::close():
boolean hadMore = false;
int howMuchMore = 0;
synchronized(mutex) {
while(this.next() != null) {
hadMore = true;
++howMuchMore;
if(howMuchMore % 100 == 0) {
Thread.yield();
}
}
if(conn != null) {
if(!((Boolean)this.protocol.getPropertySet().getBooleanReadableProperty("clobberStreamingResults").getValue()).booleanValue() && ((Integer)this.protocol.getPropertySet().getIntegerReadableProperty("netTimeoutForStreamingResults").getValue()).intValue() > 0) {
int oldValue = this.protocol.getServerSession().getServerVariable("net_write_timeout", 60);
this.protocol.clearInputStream();
try {
this.protocol.sqlQueryDirect((StatementImpl)null, "SET net_write_timeout=" + oldValue, (String)this.protocol.getPropertySet().getStringReadableProperty("characterEncoding").getValue(), (PacketPayload)null, -1, false, (String)null, (ColumnDefinition)null, (GetProfilerEventHandlerInstanceFunction)null, this.resultSetFactory);
} catch (Exception var9) {
throw ExceptionFactory.createException(var9.getMessage(), var9, this.exceptionInterceptor);
}
}
if(((Boolean)this.protocol.getPropertySet().getBooleanReadableProperty("useUsageAdvisor").getValue()).booleanValue() && hadMore) {
ProfilerEventHandler eventSink = ProfilerEventHandlerFactory.getInstance(conn.getSession());
eventSink.consumeEvent(new ProfilerEventImpl(0, "", this.owner.getCurrentCatalog(), this.owner.getConnectionId(), this.owner.getOwningStatementId(), -1, System.currentTimeMillis(), 0L, Constants.MILLIS_I18N, (String)null, (String)null, Messages.getString("RowDataDynamic.2") + howMuchMore + Messages.getString("RowDataDynamic.3") + Messages.getString("RowDataDynamic.4") + Messages.getString("RowDataDynamic.5") + Messages.getString("RowDataDynamic.6") + this.owner.getPointOfOrigin()));
}
}
}
This code unconditionally fetching all the rest of data only for logging how many records I did not fetched. Really weird. And it would be justified if logger was attached. But in my case this code counting unfetched rows and in 30 seconds and... do nothing with it. And this proble I cannot fix because there's not parameter which can tell code not to count rows.
Now I don't know what to do next. Query time is very slow for me. For example mysql driver for php execute this query in 0.0004-0.001 seconds.
So people who using mysql-connector for Java, tell me please have you got these problems? If not, could you post any examples what should I do to bypass the above problems? Maybe you use another connectors. So tell me please, what to do?
Your SQL query says
SELECT * FROM test ORDER BY id
You are, with that query, instructing your MySQL server to serialize every column of every row of your test table and send it to your Java program. So, MySQL obeys. You have a large table. So your instruction to MySQL takes time. And yes, the more rows in your table the longer it takes. This is not a problem with JDBC or the driver; it's a problem with the SQL you're using.
It seems from your sample code that you want one column -- named value -- from one row -- the first one -- in your table. You could accomplish that using this SQL statement:
SELECT value FROM test ORDER BY id LIMIT 1
If your id column is your table's primary key, this will be fast.
The whole point of SQL is to allow your tables to contain so many rows that it's unreasonable to fetch them all into your Java (or other) program in a short amount of time. That's why SQL has WHERE and LIMIT clauses.
I am trying to get a list of all users where the access level is between 0 and 10. The developer users have am higher access level, because they should be able change very critical data.
The current version returns all users.
List<UserType> userList = UserType.find.all();
Is it possible to do like that:
select *
from user
where access_level >= 0
and
access_level <=10
;
The comparision value is:
UserType.getAccessLevel
The table is called 'acces_level' in the database.
I'm not at home therefore I'm not able to test it but I'm sure you will need ge()
List<UserType> userList = UserType.find.where().ge("access_level", 10).findList();
I think it's a combination of Junction and greater than equals to
Having a quick glance at the JPA examples for Playframework, it seems that this is perfectly within the realm of possibility.
To express it, you'd need to do something like this:
List<UserType> userList = UserType.find("access_level >= 0 AND access_level < 10");
This is a version witch works, but I want to know how it works with the find Method.
for(int i = 0; i< userList.size(); i++){
if(userList.get(i).getAccessLevel() > 10){
userList.remove(i);
i--;
}
}
i am trying to make a loop for all the selected ID, but unfortunately it does not working. only the the 1st Id entered was accepted and do not loop on the next value in the arraylist. here's my code. I don't know where I missed something. Thanks!
if (arraylistSelectedConsumerIds != null)
{
for (int i = 0; i <arraylistSelectedConsumerIds.size(); i++)
ConsumerId = arraylistSelectedConsumerIds.get(i);
databaseAdapter.updateEmailmark(ConsumerId);
Toast.makeText(AdminActivity.this,"consumer id" + ConsumerId, Toast.LENGTH_LONG).show();
}
Looks like a basic syntax error to me.
if (arraylistSelectedConsumerIds != null) {
for (int i = 0; i <arraylistSelectedConsumerIds.size(); i++) {
ConsumerId = arraylistSelectedConsumerIds.get(i);
databaseAdapter.updateEmailmark(ConsumerId);
Toast.makeText(AdminActivity.this,"consumer id" + ConsumerId, Toast.LENGTH_LONG).show();
}
}
Just add the curly braces for the loop like I did here and make sure you use your IDE to check for further syntax errors.
You should to debug it. Maybe arraylistSelectedConsumerIds is linked to databaseAdapter, and size changed when you call updateEmailmark. If that's the case, you should store the value first. For example:
int listSize = arraylistSelectedConsumerIds.size();
for(int i = 0; i <listSize; i++)
I'm having a problem with a java OutOfMemoryError. The program basically looks at mysql tables that are running on mysql workbench, and queries them to get out certain information, and then puts them in CSV files.
The program works just fine with a smaller data set, but once I use a larger data set (hours of logging information as opposed to perhaps 40 minutes) I get this error, which to me says that the problem comes from having a huge data set and the information not being handled too well by the program. Or it not being possible to handle this amount of data in the way that I have.
Setting Java VM arguments to -xmx1024m worked for a slightly larger data set but i need it to handle even bigger ones but it gives the error.
Here is the method which I am quite sure is the cause of the program somewhere:
// CSV is csvwriter (external lib), sment are Statements, rs is a ResultSet
public void pidsforlog() throws IOException
{
String[] procs;
int count = 0;
String temp = "";
System.out.println("Commence getting PID's out of Log");
try {
sment = con.createStatement();
sment2 = con.createStatement();
String query1a = "SELECT * FROM log, cpuinfo, memoryinfo";
rs = sment.executeQuery(query1a);
procs = new String[countThrough(rs)];
// SIMPLY GETS UNIQUE PROCESSES OUT OF TABLES AND STORES IN ARRAY
while (rs.next()) {
temp = rs.getString("Process");
if(Arrays.asList(procs).contains(temp)) {
} else {
procs[count] = temp;
count++;
}
}
// BELIEVE THE PROBLEM LIES BELOW HERE. SIZE OF THE RESULTSET TOO BIG?
for(int i = 0; i < procs.length; i++) {
if(procs[i] == null) {
} else {
String query = "SELECT DISTINCT * FROM log, cpuinfo, memoryinfo WHERE log.Process = " + "'" + procs[i] + "'" + " AND cpuinfo.Process = " + "'" + procs[i] + "'" + " AND memoryinfo.Process = " + "'" + procs[i] + "' AND log.Timestamp = cpuinfo.Timestamp = memoryinfo.Timestamp";
System.out.println(query);
rs = sment.executeQuery(query);
writer = new CSVWriter(new FileWriter(procs[i] + ".csv"), ',');
writer.writeAll(rs, true);
writer.flush();
}
}
writer.close();
} catch (SQLException e) {
notify("Error pidslog", e);
}
}; // end of method
Please feel free to ask if you want source code or more information as I'm desperate to get this fixed!
Thanks.
SELECT * FROM log, cpuinfo, memoryinfo will sure give a huge result set. It will give a cartesian product of all rows in all 3 tables.
Without seeing the table structure (or knowing the desired result) it's hard to pinpoint a solution, but I suspect that you either want some kind of join conditions to limit the result set, or use a UNION a'la;
SELECT Process FROM log
UNION
SELECT Process FROM cpuinfo
UNION
SELECT Process FROM memoryinfo
...which will just give you all distinct values for Process in all 3 tables.
Your second SQL statement also looks a bit strange;
SELECT DISTINCT *
FROM log, cpuinfo, memoryinfo
WHERE log.Process = #param1
AND cpuinfo.Process = #param1
AND memoryinfo.Process = #param1
AND log.Timestamp = cpuinfo.Timestamp = memoryinfo.Timestamp
Looks like you're trying to select from all 3 logs simultaneously, but ending up with another cartesian product. Are you sure you're getting the result set you're expecting?
You could limit the result returned by your SQL queryes with the LIMIT estatementet.
For example:
SELECT * FROM `your_table` LIMIT 100
This will return the first 100 results
SELECT * FROM `your_table` LIMIT 100, 200
This will return results from 100 to 200
Obviously you can iterate with those values so you get to all the elements on the data base no matter how many there are.
I think your are loading too many data at the same in the memory. try to use offset and limit in your sql statement so that you can avoid this problem
Your Java code is doing things that the database could do more efficiently. From query1a, it looks like all you really want is the unique processes. select distinct Process from ... should be sufficient to do that.
Then, think carefully about what table or tables are needed in that query. Do you really need log, cpuinfo, and memoryinfo? As Joachim Isaksson mentioned, this is going to return the Cartesian product of those three tables, giving you x * y * z rows (where x, y, and z are the row counts in each of those three tables) and a + b + c columns (where a, b, and c are the column counts in each of the tables). I doubt that's what you want or need. I assume you could get those unique processes from one table, or a union (rather than join) of the three tables.
Lastly, your second loop and query are essentially doing a join, something again better and more efficiently left to the database.
Like others said, fetching the data in smaller chunks might resolve the issue.
This is one of the other threads in stackoverflow that talks about this issue:
How to read all rows from huge table?