I want to use autocomplete in inputTextArea. I am doing it using values from the database. I have words, digits, symbols(like #) stored in the database.
The problem is when I try typing in the textArea, the whole list of things appears. Instead, I just want only those options to come which matches the input written in the textArea, kind of autocomplete feature but it fetches values from a database.
Given below is the java code that I have written so far.
public class DbConnect {
public List<String> completeArea(String query1) {
ResultSet rs;
Statement st;
Connection con;
PreparedStatement pst;
List<String> result = new ArrayList<String>();
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost/company", "root", "");
try {
query1 = "select name from labels";
pst = con.prepareStatement(query1);
rs = pst.executeQuery();
while (rs.next()) {
result.add(rs.getString("name"));
}
} catch (Exception ex) {
System.out.println(ex);
}
} catch (Exception ex) {
System.out.println("error occured" + ex);
}
System.out.println("size is " + result.size());
return result;
}
I do not want to specify any particular letter for searching in the database, it should pick automatically when the user types in. Any help would do good. Thanks a lot.
In your example the query1 parameter of the completeArea method is the user input but you overwriting it with your query. Try with
public List<String> completeArea(String input) {
...
String query = "select name from labels where name like ?";
pst = con.prepareStatement(query);
pst.setString(1, input + "%");
...
}
Edited according to #Slaw comment. Thanks for the correction. :)
I would use <p:autoComplete /> instead of inputTextArea for this usecase.
You can find a good tutorial in the official PrimeFaces site.
Your query is
select name from labels
that will give all labels's name...
I do not want to specify any particular letter for searching in the database, it should pick automatically when the user types in. Any help would do good.
If you want some matching you must specify a condition
Related
I want to check that the username and data which is already in database is match with the user info or not. I have written some code but it doesn't select a row.
Here is my code:
public boolean iscorrect(String name , String pass){
boolean check=false;
openConnection();
Statement st =null;
ResultSet rs = null;
try{
st = conn.createStatement();
String q = "Select * from signup where email = '"+name+"'" ;
rs=st.executeQuery(q);
System.out.println(rs.getString(1)+" "+rs.getString(2));
if(rs.getString(1).equals(name) && rs.getString(2).equals(pass)){
check = true;
}
}catch(SQLException e){
e.printStackTrace();
}
return check;
}
You need to first call rs.next() to put the cursor at the first row of data. This will return false if there is no data.
In addition to that:
please use PreparedStatement and bind variables to avoid SQL injection
you could put the checks into the WHERE clause instead of loading the whole row
please don't store clear text passwords, use a cryptographic hash function
I'm working in report module, in order to do that I'm creating different stored procedures. I create the procedure with in parameters and then create a class to map the row (resultSet)
I think that's the best way to work arround performance and clarity.(what do you think about that?)
I'm using play framework and ebean orm (2.7.7)
I'm calling the store procedure and getting the resultSet, but I would like to use ebean in order to cast automaticly the row to model... other option is take the row-cell and cast it in a property but I'm trying to avoid it.
This is the current approach
Is this the best way to call an stored procedure?
Transaction tx = Ebean.beginTransaction();
String sql = "{CALL report(?, ?, ?, ?, ?, ?)}";
CallableStatement callableStatement = null;
try {
Connection dbConnection = tx.getConnection();
callableStatement = dbConnection.prepareCall(sql);
callableStatement.setInt(1, 3);
callableStatement.setInt(2, 5);
callableStatement.setInt(3, 2013);
callableStatement.setInt(4, 1);
callableStatement.setInt(5, 2014);
callableStatement.setInt(6, 5);
ResultSet rs = callableStatement.executeQuery(sql);
while (rs.next()) {
//HOW TO CONVER row -> model ?
}
Ebean.commitTransaction();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I've discarded RawSQL and Query because received an error
RuntimeException: Error parsing sql, can not find SELECT keyword in: xxxxx
Also I found other option... using CallableSql
String sql = "{call sp_order_mod(?,?)}";
CallableSql cs = Ebean.createCallableSql(sql);
cs.setParameter(1, "turbo");
cs.registerOut(2, Types.INTEGER);
Ebean.execute(cs);
// read the out parameter
Integer returnValue = (Integer) cs.getObject(2);
but in this case I need to return a ResultSet not simply parameter.
I'm going to share my own solution.
I get a class called ResultSetUtils.(you can google it some implementation)
I added a generic method in order to return a typed list from resultset
public static <T> List<T> populateInList(Class<T> c, final ResultSet rs) {
List<T> listTyped = new ArrayList<T>();
try {
if (rs != null) {
while (rs.next()) {
T o = c.newInstance();
// MAGIC LINE
populate(o, rs);
listTyped.add(o);
}
rs.close();
}
} catch (final Exception e) {
// TODO Auto-generated catch block
System.err.println(e.getMessage());
}
return listTyped;
}
This class to do the population use org.apache.commons.beanutils package
BeanUtils.populate(bean, propertiesRealName);
Using
private static void callingProcedureTest() {
Logger.debug("Init callingProcedureTest");
Transaction tx = Ebean.beginTransaction();
// String sql = "{CALL sp_report_test(3, 5, 2013, 1, 2014, 5)}";
String sql = "CALL sp_report_test(?, ?, ?, ?, ?, ?);";
try {
Connection dbConnection = tx.getConnection();
CallableStatement callableStatement = dbConnection.prepareCall(sql);
callableStatement.setInt(1, 3);
callableStatement.setInt(2, 5);
callableStatement.setInt(3, 2013);
callableStatement.setInt(4, 1);
callableStatement.setInt(5, 2014);
callableStatement.setInt(6, 5);
Logger.debug("SQL > " + sql);
ResultSet rs = callableStatement.executeQuery();
Class<ReportTestResult> c = ReportTestResult.class;
//************** MAGIC LINE, converting ResultSet to Model
List<ReportTestResult> listResult = ResultSetUtils.populateInList(c, rs);
for (ReportTestResult item : listResult) {
Logger.debug("item.firstName> " + item.firstName);
Logger.debug("item.lastName > " + item.lastName);
Logger.debug("item.year > " + item.year);
}
Ebean.commitTransaction();
} catch (Exception e) {
Ebean.rollbackTransaction();
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
Ebean.endTransaction();
}
}
Plus about architecture and implementation
For each report I'm going to create:
a Result class (eg ReportTestResult)
intention: represent a row of report | simple DTO
a Param class (eg ReportTestParam),
intention: represent the parameters (inputs / ouputs), filters of the report
This class should implements
public interface ReportParam {
public int countParameteres();
public void setParametersInCallableStatement(CallableStatement callableStatement) throws SQLException;
}
a Report class (eg ReportTestReport) this class should extends ReportBase
intention: Knows the stored procedure's name, parameters and dto result
public class ReportTestReport extends ReportBase<ReportTestResult, ReportTestParam> {
#Override
protected String getProcedureName() {
return STORED_NAME;
}
}
many Adapters...
Each report could displayed in different charts, In this case I'm using HighCharts. Order to arrange it, I'm creating different adapters to do that.
EG:
class ReportTestHighChartsAdapter
intention: convert a list of ReportTestResult to series and configure different options of report (eg, title, xAxis etc)
public OptionsHC buildColumnReportV1(){
OptionsHC optionChart = new OptionsHC();
optionChart.chart = new ChartHC("column");
this.setTitle(optionChart);
optionChart.yAxis = new AxisHC(new TitleHC("Fruit eaten"));
.....
return optionChart;
}
OptionsHC is a class that represent option obj in the HighCharts framework.
The final step is converting OptionHC to Json and use it in JavaScript (common use of highCharts)
What's ReportBase?
ReportBase class has the strategy to implements the final called to DB, also manage the transaction
public class ReportTestReport extends ReportBase<ReportTestResult, ReportTestParam> {
...
protected List<TResult> execute(Class<TResult> classT) {
List<TResult> resultDTO = null;
CallableStatement callableStatement = null;
Logger.debug("Running procedure> " + this.getProcedureName());
Transaction tx = Ebean.beginTransaction();
String sql = ProcedureBuilder.build(this.getProcedureName(), this.countParameters());
Logger.debug("SQL > " + sql);
try {
Connection dbConnection = tx.getConnection();
callableStatement = dbConnection.prepareCall(sql);
this.getFilter().setParametersInCallableStatement(callableStatement);
ResultSet rs = callableStatement.executeQuery();
resultDTO = ResultSetUtils.populateInList(classT, rs);
Ebean.commitTransaction();
Logger.debug("commitTransaction > " + sql);
} catch (Exception e) {
Ebean.rollbackTransaction();
Logger.debug("rollbackTransaction > " + sql);
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
Ebean.endTransaction();
}
return resultDTO;
}
...
}
Currently the support for stored procedures in Ebean is not orientated to what you are trying to do. Hence you are not going to get much joy from using CallableSql or RawSql.
>> a class to map the row (resultSet) I think that's the best way to work around performance and clarity
Yes, I can understand your motivation.
>> How to convert ResultSet into model
Currently there is no good solution. The best solution would be to enhance RawSql so that you can set a ResultSet onto it. One of the things RawSql does is provide the mapping of resultSet columns to model properties and that is what Ebean needs internally. The enhancement/code change would be to be able to set a resultSet onto the RawSql object ... and get Ebean internally to skip the creation of the resultSet ( preparedStatement, binding parameters and executeQuery()). In terms of Ebean internals this is all done in the CQuery.prepareBindExecuteQueryWithOption() method. That is, if the RawSql has already provided a resultSet skip those things.
The big benefit of doing this rather than just rolling your own row -> model mapping code is that the resulting beans would all still have lazy loading / partial object knowledge etc. They would behave exactly like any other beans that Ebean builds as part of it query mechanism.
So that said, I'm personally away for a week ... so you aren't going to hear back from me until after that. If you want to get into it yourself then internally CQuery.prepareBindExecuteQueryWithOption() is the code you will need to modify.
If you have been following the ebean google group you'll know that but just in case you have not been note that the Model and Finder objects from Play have been incorporated into Ebean just in the last week. This helps both projects ... reduces confusion etc. The Ebean source in github master is at 4.0.4 and the bytecode enhancement in 4.x is different and I don't believe supported in Play.
I'm basically going offline for a week now so I'll look back into this after that.
Cheers, Rob.
What the hey does this MySql error message mean?
java.sql.SQLException: boo!
springframework.dao.TransientDataAccessResourceException: CallableStatementCallback; SQL [{call sp_MyStoredProc(?, ?, ?)}]; boo!
It's not particularly meaningful that's for sure. Has anybody come across this and is able to translate to less lazy~developer~ish...?
I am accessing via org.springframework.jdbc.object.StoredProcedure
I am using org.springframework.jdbc-3.1.3
#Update
The offending lines are in CallableStatetement.java (2269-2271)
if (!found) {
throw SQLError.createSQLException("boo!", "S1000", this.connection.getExceptionInterceptor());`
}
Attching the sources for mysql-connector-java-5.1.18.jar and tracing though the code reveal that the correct message should be along the lines of 'mismatch between declared and actual parameters' or similar.
Indeed correctly declaring my output parameter
declareParameter(new SqlOutParameter("output", Types.INTEGER));
rather than
declareParameter(new SqlParameter("output", Types.INTEGER));
fixed my problem. But a more meaningful error message would have saved precious time. I shall make this suggestion to the MySql Connector/J Development team.
As stated in the update to the question this is commonly caused by incorrectly using a CallableStatement. For example:
Stored Procedure uses 2 parameters, one in and one out:
CREATE DEFINER=`example`#`localhost` PROCEDURE `sp_getSensorLocation`(IN in_id VARCHAR(128), OUT loc VARCHAR(128))
BEGIN
SELECT LOCATION INTO loc FROM table.SENSORS
WHERE ID = in_id;
END
but the call to it only uses 1:
private String getSensorLocation(String sensorID) {
String location = "";
Connection c = dbr.getConnection();
String prepStatement = "{ call sp_getSensorLocation(?) } ";
try {
callableStatement cs = c.prepareCall(prepStatement);
cs.setString(1, sensorID);
ResultSet rs = cs.executeQuery();
if (rs.next()) {
location = rs.getString(1);
}
} catch (SQLException ex) {
LOG.error("Error:", ex);
}
dbr.closeConnection(c, rs, cs);
return location;
}
When the correct code is really:
private String getSensorLocation(String sensorID) {
String location = "";
Connection c = dbr.getConnection();
String prepStatement = "{ call sp_getSensorLocation(?, ?) } ";
try {
CallableStatement cs = c.prepareCall(prepStatement);
cs.setString(1, sensorID);
cs.execute();
location = cs.getString(2);
} catch (SQLException ex) {
LOG.error("Error:", ex);
}
dbr.closeConnection(c, rs, cs);
return location;
}
Notice I also changed to cs.execute as I don't expect a result set and would have issues with this as well (the example is taken from someone else's code I'm fixing, the joys -_-)
I want to make several entries into a MySQL database. Because Some of the tables reference others via foreign key I have to get back the inserted ID to inject them in my next statements.
I have 4 classes:
LodgerFormTest
RentForm
RentObject
House
and the class which inserts the MySQL statements into the db: sql_statements
When I want to send a SQL statement I am getting a nullPointer Exception!
The Action listener of the House-class (this is the first sql-statement I have to send) looks like this:
saveButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("saveButton");
// sql_statements statements = new sql_statements();
sql_statements.performHouse(strasse.getText(), plz.getText(), ort.getText());
mainmenu.create();
rentnerFrame.dispose();
}
});
all methods and variables I am using in sql_statements are static! Therefore I am not instantiating an object.
here is the method "performHouse" in sql_statements
public static void performHouse(String strasse, String plz, String ort) {
String sql = "insert into haus(strasse, plz, ort) values (?,?,?)";
System.out.println(sql);
try{
ps = connect.prepareStatement(sql, ps.RETURN_GENERATED_KEYS);
ps.setString(1, strasse);
ps.setString(2, plz);
ps.setString(3, ort);
ps.execute();
rs = ps.getGeneratedKeys();
if(rs != null && rs.next()) {
// Retrieve the auto generated key(s).
key_idhaus = rs.getLong(1);
System.out.println("idhaus: " + key_idhaus);
}
}catch(Exception ex){
System.out.println(ex);
}
} // close performHouse-methode
I cant debug because I get a "Source not found." error in the debug view.
Can anybody help please?
okay I just wanted to finish the task so I implemented a solution which surely is all but not OO:
I implemented redundant code into all of the 4 classes and every class implements their own sql statements. quick and dirty ;)
hello guys i am try to validate username from the database with the username that the user entered in the html from, assume
un//be the variable where username entered now from html form is stored
now how to retrieve all the columns of the uname from user table
uname //column name in mysql for usernames
user //table name in mysql
and check weather the username i.e,un entered now is present or not in the database
i am using
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/mebps","root","admin");
Statement stmt = (Statement) con.createStatement();
ResultSet rs = stmt.executeQuery("select un from userinfo");
while(rs.next())
{
if(rs.getString("uname") == un)
{
out.println("user is present");
}
}
There are at least two major mistakes:
You're comparing string instances by == instead of comparing their values by equals() method. The proper line would be if (rs.getString("uname").equals(un)).
You're not letting the DB do the job of returning the right row, instead you're copying the entire DB table into Java's memory and doing the comparison in Java. This is very inefficient. Make use of SQL powers the smart way so that it always returns exactly the information you need. There's for example a WHERE clause.
On an unrelated note, you seem not to be closing DB resources properly after use. This will result in resource leaking which is also a bad idea as it may cause your application to crash on long term. Further, the column name uname and un are not the same. But I'll assume it to be careless oversimplifying of the example.
Here's a minor rewrite:
public boolean exist(String username) throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
boolean exist = false;
try {
connection = database.getConnection();
statement = connection.prepareStatement("SELECT uname FROM userinfo WHERE uname=?");
statement.setString(1, username);
resultSet = statement.executeQuery();
exist = resultSet.next();
} finally {
if (resultSet != null) try { resultSet.close(); } catch (SQLException ignore) {}
if (statement != null) try { statement.close(); } catch (SQLException ignore) {}
if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
}
return exist;
}
You see, if there's a match, then it returns true (at least one record), otherwise false (no one record). No need to copy the entire table into Java's memory and crawl through it in Java.
Last but not least, this code doesn't belong in a JSP file, but in a normal Java class, starting with a servlet. See also our servlets wiki page to learn more about it.