I need to open, read and insert items into an online SQLite database from an Android app. I know url, username and password. In JavaSE i would do the following:
Class.forName("com.mysql.jdbc.Driver");
Connection dbConnection = DriverManager.getConnection(URL, USER, PASSWORD);
I read that I can't do this in Android because there is not a JDBC Driver (there is a "SQLite.JDBCDriver" but it is not documented and not recommended).
So which is the easiest way? I asked to Google but it looks like he either doesn't know.
You should expose your datasource like this via an intermediary such as a Web Service for at least the following reasons:
someone has direct access to your datasource and can read, manipulate or destroy the data
abstraction; you can control the way in which the data is sent and how it's represented. Should the database tables/objects change, you'd only have to change the web service instead of force an update (in some cases)
JSON interaction is very well supported on Android out of the box, whereas JDBC isn't (for previously documented reasons)
I'm sure there are plenty of more reasons, but the above are the most prevalent in my mind.
There is no official support for JDBC on Android. There is a private SqlLite driver, but it's not recommended as it is unsupported and might go away in the future.
Read these:
Does Android Support JDBC
http://groups.google.com/group/android-developers/browse_thread/thread/cf3dea94d2f6243c
http://code.google.com/p/sqldroid/
So the recommended way is to not use internal (private) SQlite driver and instead create a REST layer on server through which you access data. This is a recommended way as it minimizes load on device side and also gives you opportunity to create authentication on the server side - having publicly accessible JDBC connection is a big no-no.
Related
I'm currently in the process of learning Java and swing and in doing so am trying to create a desktop app.
As part of this app I have set up a mysql database which the app is connected to, however I'm uncertain as to how this would work if I was to distribute the app for other users, how would I create a database that they are able to use on their system if they don't have mySQL installed or the database initiated.
Help with this would be much appreciated.
You should use embedded database. I would not recommend MySQL for commercial applications, because it is very expensive. Try to use HSQLDB - very fast and do not has memory leaks (at least I didn't noticed).
Here is an implementation example:
private static Connection conn;
/**
* Gets database connection.
*
* #return the database connection.
* #throws SQLException if database error occurs.
*/
public static Connection getConnection() throws SQLException {
if (conn == null || conn.isClosed()) {
conn = DriverManager.getConnection("jdbc:hsqldb:file:data", "somedb", "");
// conn.setAutoCommit(false);
}
return conn;
}
Make sure you have added hsqldb.jar file to your libraries.
I would suggest looking at SQLite instead of mySQL. It sounds like you need a standalone database that does not require a server to run. I've done both Java (and Android), Swing, as well as C#. I found that SQLite was the best solution to have a database on the different platforms and not install a server.
You have three choices:
Each desktop will have it's own, private database.
Each desktop talks to one, remote database server.
Each desktop talks to a web front-end to the remote database server.
"Option 3" is the most common scenario. One option is a "web app" (in which case you don't need the "Swing desktop" app at all). Another option is a "thick client Java applet". You can use Swing, most of the processing will be local ... but your Swing applet will communicate with the remote database for database access. You might consider a REST interface.
If you really want option 1 (app and database completely local to the desktop), then I'd definitely go with an embedded database. Sqlite is an excellent choice. In fact, Android uses Sqlite. HSQLDB or even MS-Access can also be good choices.
Regarding your problem, I'd ask if you're sharing the information of the database among the users of your application. I mean if you need the data centralized in one database the users can access through the desktop Swing application.
If so, then you'd need another application that would provide the information that is stored in the database (you can use Web Services at this point), then you'd just need to implement Web Service client code to interact with your database through the Swing application.
Now, if you want independent application with a database per user. Then you can go for many options such:
SQL Lite
H2 Database Engine
Apache Derby
HSQLDB
Hope this can give you orientation in what you need to implement.
Happy coding.
I have an SQLite Database on a webserver. I would like to access the database from a typical Java Desktop Application. Presently, I'm doing this thing...
Download the Database file to a local directory, perform the queries as necessary.
But, I'm unable to perform any update queries on this. How can I do this. [ On the actual database]
Another question is, to directly access the database from web in java (is this possible), make direct queries, updates anything etc,.
How can I achieve this type?
I've written code for connection of Java to SQLite and is working pretty fine, if the db file is in local directory. What changes or anything I have to do to establish a link to the file on webserver without having to download the database file.?
Thanks in advance...
CL. is right saying that if you need to access from desktop applications to a web database, SQLite is not an appropriate choice.
Using SQLite is fine in small web sites, applications where your data have to be accessed from and only from the web site itself; but if you need to access your data from - say - your desktop, without downloading the data file, you can't achieve that with SQLite and HTTP.
An appropriate choice for your web application would be MySQL or other client/server database, so that you could be able to connect to the database service from any place other than your web application, provided server access rules set permit that (e.g. firewalls, granted authentication, etc.).
In your usage scenario, you would be facing several orders of problems.
1) Security
You would be forced to violate the safety principle saying that database files must be protected from direct web exposure; in fact, to access your web SQLite database file from your desktop you would be forced to expose it directly, and this is wrong, as anyone would be able to download it and access your data, which by definition must be accessible just by you.
2) Updatability without downloading
Using HTTP to gain access to the database file can only lead to the requested resource download, because HTTP is a stateless protocol, so when you request GET or even POST access to the database, the web server would provide it to you in one solution, full stop.
In extreme synthesis, no chance to directly write back changes to the database file.
3) Updatability with downloading
You could download your file with a HTTP GET request, read data, make changes and the rest, but what if your online database changes in the meanwhile? Data consistency would be easily compromised.
There could be a way
If you give up using HTTP for your desktop application access to the database, then you could pick FTP (provided you have access credentials to the resource).
FTP lets you read data from and write data to files, so - on Linux - you could use FUSE to mount a remote FTP sharing and access it just like if it was connected to your local file system (see this article, for example).
In synthesis, you:
Create a mount point (i.e. a local directory) for FTP sharing
Use curlftpfs to link the remote FTP resource to your mount point
Access to this directory from your application as if it was a conventional directory
This way you could preserve security, keeping the database file from being exposed on the web, and you would be able to access it from your desktop application.
That said, please consider that concurrent access by several processes (desktop app + webserver instance) to a single database file could lead to problems (see this SO post to have an idea). Keep that in mind before architecting your solution.
Finally, in your usage scenario my suggestion is to program some server-side web service or REST interface that, under authentication, let you interact with the database file performing the key operations you need.
It is safe, reliable and "plastic" enough to let you do whatever you want.
EDIT:
MySQL is widely used for web sites or web applications, as it is fast, quite scalable and reasonably reliable. Activating MySQL server is a little bit OT on StackOverflow and quite long-winded to report, but in that case you could google around to find plenty of articles discussing such topic for your operating system of choice.
Then use MySQL JDBC driver to access the database from your Java desktop application.
If your idea is to stick with SQLite, though, you could basically prepare four web endpoints:
http://yourwebsite.com/select
http://yourwebsite.com/insert
http://yourwebsite.com/update
http://yourwebsite.com/delete
(Notice I specified "http", but you could consider moving to SSL encrypted http connection, a.k.a. "https", find details here and here. I don't know which webserver are you running, but still googling a little bit should point you to a good resource to properly configure https.)
Obviously you could add any endpoint you like for any kind of operation, even a more generic execute, but play my game just for a while.
Requests towards those endpoints are POST, and every endpoint receives proper parameters such as:
table name
fields
where clause
... and the like, but most important is security, so you have to remember 2 things:
1. Sign every request. You could achieve this defining a secret operation key (a string which is known to your client and you server but never travels in clear text), and using it in a hashing function to produce a digest which is sent together with other parameters as an incontrovertible proof for the server that that request it's receiving comes from a genuine source. This avoids you to send username and password in every request, which would introduce the problem of password encryption if you don't use https, and involves that the server has to be able to reconstruct the same signature for the same request using the same algorithm. (I flew over this thing at 400Mph, but the topic is too large to be correctly treated here. Anyways I hope this could point you in the right direction.)
2. Properly escape request parameters. "Sanitize" parameters someone calls it, and I think the metaphor is correct. Generally speaking this process involves some filtering operations performed by the server's endpoint, but it basically could be written as "use prepared statements for your queries". If you don't it could be likely that some malicious attacker injects SQL code in requests to exploit your server in some manner.
SQLite is an embedded database and assumes that the database file is directly accessible.
Your application is not an appropriate use of SQLite.
You should use a client/server database.
In any case, you should never make a database directly accessible on the internet;
the data should go through a web service.
i am writing an application in java and i want to enable it to access a mysql remote server.
my problem is that if the application have the user name and password someone can take them and use my db with a different software.
is there a way of preventing it ?
UPDATE
i found this workaround for connecting to a remote MySQL database from an android device.
you put a service in the middle. like a php page that code the data in JSON format which the android app gets via http.
here is the example i found :
Connecting to MySQL database
Having the username and password is designed specifically to grant access to the database. That's the whole point.
You could go to some extra lengths like restricting database connectivity to specific hosts, so at least your paying customers get access to the database and no else can access it, but your customers might choose to use different software to access the database. There's no way around it except licensing terms.
What you could do is run an intermediary program on your own hardware that connects to the database and restrict access to the database to software that is under your direct administrative control. Your program would validate all requests from software under control of your customers and allow the queries that you want to allow and refuse (and log) the queries you do not have to allow. (You do not need to send raw SQL data back and forth -- you can do any amount of processing on the data and queries.)
You can setup JDBC Data Source on your application server. Here you can see example for Oracle Glassfish.
So, your credential won't be used in your code/resources.
If you are saying that you have an application trying to access a MySQL remotely (not in the same box), then i think you need not worry, as the connection that will be established by your application codes will not expose the username and password when it is trying to authenticate and authorize itself to the MySQL server.
You can limit the access to the MySQL-server so that only certain IP-addresses or IP-ranges have access to it.
As a side note, make sure that the user you use in your application only has the needed permissions to the database. For example, the user might not need to be able to create or delete tables. You can even specify permissions for the user on table and column level.
I am making an Android application. Since it is so simple, I first thought I could simply eliminate the need for Java application on the server which acts as a middleware. I tried directly connecting to the database using the JDBC driver for MySQL but my program is crashing so I'm not sure if Android "supports" the JDBC driver for MySQL.
So I am thinking of how to implement the application. Basically the application writes some data from a remote MySQL database and retrieves some data from a remote MySQL database.
Do I connect to a Java server program using sockets (or some other method of communication)? Or could I implement a direct connection to the MySQL database from the client application?
I tried directly connecting to the
database using the JDBC driver for
MySQL but my program is crashing so
I'm not sure if Android "supports" the
JDBC driver for MySQL.
Never never never use a database driver across an Internet connection, for any database, for any platform, for any client, anywhere. That goes double for mobile. Database drivers are designed for LAN operations and are not designed for flaky/intermittent connections or high latency.
Do I connect to a Java server program
using sockets (or some other method of
communication)?
It doesn't have to be Java. It just has to be something designed for use over the Internet. As Mr. King's comment suggests, Web services have been used for this for much of the past decade. For Android, REST Web services are probably the easiest to consume, since there is no built-in support for SOAP or XML-RPC. But whether the Web service is implemented in Java, or PHP, or Perl, or SNOBOL, is up to you.
Well, OK, perhaps SNOBOL won't be a viable option. :-)
I know this might be a little late but as I ran into the same problem with a project at school I wanted to share my solution with you as you might profit out of my experiences.
Android is bad for Database-Operations so creating a normal Database-Controller wasn't a thing. Instead I created a Server in Java which handles all Database-related stuff and can also be extended (in my case I used a Feedback-function, too).
The Github-REPO is: https://github.com/Cedced-Bro/Public-Server You can check it out and this is open-source so you can use and contribute to it if you have more ideas to it.
To answer your question more properly: I would strongly suggest to NOT grant all users direct access to your DB as you can run into security issues with malicious users. This was the reason why I created this controller in the first place instead of just a PHP "forwarding"-server.
I've been searching and can't find an answer anywhere. I also haven't had time to try it out either.
Is it possible, using java in the Google App Engine (GAE), to connect to a remote database. Whether it MySql, SQLServer, etc. Will it be allowed to make calls outside of it's domain? Is it possible to even use the required libraries to make such a connection?
The closest thing that you will find is the Google Secure Data Connector. All connections outbound from GAE are HTTP based, so you're very unlikely to get a jdbc type connection to a database server (MySql, SqlServer, etc).
IMHO you can try to tunnel JDBC through HTTP. It is possible. For example here is free solution http://sourceforge.net/projects/sqlgateway/ and here commercial http://www.idssoftware.com/jdbcdrv.html :)
I do this all the time using a REST API on the server that contains the database. Depending on your needs (eg, do you need ad-hoc queries) you may want to choose a REST API with some flexibility.
There are quite a few simple REST-DB libraries around, such as http://phprestsql.sourceforge.net/
Though you may want to simply roll your own using http://www.playframework.org/ or http://guides.rubyonrails.org/getting_started.html#rest
Dont use HTTP for DB connections as it is less secure.
Use CLoud SQL instead (jdbc type connection, mysql like queries and drivers in jars)
getting started with cloud sql
an easy video for java + cloud sql + app engine