CharSet for MS Access '97 DB using UCanAccess - ms-access

Hey I am reading a database using ucanaccess-5.0.0.
The database is propably < Access 2000, since it's not UTF-8.
It seems like I have to setup a charset. I tried this using the charset parameter in the url:
jdbc:ucanaccess://${databaseFile.absolutePath};memory=false;charSet=Cp1250
It seems to be ignored, since I still don't get my german umlauts out of the DB.
What can I do about it?

Working Solution:
class DatabaseOpener : JackcessOpenerInterface {
override fun open(fl: File, pwd: String?): Database {
return DatabaseBuilder.open(fl).apply {
this.charset = charset("Cp1252")
}
}
}
// URL
"jdbc:ucanaccess://<path-to-mdb-file>;memory=false;jackcessOpener=${DatabaseOpener::class.qualifiedName!!}"

on java:
public class CryptCodecOpener implements JackcessOpenerInterface {
public Database open(File fl,String pwd) throws IOException {
DatabaseBuilder dbd =new DatabaseBuilder(fl);
dbd.setCodecProvider(new CryptCodecProvider(pwd));
dbd.setCharset(Charset.forName("WINDOWS-1251"));
return dbd.open();
}
public class MainTest {
public static void main(String[] args) throws IOException {
String connUrl = "jdbc:ucanaccess://C:/GATE/Server/config.mdb";
try {
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
Connection conn =
DriverManager.getConnection(connUrl + ";jackcessOpener=com.example.demo.CryptCodecOpener");
Statement st = conn.createStatement();
String sql = "SELECT * FROM Users LIMIT 10";
ResultSet rs = st.executeQuery(sql);
while (rs.next()) {
System.out.println("\n" + rs.getString(1) + "\t" + rs.getString(3));
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
maven:
<dependency>
<groupId>net.sf.ucanaccess</groupId>
<artifactId>ucanaccess</artifactId>
<version>5.0.1</version>
</dependency>
<dependency>
<groupId>com.healthmarketscience.jackcess</groupId>
<artifactId>jackcess-encrypt</artifactId>
<version>3.0.0</version>
</dependency>

Related

JDBC executeQuery returns empty ResultSet even though there is data?

import java.sql.*;
public class Driver {
public static void main(String[] args) {
try {
Connection myConn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb?autoReconnect=true&useSSL=false",
"root", "password");
Statement myStamement = myConn.createStatement();
ResultSet myRs = myStamement.executeQuery("SELECT * FROM table1");
while(myRs.next()) {
System.out.println("I GOT SOMETHING FROM DATABASE");
System.out.println(myRs.getString("id"));
}
}
catch (Exception exc) {
exc.printStackTrace();
}
}
}
and I have setup my SQL server and can see the same query in mySQL workbench here:
enter image description here
It doesn't give me an error connecting to the database else it would go to catch.
It returns an empty ResultSet else it would go into while loop once.
There is data in my database that I can see from using same command in photo photo.

What's wrong with Google endpoints -- Cloud SQL connection?

I'm trying to connect from a Google Endpoints server to a Google Cloud SQL server. I'm modifying the Greetings.getGreeting() method in this tutorial:
https://cloud.google.com/appengine/docs/java/endpoints/getstarted/backend/helloendpoints
to call the Cloud mysql database as demonstrated in this tutorial (see doGet method):
https://cloud.google.com/appengine/docs/java/cloud-sql/#enable_connector_j
I have made sure that I can connect to the database from my machine mysql client. The database instance "simple" has a single table "simpletable" who's rows hold an entityID and a string. (But I'm not able to connect, so that's not too important yet.)
This is my endpoints code:
package com.example.helloendpoints;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.response.NotFoundException;
import com.google.appengine.api.users.User;
import java.sql.*;
import java.util.ArrayList;
import javax.inject.Named;
/**
* Defines v1 of a helloworld API, which provides simple "greeting" methods.
*/
#Api(
name = "helloworld",
version = "v1",
scopes = {Constants.EMAIL_SCOPE},
clientIds = {Constants.WEB_CLIENT_ID,
Constants.ANDROID_CLIENT_ID,
Constants.IOS_CLIENT_ID,
Constants.API_EXPLORER_CLIENT_ID},
audiences = {Constants.ANDROID_AUDIENCE}
)
public class Greetings {
public static ArrayList<HelloGreeting> greetings = new ArrayList<HelloGreeting>();
static {
greetings.add(new HelloGreeting("hello world!"));
greetings.add(new HelloGreeting("goodbye world!"));
}
public HelloGreeting getGreeting(#Named("id") Integer id) throws NotFoundException {
// pair to use when running local endpoint server
String urlFromDev = "jdbc:mysql://173.194.XXX.90:3306/simple?user=root";
String classForNameFromDev = "com.mysql.jdbc.Driver";
// pair to use when running cloud endpoint server
String classForNameFromCloud = "com.mysql.jdbc.GoogleDriver";
String urlFromCloud = "jdbc:google:mysql://"
+ Constants.PROJECT_ID + ":"
+ Constants.CLOUD_SQL_INSTANCE_NAME +"/"
+ Constants.DATABASE_NAME + "?user=root";
HelloGreeting helloGreeting = new HelloGreeting();
try {
Class.forName(classForNameFromDev);
// Class.forName(classForNameFromCloud);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
Connection connection = DriverManager.getConnection(urlFromDev);
// Connection connection = DriverManager.getConnection(urlFromCloud);
try {
String statement = "Select simplestring from simpletable where entryID = ?";
PreparedStatement preparedStatement = connection.prepareStatement(statement);
preparedStatement.setInt(1, id);
ResultSet resultSet = preparedStatement.executeQuery();
if (!resultSet.wasNull()) {
helloGreeting.setMessage(resultSet.getString("simplestring"));
} else {
throw new NotFoundException("Greeting not found with an index: " + id);
}
} finally {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
return helloGreeting;
}
#ApiMethod(name = "greetings.multiply", httpMethod = "post")
public HelloGreeting insertGreeting(#Named("times") Integer times, HelloGreeting greeting) {
HelloGreeting response = new HelloGreeting();
StringBuilder responseBuilder = new StringBuilder();
for (int i = 0; i < times; i++) {
responseBuilder.append(greeting.getMessage());
}
response.setMessage(responseBuilder.toString());
return response;
}
#ApiMethod(name = "greetings.authed", path = "hellogreeting/authed")
public HelloGreeting authedGreeting(User user) {
HelloGreeting response = new HelloGreeting("hello " + user.getEmail());
return response;
}
}
I have tried to enable mysql connector/j in my appengine-web.xml
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<use-google-connector-j>true</use-google-connector-j>
<application>backendapitutorial-1XXX</application>
<version>${app.version}</version>
<threadsafe>true</threadsafe>
<system-properties>
<property name="java.util.logging.config.file" value="WEB- INF/logging.properties"/>
</system-properties>
</appengine-web-app>
Whichever way I build+depl0y it (Dev or cloud), I always get
java.sql.SQLException: No suitable driver found for jdbc:mysql://173.194.XXX.90:3306/simple?user=root
or
java.sql.SQLException: No suitable driver found for jdbc:google:mysql://backendapitutorial-XXXX:simple/simple?user=root
(I replaced the real IP and project name with "X"s for this post).
I've already looked at these:
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/dbname
ClassNotFoundException: com.mysql.jdbc.GoogleDriver
What does 'Class.forName("org.sqlite.JDBC");' do?
I'm building with Maven and working on IntelliJ IDE.
Any help is greatly appreciated. Thanks.

Hibernate export to csv

I want to export query result to excel or csv file.
I am using hibernate struts.
Is there any query like 'into outfile' which can directly export excel to specified location?
In MySQL database, 'into outfile' query works fine but in hibernate it is not working.
I tried using native sql but it gives error 'couldn't execute bulk manipulation query' and anyhow I can not solve that.
I am using MySQL database.
If you are writing an web app and using spring you can do it by writing data to an output stream
Write a simple class to construct your response
public class CsvResponse {
private final String filename;
private final List<YourPojo> records;
public CsvResponse(List<YourPojo> records, String filename) {
this.records = records;
this.filename = filename;
}
public String getFilename() {
return filename;
}
public List<YourPojo> getRecords() {
return records;
}
}
Now write a message converter to write them to an output stream
public class CsvMessageConverter extends AbstractHttpMessageConverter<CsvResponse> {
public static final MediaType MEDIA_TYPE = new MediaType("text", "csv", Charset.forName("UTF-8"));
public CsvMessageConverter() {
super(MEDIA_TYPE);
}
protected boolean supports(Class<?> clazz) {
return CsvResponse.class.equals(clazz);
}
protected void writeInternal(CsvResponse response, HttpOutputMessage output) throws Exception {
output.getHeaders().setContentType(MEDIA_TYPE);
output.getHeaders().set("Content-Disposition", "attachment; filename=\"" + response.getFilename() + "\"");
OutputStream out = output.getBody();
CsvWriter writer = new CsvWriter(new OutputStreamWriter(out), '\u0009');
List<YourPojo> allRecords = response.getRecords();
for (int i = 1; i < allRecords.size(); i++) {
YourPojo aReq = allRecords.get(i);
writer.write(aReq.toString());
}
writer.close();
}
}
Add this Message converter to your app context config file
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="com.yourpackage.CsvMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
Finally the controller will look like
#RequestMapping(value = "/csvData", method = RequestMethod.GET, produces="text/csv")
#ResponseBody
public CsvResponse getFullData(HttpSession session) throws IOException {
// get data
List<YourPojo> allRecords = yourService.getData();
return new CsvResponse(allRecords, "yourData.csv");
}
I've found a similar way using JAX RS here.
But the bottomline is you'll have to use a REST mechanism to get data into the output stream if you want to do it in proper way but if your only target is to get data into a file you can just get your data in a list and then simply write it to a file.

jsp mysql server connection timeout

hi i am doing an jsp project. and i deploy my project on apache tomcat. i use mysql as databese.
when i deploy project on remote server it is run good. but after some hours it gives me sql error. then i go back my apache server and start projecet again it run and after some hours it gives me same sql error again. i dont know the problem. is that caused from my java connection code or it is about mysql server. can some one tell me why it gives me sql error.?
public class ConnectionManager {
private String className = "com.mysql.jdbc.Driver";
private String userName ="username";
private String password = "password";
private String url = "jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf-8";
/**
* #uml.property name="connectionInstance"
* #uml.associationEnd
*/
private static ConnectionManager connectionInstance = null;
public ConnectionManager(){
}
public static synchronized ConnectionManager getInstance() {
if(connectionInstance == null) {
connectionInstance = new ConnectionManager();
}
return connectionInstance;
}
public Connection getConnection(){
Connection conn = null;
try {
Class.forName(className);
conn = DriverManager.getConnection (url, userName, password);
System.out.println("Connection Established");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
MySQL has a default connection timeout of 8 hours. So this means that you've kept a SQL connection open for too long. Your code suggests that you're creating only one connection on application's startup and reusing it application wide. This is very bad. This is not threadsafe.
You need to change your code so that you're not declaring and storing the SQL Connection as a static or instance variable anywhere in your code. Instead, it should be declared, created and closed within the shortest possible scope. Preferably within the very same method block as where you're executing the SQL query.
Here's a minor rewrite of your ConnectionManager which does the job properly:
public class ConnectionManager {
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String USERNAME ="username";
private static final String PASSWORD = "password";
private static final String URL = "jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf-8";
static {
try {
Class.forName(DRIVER);
}
catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(DRIVER + " missing in classpath!", e);
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USERNAME, PASSWORD);
}
}
Use it as follows:
public class SomeDAO {
public SomeEntity find(Long id) throws SQLException {
Connection connection = null;
// ...
try {
connection = ConnectionManager.getConnection();
// ...
}
finally {
// ...
if (connection != null) try { connection.close(); } catch(SQLException ignore) {}
}
return someEntity;
}
To improve connecting performance, use a connection pool instead of DriverManager.
See also:
Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern
Are you closing connections properly after using them.

Am I Using JDBC Connection Pooling?

I am trying to determine if I am actually using JDBC connection pooling. After doing some research, the implementation almost seems too easy. Easier than a regular connection in fact so i'd like to verify.
Here is my connection class:
public class DatabaseConnection {
Connection conn = null;
public Connection getConnection() {
BasicDataSource bds = new BasicDataSource();
bds.setDriverClassName("com.mysql.jdbc.Driver");
bds.setUrl("jdbc:mysql://localhost:3306/data");
bds.setUsername("USERNAME");
bds.setPassword("PASSWORD");
try{
System.out.println("Attempting Database Connection");
conn = bds.getConnection();
System.out.println("Connected Successfully");
}catch(SQLException e){
System.out.println("Caught SQL Exception: " + e);
}
return conn;
}
public void closeConnection() throws SQLException {
conn.close();
}
}
Is this true connection pooling? I am using the connection in another class as so:
//Check data against database.
DatabaseConnection dbConn = new DatabaseConnection();
Connection conn;
ResultSet rs;
PreparedStatement prepStmt;
//Query database and check username/pass against table.
try{
conn = dbConn.getConnection();
String sql = "SELECT * FROM users WHERE username=? AND password=?";
prepStmt = conn.prepareStatement(sql);
prepStmt.setString(1, user.getUsername());
prepStmt.setString(2, user.getPassword());
rs = prepStmt.executeQuery();
if(rs.next()){ //Found Match.
do{
out.println("UserName = " + rs.getObject("username") + " Password = " + rs.getObject("password"));
out.println("<br>");
} while(rs.next());
} else {
out.println("Sorry, you are not in my database."); //No Match.
}
dbConn.closeConnection(); //Close db connection.
}catch(SQLException e){
System.out.println("Caught SQL Exception: " + e);
}
Assuming that it's the BasicDataSource is from DBCP, then yes, you are using a connection pool. However, you're recreating another connection pool on every connection acquirement. You are not really pooling connections from the same pool. You need to create the connection pool only once on application's startup and get every connection from it. You should also not hold the connection as an instance variable. You should also close the connection, statement and resultset to ensure that the resources are properly closed, also in case of exceptions. Java 7's try-with-resources statement is helpful in this, it will auto-close the resources when the try block is finished.
Here's a minor rewrite:
public final class Database {
private static final BasicDataSource dataSource = new BasicDataSource();
static {
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/data");
dataSource.setUsername("USERNAME");
dataSource.setPassword("PASSWORD");
}
private Database() {
//
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}
(this can if necessary be refactored as an abstract factory to improve pluggability)
and
private static final String SQL_EXIST = "SELECT * FROM users WHERE username=? AND password=?";
public boolean exist(User user) throws SQLException {
boolean exist = false;
try (
Connection connection = Database.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL_EXIST);
) {
statement.setString(1, user.getUsername());
statement.setString(2, user.getPassword());
try (ResultSet resultSet = preparedStatement.executeQuery()) {
exist = resultSet.next();
}
}
return exist;
}
which is to be used as follows:
try {
if (!userDAO.exist(username, password)) {
request.setAttribute("message", "Unknown login. Try again.");
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
} else {
request.getSession().setAttribute("user", username);
response.sendRedirect("userhome");
}
} catch (SQLException e) {
throw new ServletException("DB error", e);
}
In a real Java EE environement you should however delegate the creation of the DataSource to the container / application server and obtain it from JNDI. In case of Tomcat, see also for example this document: http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html
Doesn't seem like it's pooled. You should store the DataSource in DatabaseConnection instead of creating a new one with each getConnection() call. getConnection() should return datasource.getConnection().
Looks like a DBCP usage. If so, then yes. It's already pooled. And here is the default pool property value of the DBCP.
/**
* The default cap on the number of "sleeping" instances in the pool.
* #see #getMaxIdle
* #see #setMaxIdle
*/
public static final int DEFAULT_MAX_IDLE = 8;
/**
* The default minimum number of "sleeping" instances in the pool
* before before the evictor thread (if active) spawns new objects.
* #see #getMinIdle
* #see #setMinIdle
*/
public static final int DEFAULT_MIN_IDLE = 0;
/**
* The default cap on the total number of active instances from the pool.
* #see #getMaxActive
*/
public static final int DEFAULT_MAX_ACTIVE = 8;
As a follow up to BalusC's solution, below is an implementation that I can be used within an application that requires more than one connection, or in a common library that would not know the connection properties in advance...
import org.apache.commons.dbcp.BasicDataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.ConcurrentHashMap;
public final class Database {
private static final ConcurrentHashMap<String, BasicDataSource> dataSources = new ConcurrentHashMap();
private Database() {
//
}
public static Connection getConnection(String connectionString, String username, String password) throws SQLException {
BasicDataSource dataSource;
if (dataSources.containsKey(connectionString)) {
dataSource = dataSources.get(connectionString);
} else {
dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl(connectionString);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSources.put(connectionString, dataSource);
}
return dataSource.getConnection();
}
}