I have a class which is creating and inserting data into a table.Please find my code below:
Class DBConnection:
import java.sql.Connection;
import java.sql.DriverManager;
public class DBConnection {
public static Connection getDBConnection() {
String url = "jdbc:mysql://localhost:3306/";
String dbName = "expenseCalc";
String driver = "com.mysql.jdbc.Driver";
String userName = "*********";
String password = "*******";
Connection conn = null;
try {
Class.forName(driver).newInstance();
conn = (Connection) DriverManager.getConnection(url + dbName, userName, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
}
SpringConfig.class
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class SpringConfig {
#Bean("sqloperations")
public SQLOperationJavaConfig sqLoperationJavaConfig() {
DBConnection dbConnection=new AppJavaConfig<DBConnection>().getbean("dbconnection");
return new SQLOperationJavaConfig(dbConnection);
}
#Bean("dbconnection")
public DBConnection dbConnection() {
return new DBConnection();
}
}
SQLOperationJavaConfig.class
public class SQLOperationJavaConfig {
private DBConnection dbConnection;
public SQLOperationJavaConfig(DBConnection dbConnection) {
this.dbConnection=dbConnection;
}
private Connection conn;
public void createTable() throws SQLException {
conn = dbConnection.getDBConnection();
String sql="drop table if exists dummy";
String sql1 = "create table dummy (id int,name varchar(20))";
Statement statement = conn.createStatement();
statement.execute(sql);
statement.execute(sql1);
System.out.println("Table Created!!");
}
public void insertData() throws SQLException {
conn = dbConnection.getDBConnection();
String sql = "insert into dummy values(12,'Sunny')";
Statement statement = conn.createStatement();
statement.execute(sql);
System.out.println("Record Inserted!!");
}
}
AppJavaConfig.java
public class AppJavaConfig<T> {
static ApplicationContext context;
public static void main(String[] args) throws SQLException {
context = new AnnotationConfigApplicationContext(SpringConfig.class);
SQLOperationJavaConfig sqLoperationJavaConfig = (SQLOperationJavaConfig) context.getBean("sqloperations");
sqLoperationJavaConfig.createTable();
sqLoperationJavaConfig.insertData();
}
public T getbean(String beanName) {
T t=(T) context.getBean(beanName);
return t;
}
}
When running this class i am getting the below error:
Caused by: java.lang.NullPointerException
at com.src.springproj.AppJavaConfig.getbean(AppJavaConfig.java:17)
at com.src.springproj.SpringConfig.sqLoperationJavaConfig(SpringConfig.java:10)
The getBean method is not returning the "dbconnection" Bean.
You don't need this getBean method..just change the initializer of SQLOperationsJavaConfig to the following:
return new SQLOperationJavaConfig(dbConnection());
Spring will look at the bean already created for the DBConnection
Use #autowired.
#autowired
private DBConnection dbConnection;
Because The #Autowired annotation can be used to autowire bean on the setter method just like #Required annotation, constructor, a property or methods with arbitrary names and/or multiple arguments.
Related
Have implemented a DAO pattern with Hikari connection pool
Made the best use of the DAO design pattern.
Have created singleton class which returns the object of a class with a public connection if the object of the singleton class is NULL> object is again created thereby getting the connection
queries to call the static method of the singleton class to obtain public connection and prepared statements are closed in try-with-resources.
application is live for more than 12hrs after few requests queries are not getting executed
"The connection is closed."
public class DatabaseConnection {
//Constants
String url = "jdbc:mysql://localhost:3306/";
String driver="com.mysql.jdbc.Driver";
String userName = "root";
String password = "#";
private static HikariDataSource dataSource;
public Connection conn;
public static DatabaseConnection db;
/**
* A static method which uses HikariDataSource Connection Pooling library to connect with the MySQL Database.
* Accepts and Sets few JDBC details like User Name,Password,URL,Driver Name and many more.
* #return This methods returns HikariDataSource
* #throws SQLException and CasbnException
*/
public DatabaseConnection() throws SQLException,CasbnExceptions {
try {
//create the object of HikariDataSource
dataSource=new HikariDataSource();
//set up the JDBC details (username,password,url,driver)
System.out.println("Inside DatabaseConnection constructor..");
dataSource.setDriverClassName(driver);
dataSource.setJdbcUrl(url);
dataSource.setUsername(userName);
dataSource.setPassword(password);
this.conn=dataSource.getConnection();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static DatabaseConnection getCon() throws CasbnExceptions, SQLException
{
if(db==null)
{
System.out.println("Inside getCon() and if block...");
db=new DatabaseConnection();
}
return db;
}
}
public class DAO_Implementation implements DAOFactory {
//Declare all the SQL queries as private static and final
//getCompany query
private static final String getCompanyName="SELECT company_name FROM #.company_register where email=?";
#Override
public String getCompanyName(String Email) throws SQLException {
try
(PreparedStatement pst = DatabaseConnection.getCon().conn
.prepareStatement(getCompanyName)){
pst.setString(1, Email);
ResultSet rs = pst.executeQuery();
rs.next();
Name=rs.getString(1);
}
catch(Exception e)
{
e.printStackTrace();
}
return Name;
}
#Override
public Pojos Individual_Company_detail(String CompanyName) throws SQLException{
try
(PreparedStatement pst = DatabaseConnection.getCon().conn
.prepareStatement(CompanyDetail);){
pst.setString(1, CompanyName);
ResultSet rs = pst.executeQuery();
if(rs.next()==true)
{
Pojos Po=new Pojos();
Po.setCompanyID(rs.getInt(1));
Po.setUserCount(rs.getInt(2));
Po.setPlan(rs.getString(3));
Po.setDateofSub(rs.getString(4));
Po.setSubscriptionID(rs.getString(5));
Po.setVaildTill(rs.getString(6));
return Po;
}
else
{
Pojos Po=new Pojos();
Po.setErrorMessage(CompanyName +" Has not registered to of our Plan and no Recent Transactions");
return Po;
}
}
}
Currently you are returning the same connection all the time using .conn
remove conn from DatabaseConnection and add a different method which getConnection from Hikari datasource every time
This way Hikari will handle connection pooling
public static Connection getConnection() {
return dataSource.getConnection();
}
And open Connection resource separately so it will be closed:
try
(Connection conn = DatabaseConnection.getConnection();
PreparedStatement pst = conn.prepareStatement(CompanyDetail))
public class DatabaseConnection {
String url = "jdbc:mysql://localhost:3306/";
//String dbName = ""
String driver="com.mysql.jdbc.Driver";
String userName = "root";
String password = "";
private static HikariDataSource dataSource;
public static DatabaseConnection db;
public DatabaseConnection() throws SQLException,CasbnExceptions {
try {
//create the object of HikariDataSource
dataSource=new HikariDataSource();
//set up the JDBC details (username,password,url,driver)
System.out.println("Inside DatabaseConnection constructor..");
dataSource.setDriverClassName(driver);
dataSource.setJdbcUrl(url);
dataSource.setUsername(userName);
dataSource.setPassword(password);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException
{
if(db==null)
{
db=new DatabaseConnection();
}
return dataSource.getConnection();
}
}
I am trying to get the values that the main method would have produced and use them in the getConnection method. However when I try to access the getConnection method, null values are being returned.
I want to use the ConnectionManager class to connect to the database.
Code below.
public class ConnectionManager {
public static String database;
public static String dbuser;
public static String dbpassword;
public static void main(String args[]) {
Properties prop = new Properties();
InputStream input = null;
try {
input = new FileInputStream("config.properties");
// load a properties file
prop.load(input);
database = prop.getProperty("database");
dbuser = prop.getProperty("dbuser");
dbpassword = prop.getProperty("dbpassword");
System.out.println(database);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static String url = "jdbc:mysql://localhost:3306/" + database;
private static String driverName = "com.mysql.jdbc.Driver";
private static String username = dbuser;
private static String password = dbpassword;
private static Connection con;
public static Connection getConnection() {
try {
Class.forName(driverName);
try {
con = DriverManager.getConnection(url, username, password);
} catch (SQLException ex) {
// log an exception. For example:
System.out.println("Failed to create the database connection.");
System.out.println(url + " " + username + " " + password);
}
} catch (ClassNotFoundException ex) {
System.out.println("Your driver has not been found.");
}
return con;
}
}
You just have to call the getConnection() method with parameters.
public static Connection getConnection(String url, String username, String password) {
/* Your code here */
}
And then, call this method.
Connection connection = getConnection(url, username, password);
Static c fields are initialized once when the class is loaded. The Connection fields are set to the ConnectionManager fields once, when they are still null.
To "fix" your problem, have your code in Connection use the fields in ConnectionManager:
con = DriverManager.getConnection(url, ConnectionManager.dbuser, ConnectionManager.dbpassword);
You're getting null argument values in DriverManager.getConnection(url, username, password) calling cause you have declared them as static fields.
So you initialize them as nulls before you read the particular values from the config.properties
Let's follow the flow:
Static initialization step:
private static String username = dbuser; //username==null; dbuser==null;
private static String password = dbpassword; //password==null; dbpassword==null
private static Connection con; //con==null;
Method main execution:
database = (prop.getProperty("database"));
dbuser = (prop.getProperty("dbuser")); //dbuser="smth"; username==null
dbpassword = (prop.getProperty("dbpassword")); //dbpassword ="smth"; password==null
Method getConnection execution:
con = DriverManager.getConnection(url, username, password); //username==null; //password==null;
P.S.: As it was previously said, it's better to use function with arguments like this:
public static Connection getConnection(String url, String username, String password) {
/* Your code here */
}
Which is the best way to handle a MySql connection with Java, via static context or Object one?
Static context:
public class MainClass {
public static void main(String[] args) {
Class.forName("com.mysql.jdbd.Driver");
Connection con = DBHandler.getConnection();
//Using connection
}
}
public class DBHandler {
public static Connection getConnection() {
final String URL = "";
final String USER = "";
final String PASS = "";
return DriverManager.getConnection(URL, USER, PASS);
}
}
Or creating an object:
public class MainClass {
public static void main(String[] args) {
Class.forName("com.mysql.jdbd.Driver");
Connection con = new DBHandler().getConnection();
//Using connection
}
}
public class DBHandler {
private final Connection con;
public DBHandler() {
final String URL = "";
final String USER = "";
final String PASS = "";
this.con = DriverManager.getConnection(URL, USER, PASS);
}
public Connection getConnection() {
return con;
}
}
I think creating an object in every class you need to use the connection is weird but maybe it's the best way to solve that.
Thank you.
I've got 2 file in my java project : MysqlConnect and Main .
I want to run query from Main class.It's possible?
This is MysqlConnect file:
public class MysqlConnect {
public Connection conn = null;
public String url = "jdbc:mysql://localhost:3306/";
public String dbName = "jdbctutorial";
public String driver = "com.mysql.jdbc.Driver";
public String userName = "birthday";
public String password = "123456";
public Statement stmt;
public String query = "";
public int rs;
public void crearedatabase() {
try {
Class.forName(driver).newInstance();
conn = DriverManager
.getConnection(url + dbName, userName, password);
// System.out.println("Connected to the database");
Statement stmt = conn.createStatement();
} catch (Exception e) {
System.out.println("Baza de date nu a fost creata");
}
}
public void executeSql() {
try {
rs = stmt.executeUpdate(query);
} catch (Exception e) {
System.out.println("Mysql Error");
}
}
}
And this is the Main file:
public class Main {
public static void main(String[] args) throws SQLException
{
MysqlConnect sqlconnect = new MysqlConnect();
sqlconnect.crearedatabase();
sqlconnect.query="INSERT INTO `jdbctutorial`.`persons` (`id`, `nume`, `prenume`, `data`) VALUES (NULL, 'xxxx', 'xxxx', '1990-12-12');";
sqlconnect.executeSql();
}
}
The error(Exception) is on the MysqConnection at the try/catch
rs = stmt.executeUpdate(query);
You assign statement object to a local variable named stmt instead of the object field with the same name.
Replace this
Statement stmt = conn.createStatement();
With this:
this.stmt = conn.createStatement();
this is not necessary here, but it's a good practice to have it there.
I wrote a singleton class for obtaining a database connection.
Now my question is this: assume that there are 100 users accessing the application. If one user closes the connection, for the other 99 users will the connection be closed or not?
This is my sample program which uses a singleton class for getting a database connection:
public class GetConnection {
private GetConnection() { }
public Connection getConnection() {
Context ctx = new InitialContext();
DataSource ds = ctx.lookup("jndifordbconc");
Connection con = ds.getConnection();
return con;
}
public static GetConnection getInstancetoGetConnection () {
// which gives GetConnection class instance to call getConnection() on this .
}
}
Please guide me.
As long as you don't return the same Connection instance on getConnection() call, then there's nothing to worry about. Every caller will then get its own instance. As far now you're creating a brand new connection on every getConnection() call and thus not returning some static or instance variable. So it's safe.
However, this approach is clumsy. It doesn't need to be a singleton. A helper/utility class is also perfectly fine. Or if you want a bit more abstraction, a connection manager returned by an abstract factory. I'd only change it to obtain the datasource just once during class initialization instead of everytime in getConnection(). It's the same instance everytime anyway. Keep it cheap. Here's a basic kickoff example:
public class Database {
private static DataSource dataSource;
static {
try {
dataSource = new InitialContext().lookup("jndifordbconc");
}
catch (NamingException e) {
throw new ExceptionInInitializerError("'jndifordbconc' not found in JNDI", e);
}
}
public static Connection getConnection() {
return dataSource.getConnection();
}
}
which is to be used as follows according the normal JDBC idiom.
public List<Entity> list() throws SQLException {
List<Entity> entities = new ArrayList<Entity>();
try (
Connection connection = Database.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT id, foo, bar FROM entity");
ResultSet resultSet = statement.executeQuery();
) {
while (resultSet.next()) {
Entity entity = new Entity();
entity.setId(resultSet.getLong("id"));
entity.setFoo(resultSet.getString("foo"));
entity.setBar(resultSet.getString("bar"));
entities.add(entity);
}
}
return entities;
}
See also:
Is it safe to use a static java.sql.Connection instance in a multithreaded system?
Below code is a working and tested Singleton Pattern for Java.
public class Database {
private static Database dbIsntance;
private static Connection con ;
private static Statement stmt;
private Database() {
// private constructor //
}
public static Database getInstance(){
if(dbIsntance==null){
dbIsntance= new Database();
}
return dbIsntance;
}
public Connection getConnection(){
if(con==null){
try {
String host = "jdbc:derby://localhost:1527/yourdatabasename";
String username = "yourusername";
String password = "yourpassword";
con = DriverManager.getConnection( host, username, password );
} catch (SQLException ex) {
Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
}
}
return con;
}
While getting Connection in any Class simply use below line
Connection con = Database.getInstance().getConnection();
Hope it may help :)
package es.sm2.conexion;
import java.sql.Connection;
import java.sql.DriverManager;
public class ConexionTest {
private static Connection conn = null;
static Connection getConnection() throws Exception {
if (conn == null) {
String url = "jdbc:mysql://localhost:3306/";
String dbName = "test";
String driver = "com.mysql.jdbc.Driver";
String userName = "userparatest";
String password = "userparatest";
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url + dbName, userName, password);
}
return conn;
}
}
To close Connection
public static void closeConnection(Connection conn) {
try {
conn.close();
} catch (SQLException e) {
}
}
To call to the connection:
package conexion.uno;
import java.sql.*;
import es.sm2.conexion.ConexionTest;
public class LLamadorConexion {
public void llamada() {
Connection conn = null;
PreparedStatement statement = null;
ResultSet resultado = null;
String query = "SELECT * FROM empleados";
try {
conn = ConexionTest.getConnection();
statement = conn.prepareStatement(query);
resultado = statement.executeQuery();
while (resultado.next()) {
System.out.println(resultado.getString(1) + "\t" + resultado.getString(2) + "\t" + resultado.getString(3) + "\t" );
}
}
catch (Exception e) {
System.err.println("El porque del cascar: " + e.getMessage());
}
finally {
ConexionTest.closeConnection(conn);
}
}
}
Great post, farhangdon! I, however, found it a little troublesome because once you close the connection, you have no other way to start a new one. A little trick will solve it though:
Replace if(con==null) with if(con==null || con.isClosed())
import java.sql.Connection;
import java.sql.DriverManager;
public class sql11 {
static Connection getConnection() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/ics", "root", "077");
return c;
}
}