REST Web Service to consume MySQL DB - mysql

I'm building a REST WebService with JAX-RS and Tomcat to consume a MySQL Database.
I'm following this model:
#Path("/login")
public class Login {
String username;
String password;
// This method is called if POST is requested
#POST
#Produces(MediaType.APPLICATION_XML)
public String loginResponseXML(#FormParam("username") String user, #FormParam("password") String pass) {
//Connection to MySQL Database
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/sakila", "root","larcom");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("Select first_name, last_name From actor where first_name='" +
user + "' and last_name='" + pass + "'");
while (rs.next()){
System.out.println(rs.getString("first_name") + " " + rs.getString("last_name"));
username = rs.getString("first_name");
password = rs.getString("last_name");
}
}
catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
if (user.equals(username) && pass.equals(password)) {
return ("<?xml version=\"1.0\"?>" + "<auth>200" + "</auth>"); //Success
//return "Success!";
} else {
return ("<?xml version=\"1.0\"?>" + "<auth>404" + "</auth>"); //Damn
//return "Damn!";
}
}
}
I call this method with:
HttpPost httppost = new HttpPost("http://192.168.15.245:8080/org.jersey.andre/rest/login");
Now, my question is:
If I want to query the DB for another table I have to create a new class like Login and make the JDBC connection again?
A new class and a new JDBC connection for each class that make a query to the DB? Performance issues?
Hope you can understand.
Thanks in advance.

A few tips are in order here: Please isolate the DB based code to a "data layer" so to speak...only perform dispatching/business logic within your resource classes.
Now If you are querying a different table, you WILL have a different query! You could either use the same connection (bad) or create a new one and fire a different query(s).
Now whether each resource hits a different table or the same table with a different query depends on your choice of 'representation' for that resource. There is a reason a RDB schema has multiple tables and it's quite common you'll have a different query involving multiple tables or to mutually independent tables.
Performance issues: For 'fresh data' you ARE always going to hit the DB so to speak. If you want to optimize that either develop your own cache (extremely hard) or use approaches like memcached or ehcache to boost performance - before you decide to do that make sure you verify if it's worth it.
Are you going to be having about 1000 DB hits per second? You probably need some performance boosting/handling. Per day...maybe not. Per 2-3 days...YAGNI (You ain't gonna need it, so don't worry for now)
So, for every 'resource' that you design in your application (Login is NOT a resource: See related post: Why is form based authentication NOT considered RESTful?) choose the representation. It may involve different queries etc., for you to return json/xml/xhtml (whatever you choose). Each 'DB related call' should be isolated into it's own 'data layer' - I suggest go with Spring JDBC to make your life easier. It'll take the burden of JDBC plumbing off your shoulders so you can focus on creating your DAOs (Data Access Objects - a patter for Data Access classes. All DAOs logically belong in the data layer)
Hope this helps

Related

Safety of not catching SQL Exception

Let's say I have a program that puts email addresses into a database where the email attribute is a primary key.
If I have a duplicate email address, I could deal with it in two ways.
1) run a "select email from table" query. If the email is currently in there, don't add it.
2) don't check if email is in the table. catch(SQLException e), but don't print the stack trace, simply skip over it. This way, if I'm inserting a duplicate it effectively ignores it.
Granted with method 1, I'm only executing a simple select query (no joins or anything fancy) so performance isn't really a huge issue. But if I wanted to optimize performance, would method 2 be a viable, safe way of doing this?
So instead of running a "select ..." every time, I just add it.
Are there any safety issues with skipping over the exception?
Java Example (with JDBC):
try {
String sql = "insert into emails values(?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, email);
pstmt.execute();
return true;
}
catch(SQLException e) {
// e.printStackTrace(); // skip; don't print out error
return false;
}

Why there are many connections in this case (MySQLNonTransientConnectionException)

I am getting an exception using PreparedStatement to select.
Got an exception accessing TestCase data! null
Problem to connect.
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:
Too many connections
Here is my code:
public Integer getTypeByInputAndProblemId(String inputTestCase, Long problemId) {
String sql = "SELECT type FROM test_case where problem_id= ? and input= ?";
Integer type = 0;
try {
PreparedStatement ps = connection.prepareStatement(sql);
ps.setLong(1, problemId);
ps.setString(2, inputTestCase);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
type = new Integer(rs.getInt("type"));
}
rs.close();
ps.close();
} catch (Exception e) {
System.err.println("Got an exception accessing TestCase data! " + e.getMessage());
}
return type;
}
In line PreparedStatement ps = connection.prepareStatement(sql);
my problem is because connection sometimes is Null (the debug shows this).
I'm guessing this is because of many connections, but I don't know why this is happening.
I would like some help, please!
Yes, the issue happens because your server is reaching the max number of multiple connections accepted by your MySQL Server.
First, you need to see if you have a proper number configured in MySQL for multiple connections: max_connections. If this look low to you, you can increase this number in order to "fix" this issue.
Secondly, if the number makes sense, you're probably using more connections than you think you are. Probably because you're opening connections in your application and not closing them.
Check how many multiple connections your server have used so far.
show status like 'Max_used_connections';
This number is reset when you restart your database service.

A lot of database connections jsp

I made a Java Webapp with Spring and Hibernate where I have to take a lot of data from the database, but I have a problem, because the app is too slowly and I need to make it faster. I think that the higher problem is the amount of conexions that I do in each jsp file, and I don't know how to solve it. That conexions I think are all neccesary, but maybe I can modify some part of code to make it faster. I pass the data to the jsp via Hibernate and Spring in the model, but then in the jsp I have to make a connection with the database to take some more information that are in another class. For example, I have some players, and in the player I have the ID of their team, so I have to connect in the jsp to take the name of the team, because I only know the ID. I show you how I connect the app with the database:
try {
Class.forName("org.gjt.mm.mysql.Driver");
Connection conexion = DriverManager.getConnection("jdbc:mysql://localhost:3306/database", "user", "pwd");
if (!conexion.isClosed()) {
// La consulta
Statement st = conexion.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM entity");
while (rs.next()){
aaa = rs.getObject("aaa").toString();
}
// cierre de la conexion
conexion.close();
}
else
// Error en la conexion
out.println("fallo");
}
catch (Exception e) {
// Error en algun momento.
out.println("Excepcion "+e);
e.printStackTrace();
}
And I do this same a lot of times in the same jsp, even 10-15 times in the biggers jsp.
Can I open the conexion in the begin of the jsp and close the conexion in the end and put all the jsp code and html inside the conexion with the database to make only 1 connection?
And another doubt, in the same conection, if I have to do 2 querys, I do like this:
Statement st = conexion.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM entity");
while (rs.next()){
aaa = rs.getObject("aaa").toString();
}
st = conexion.createStatement();
rs = st.executeQuery("select * from entity2");
while (rs.next()){
bbb = rs.getObject("bbb").toString();
}
So, I create a new Statement for the query, is it neccesary? Or is enough if I create the Statement in the first query? And is this important in the speed of the page?
Does someone know what could I do to make my app faster?
Thanks!
One Statement st = conexion.createStatement(); is sufficient. Don't keep recreating the statement. You only have a limited amount of times you can call createStatement. If you need a nested query, make two statements, st and st2, but do not keep calling createStatement for the same variable.
Also, if you are going to use connections in scriptlets, you should at the very least make a class to put the actual connecting part in, i.e. Class.forName("org.gjt.mm.mysql.Driver"); Connection conexion = DriverManager.getConnection(....); and then just call that in the JSP. That way you don't have messy connection code in every JSP and when you have to change the server IP or username or something you won't have to go change a slew of JSPs.
And don't open the connection 10 times in one JSP. You wouldn't even want to do that in a Servlet. You would want to create a member variable that is of type Connection, open it, and keep it open and until the end.
If you are going to use scriptlets, your code should be at least this clean:
<%
//call a static method in a class you create to get the connection
Connection connection = Appname.dbclass.getConnection();
if(connection==null)
{
out.print("error connecting");
return;
}
Statement st = connection.createStatement();
ResultSet rs = null;
...
//do all your stuff
...
if(rs!=null)
{
try
{
rs.close();
}
catch(Exception ex){}
}
if(st!=null)
{
try
{
st.close();
}
catch(Exception ex){}
}
if(connection!=null)
{
try
{
connection.close();
}
catch(Exception ex){}
}
%>
Also, instead of doing "select * from table" followed by something like:
while (rs.next()){
aaa = rs.getObject("aaa").toString();
}
use a WHERE CLAUSE in your SQL to limit the number of rows returned to ONE, and also limit the fields you pull to the ones you need ("select aaa from table WHERE id=1") and then an if-statement:
if (rs.next()){
aaa = rs.getObject("aaa").toString();
}
With your present code, each time you go through the loop again, aaa is being overwritten with a new value. Its wasting a ton of processing time either doing nothing or ensuring that the result is completely wrong.

Mahout 0.7 Failed to get recommendation with a large data using MysqlJdbcDataModel

I am using Mahout to build an Item-based Cf recommendation engine.
I create an MahoutHelper class which has a constructor:
public MahoutHelper(String serverName, String user, String password,
String DatabaseName, String tableName) {
source = new MysqlConnectionPoolDataSource();
source.setServerName(serverName);
source.setUser(user);
source.setPassword(password);
source.setDatabaseName(DatabaseName);
source.setCachePreparedStatements(true);
source.setCachePrepStmts(true);
source.setCacheResultSetMetadata(true);
source.setAlwaysSendSetIsolation(true);
source.setElideSetAutoCommits(true);
DBmodel = new MySQLJDBCDataModel(source, tableName, "userId", "itemId",
"value", null);
similarity = new TanimotoCoefficientSimilarity(DBmodel);
}
and the recommend method is:
public List<RecommendedItem> recommendation() throws TasteException {
Recommender recommender = null;
recommender = new GenericItemBasedRecommender(DBmodel, similarity);
List<RecommendedItem> recommendations = null;
recommendations = recommender.recommend(userId, maxNum);
System.out.println("query completed");
return recommendations;
}
It's using datasource to build datamodel but the problem is that when mysql has only a few data (less than 100) the program works fine for me, while when the scale turns to be over 1,000,000, the program stacks at doing recommendation and never goes forward. I have no idea how it happens. By the way I used the same data to build a FileDataModel with a .dat file, and it takes only 2~3 second to complete analysis. I am confused.
Using the database directly will only work for tiny data sets, like maybe a hundred thousand data points. Beyond that the overhead of such data-intensive applications will never run quickly; a query takes thousands of SQL queries or more.
Instead you must load and re-load into memory. You can still pull from the database; look at ReloadFromJDBCDataModel as a wrapper.

SQL: 4 classes must reference one central class which provides database access

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 ;)