A minimum runnable example of my project is above:
Shopping Cart and its Products; I need to save this aggregation in pure JDBC, without ORM, in the Database. Is it the proper way to save the product list to DB, passing to the shopping_cart_fk_id to each product and its DAOs?
MainClass
package ShoppingCartDAO;
import java.util.Scanner;
public class MainClass {
public static void main(String[] args)
{
ShoppingCart shoppingCart = new ShoppingCart();
Integer choice = 0;
Scanner input = new Scanner(System.in);
do {
choice = 0;
System.out.print("Choose one option: \n");
System.out.print("1 - Register New Product \n");
System.out.print("0 - Exit And Save");
choice = input.nextInt();
switch (choice)
{
case 1:
new ShoppingCart().InsertInto(new ProductRegister().RegisterNewProduct());
break;
default:
System.out.print(" Invalid Option \n");
break;
}
} while (choice != 0);
new ShoppingCartDao().add(shoppingCart);
input.close();
}
}
ConnectionFactory
package ShoppingCartDAO;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
class ShoppingCartDao{
public void add(ShoppingCart shoppingCart)
{
try
{
PreparedStatement pstmt = ConnectionFactory.getConnection().prepareStatement("Insert into shoppingCart (date) values (?)");
pstmt.setDate(1, new java.sql.Date(System.currentTimeMillis()));
pstmt.execute();
pstmt.close();
} catch(SQLException e)
{
throw new RuntimeException(e);
}
ProductDao productDAO = new ProductDao();
for(Product product : shoppingCart.getProduct()){
productDAO.add(product);
}
}
public Integer getCount()
{
Integer count;
try
{
Statement stmt = ConnectionFactory.getConnection().createStatement();
ResultSet rs = stmt.executeQuery("SELECT COUNT(*) AS recordCount FROM shoppingcart");
rs.next();
count = rs.getInt(1);
rs.close();
stmt.close();
} catch(SQLException e)
{
throw new RuntimeException(e);
}
return count;
}
}
ShoppingCart Entity
public class ShoppingCart
{
Long id;
Date date;
ArrayList<Product>products = new ArrayList<Product>();
public ShoppingCart(){
this.date = new Date();
}
public void InsertInto(Product product){
products.add(product);
}
public Date getDate(){
return this.buyDate;
}
public ArrayList<Product>getProduct(){
return this.products;
}
}
Product Entity
public class Product
{
String name = new String();
Integer quantity = new Integer();
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setQuantity(Integer quantity){
this.quantity = quantity;
}
public Integer getQuantity(){
return this.quantity;
}
}
Shopping Cart DAO
package ShoppingCartDAO;
import java.util.ArrayList;
import java.util.Date;
public class ShoppingCart {
Long id;
Date date;
ArrayList<Product>products = new ArrayList<Product>();
public ShoppingCart(){
this.date = new Date();
}
public void InsertInto(Product product){
products.add(product);
}
public Date getDate(){
return this.date;
}
public ArrayList<Product>getProduct(){
return this.products;
}
public void addProduct(Product product) {
products.add(product);
}
}
ProductDAO
package ShoppingCartDAO;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class ProductDao {
public void add(Product product)
{
try
{
String query = "Insert into product (fkShoppingCartId, name, quantity) values (?, ?, ?)";
PreparedStatement pstmt = ConnectionFactory.getConnection().prepareStatement(query);
pstmt.setLong(1, new ShoppingCartDao().getCount() + 1);
pstmt.setString(2, product.getName());
pstmt.setInt(3, product.getQuantity());
pstmt.execute();
pstmt.close();
}
catch(SQLException e)
{
throw new RuntimeException(e);
}
}
You have a Java model for your data, what database schema do you need to store it?
It's pretty obvious for the simple types like numbers and strings; for the List of products in your ShoppingCart, I assume you want to conserve the order of the Products in you ShoppingCart. I also assume that a Product is in fact an item in a ShoppingCart since it has a quantity field; so a Product has no existence of it's own: it's a part of a ShoppingCard.
With these assumptions, I can represent the Java model in the database with two tables:
SHOPPING_CART(ID, DATE)
PRODUCT(SHOPPING_CART_ID, POS, NAME, QUANTITY)
and then define class ShoppingCartPersistence:
public class ShoppingCardPersistence {
private final Connection connection;
private final ProductPersistence productPersistence;
public ShoppingCardPersistence(Connection connection) {
this.connection = connection;
this.productPersistence = new ProductPersistence(connection);
}
public void create(ShoppingCart cart) throws SQLException {
try (PreparedStatement stmt = connection.prepareStatement(
"INSERT INTO SHOPPING_CART(ID, DATE) VALUES(?, ?)")) {
stmt.setLong(1, cart.getId());
stmt.setTimestamp(2, new Timestamp(cart.getDate().getTime()));
stmt.executeUpdate();
}
productPersistence.create(cart.getId(), cart.getProducts());
}
public ShoppingCart read(long id) throws SQLException {
ShoppingCart cart;
try (PreparedStatement stmt = connection.prepareStatement(
"SELECT DATE FROM SHOPPING_CART WHERE ID=?")) {
stmt.setLong(1, id);
ResultSet rs = stmt.executeQuery();
if (!rs.next()) {
return null;
}
cart = new ShoppingCart();
cart.setId(id);
cart.setDate(new Date(rs.getTimestamp(1).getTime()));
}
cart.setProducts(productPersistence.read(cart.getId()));
return cart;
}
public void update(ShoppingCart cart) throws SQLException {
productPersistence.delete(cart.getId());
try (PreparedStatement stmt = connection.prepareStatement(
"UPDATE SHOPPING_CART SET DATE=? WHERE ID=?")) {
stmt.setLong(2, cart.getId());
stmt.setTimestamp(1, new Timestamp(cart.getDate().getTime()));
stmt.executeUpdate();
}
productPersistence.create(cart.getId(), cart.getProducts());
}
public void delete(ShoppingCart cart) throws SQLException {
productPersistence.delete(cart.getId());
try (PreparedStatement stmt = connection.prepareStatement(
"DELETE SHOPPING_CART WHERE ID=?")) {
stmt.setLong(1, cart.getId());
stmt.executeUpdate();
}
}
}
and ProductPersistence:
public class ProductPersistence {
private final Connection connection;
public ProductPersistence(Connection connection) {
this.connection = connection;
}
public void create(long id, List<Product> products) throws SQLException {
if (!products.isEmpty()) {
try (PreparedStatement stmt = connection.prepareStatement(
"INSERT INTO PRODUCT(SHOPPING_CART_ID, POS, NAME, QUANTITY)"
+ " VALUES(?,?,?,?)")) {
for (int i = 0; i < products.size(); ++i) {
Product prod = products.get(i);
stmt.setLong(1, id);
stmt.setInt(2, i);
stmt.setString(3, prod.getName());
stmt.setInt(4, prod.getQuantity());
stmt.addBatch();
}
stmt.executeBatch();
}
}
}
public List<Product> read(long id) throws SQLException {
try (PreparedStatement stmt = connection.prepareStatement(
"SELECT POS, NAME, QUANTITY FROM PRODUCT"
+ " WHERE SHOPPING_CART_ID=?"
+ " ORDER BY POS")) {
List<Product> result = new ArrayList<>();
stmt.setLong(1, id);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
Product prod = new Product();
prod.setQuantity(rs.getInt(2));
prod.setName(rs.getString(3));
result.add(prod);
}
return result;
}
}
public void delete(long id) throws SQLException {
try (PreparedStatement stmt = connection.prepareStatement(
"DELETE PRODUCT WHERE SHOPPING_CART_ID=?")) {
stmt.setLong(1, id);
stmt.executeUpdate();
}
}
}
You would typically use these classes with a piece of code like this:
try (Connection connection = ConnectionFactory.getConnection()) {
ShoppingCartPersistence pm
= new ShoppingCartPersistence(connection);
ShoppingCart cart = pm.read(shoppingCardId);
// do a lot of useful thing with the cart
pm.update(cart);
connection.commit();
} catch (SQLException ex) {
ex.printStackTrace();
}
Note that in your ConnectionFactory you should disable autocommit.
The ID of a shopping card has to be assigned before a call to ShoppingCardPersistence.create but databases offer mechanisms to automatically generate them, either with an autoincremented column or with a sequence.
Related
I want to pass the postgresql column names as dynamically on the execute query in java.I have created table and table name is product which has 4 columns(year, product,no,age).I have established the db connection and trying to pass the columns dynamically. I have created one pogo class which is having getter and setter of columns names.How can I pass the columns name dynamically on execute query.
dbcon.java
import java.sql.*;
import java.sql.Connection;
public class dbcon {
public static void main(String[] args) {
Connection conn =null;
Statement stmt = null;
DatabaseStatus databaseStatus = new DatabaseStatus();
try
{
Class.forName("******");
conn = DriverManager.getConnection("************", "*******", "*******");
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("Select "+databaseStatus.getYear()+","+databaseStatus.getProduct()+","+databaseStatus.getNo()+","+databaseStatus.getAge()+" FROM \"Products\";");
while(rs.next()){
System.out.println(rs.getString("Year").trim());
System.out.println(rs.getString("Product").trim());
System.out.println(rs.getString("No.").trim());
System.out.println(rs.getString("Age").trim());
}
}
catch (Exception e) {
e.printStackTrace();
}finally {
try {
stmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
datastatus.java
public class DatabaseStatus {
private String No;
private String Year;
private String Product;
private String Age;
public String getNo() {
return No;
}
public void setNo(String no) {
No = no;
}
public String getYear() {
return Year;
}
public void setYear(String year) {
Year = year;
}
public String getProduct() {
return Product;
}
public void setProduct(String product) {
Product = product;
}
public String getAge() {
return Age;
}
public void setAge(String age) {
Age = age;
}
}
table
SELECT "Year", "Product", "No.", "Age"
FROM "Products";
If you really want use the setters.
databaseStatus.setNo("No.");
databaseStatus.setYear( "Year");
databaseStatus.setProduct("Product");
databaseStatus.setAge("Age");
else remove the setters and
public class DatabaseStatus {
private String No = "No.";
private String Year = "Year";
private String Product = "Product";
private String Age = "Age";
public String getNo() {…
}
I'm working on a sample user-based java web application. When I try to add a user via registration to my database. After capturing the data on the front end, the records get stored as null values
i.e a row of my users table would contain the values (7, null, null, null, null) (using template id(primary-key), f_name, l_name, email, password).
Below are the files I believe could cause possible problems
User.java
package com.ysg.data;
import com.ysg.service.PasswordEncrypter;
import java.io.Serializable;
import java.util.Date;
import java.util.Objects;
public class User implements Serializable {
private String id;
private String password;
private String firstName;
private String lastName;
private String email;
public User(){
// default
}
public User( String password, boolean isEncrypted, String firstName, String
lastName, String email){
this.password = isEncrypted ? password : encrypt(password);
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
} //getters and setters follow
UserRepository.java
package com.ysg.repository;
import com.ysg.data.User;
import com.ysg.exception.DuplicateItemException;
import com.ysg.exception.RepositoryException;
import com.ysg.util.MySQLHelper;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class UserRepository implements RepositoryInt<User> {
private static final String INSERT = "INSERT INTO ysg.users (f_name, l_name, email, password) values (?, ?, ?, ?)";
private static final String USER_LOGIN = "SELECT * FROM ysg.users WHERE email=? and password=?";
private static final String USER_FETCH = "SELECT * FROM ysg.users WHERE email='";
private static final String FIRSTNAME = "f_name";
private static final String LASTNAME = "l_name";
private static final String EMAIL= "email";
private static final String PASSWORD = "password";
public UserRepository(){
// default
}
#Override
public User login(User obj){
User result = find(obj);
if (result != null) {
return result;
}
return null;
}
#Override
public User register(User obj){
if (obj != null && (find(obj) == null)) {
return add(obj);
}
return null;
}
private User add(User user){
Connection conn = null;
try {
conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(INSERT);
stmt.setString(1, user.getFirstName());
stmt.setString(2, user.getLastName());
stmt.setString(3, user.getEmail());
stmt.setString(4, user.getPassword());
stmt.execute();
closeStatement(stmt);
return user;
}
catch (SQLException ex) {
if (ex.getMessage().contains("Duplicate")) {
System.out.println("Item with duplicate id already exists in repository");
throw new DuplicateItemException("Item with duplicate id already exists in repository");
}
else {
ex.printStackTrace();
System.out.println("Failed to add item to repository");
throw new RepositoryException(ex);
}
}
finally {
closeConnection(conn);
}
}
private User fetch(User user){
Connection conn = null;
try {
conn = getConnection();
Statement stmt = conn.createStatement();
stmt.execute(USER_FETCH + user.getEmail()+ "'");
ResultSet resultSet = stmt.getResultSet();
User result = marshall(resultSet);
closeStatement(stmt);
return result;
}
catch (SQLException ex) {
ex.printStackTrace();
System.out.println("Failed to fetch item from repository");
throw new RepositoryException(ex);
}
finally {
closeConnection(conn);
}
}
private User find(User user){
Connection conn = null;
try {
conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(USER_LOGIN);
stmt.setString(1, user.getEmail());
stmt.setString(2, user.getPassword());
ResultSet resultSet = stmt.executeQuery();
User result = marshall(resultSet);
closeStatement(stmt);
return result;
}
catch (SQLException ex) {
ex.printStackTrace();
System.out.println("Failed to add item to repository");
throw new RepositoryException(ex);
}
finally {
closeConnection(conn);
}
}
private User marshall(ResultSet result) throws RepositoryException, SQLException{
if (result == null) {
return null;
}
User user = null;
if (result.next()) {
// String id = result.getString(ID);
String password = result.getString(PASSWORD);
String firstName = result.getString(FIRSTNAME);
String lastName = result.getString(LASTNAME);
String email = result.getString(EMAIL);
user = new User(password, true, firstName, lastName, email);
}
return user;
}
private Connection getConnection(){
return MySQLHelper.getConnection();
}
private static void closeStatement(Statement stmt){
if (stmt != null) {
try {
stmt.close();
//stmt = null;
}
catch (SQLException ex) {
ex.printStackTrace();
}
}
}
private void closeConnection(Connection conn){
if (conn != null) {
try {
conn.close();
conn = null;
}
catch (SQLException e) {
e.printStackTrace();
}
}
}
}
MySQLHelper.java
package com.ysg.util;
import com.ysg.data.User;
import com.ysg.exception.DuplicateItemException;
import com.ysg.exception.RepositoryException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class MySQLHelper {
private static final String INSERT_USER = "INSERT INTO users(f_name, l_name, email, password) values (?, ?, ?, ?)";
private static final String USER_FETCH = "SELECT * FROM users WHERE id='";
private static final String FETCH_ALL = "SELECT * FROM users";
private static final String COUNT_ALL_USERS = "SELECT COUNT(*) FROM users";
private static final String DELETE_ALL = "DELETE FROM users";
private static final String ID = "id";
private static final String EMAIL = "email";
private static final String PASSWORD = "password";
private static final String FIRSTNAME = "f_name";
private static final String LASTNAME = "l_name";
private static final String DS_NAME = "jdbc/sen301DS";
private static Context envCtx;
private static DataSource ds;
static {
try {
Context ctx = new InitialContext();
envCtx = (Context) ctx.lookup("java:/comp/env");
System.out.println(envCtx);
}
catch (Exception ex) {
System.out.println("ConnectionPool will not be available - only direct connection can be used");
}
}
public static List<User> fetch() throws SQLException{
Connection conn = null;
try {
conn = getConnection();
Statement stmt = conn.createStatement();
stmt.execute(FETCH_ALL);
ResultSet resultSet = stmt.getResultSet();
List<User> result = marshall(resultSet);
closeStatement(stmt);
return result;
}
catch (SQLException ex) {
ex.printStackTrace();
throw ex;
}
finally {
closeConnection(conn);
}
}
public static User fetch(String id) throws SQLException{
Connection conn = null;
try {
conn = getConnection();
Statement stmt = conn.createStatement();
stmt.execute(USER_FETCH + id + "'");
ResultSet resultSet = stmt.getResultSet();
List<User> result = marshall(resultSet);
closeStatement(stmt);
return result.get(0);
}
catch (SQLException ex) {
ex.printStackTrace();
throw ex;
}
finally {
closeConnection(conn);
}
}
public static User add(User user){
Connection conn = null;
try {
conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(INSERT_USER);
stmt.setString(1, user.getFirstName());
stmt.setString(2, user.getLastName());
stmt.setString(3, user.getEmail());
stmt.setString(4, user.getPassword());
stmt.execute();
closeStatement(stmt);
return user;
}
catch (SQLException ex) {
if (ex.getMessage().contains("Duplicate")) {
System.out.println("Item with duplicate id already exists in repository");
throw new DuplicateItemException("Item with duplicate id already exists in repository");
}
else {
ex.printStackTrace();
System.out.println("Failed to add item to repository");
throw new RepositoryException(ex);
}
}
finally {
closeConnection(conn);
}
}
public static int countusers() throws SQLException{
Connection conn = null;
try {
conn = getConnection();
Statement stmt = conn.createStatement();
stmt.execute(COUNT_ALL_USERS);
ResultSet resultSet = stmt.getResultSet();
int count = 0;
if (resultSet.next()) {
count = resultSet.getInt(1);
}
closeStatement(stmt);
return count;
}
catch (SQLException ex) {
ex.printStackTrace();
throw ex;
}
finally {
closeConnection(conn);
}
}
public static void reset() throws SQLException{
Connection conn = null;
try {
conn = getConnection();
Statement stmt = conn.createStatement();
stmt.executeUpdate(DELETE_ALL);
closeStatement(stmt);
}
catch (SQLException ex) {
ex.printStackTrace();
throw ex;
}
finally {
closeConnection(conn);
}
}
private static List<User> marshall(ResultSet result) throws SQLException{
List<User> list = new ArrayList<User>();
if (result == null) {
return list;
}
while (result.next()) {
String firstName = result.getString(FIRSTNAME);
String lastName = result.getString(LASTNAME);
String email = result.getString(EMAIL);
String passwd = result.getString(PASSWORD);
User user = new User(passwd, true, firstName, lastName, email);
list.add(user);
}
return list;
}
private static DataSource getDataSource(){
DataSource ds = null;
try {
ds = (DataSource) envCtx.lookup(DS_NAME);
}
catch (NamingException ex) {
ex.printStackTrace();
throw new RepositoryException("Failed to get DataSource");
}
return ds;
}
public static Connection getConnection(){
Connection con = null;
try {
con = getDataSource().getConnection();
}
catch (SQLException ex) {
ex.printStackTrace();
throw new RepositoryException("Failed to get connection to database server");
}
catch (Exception ex) {
con = getDirectConnection();
}
return con;
}
private static Connection getDirectConnection(){
try {
String conURL = "jdbc:mysql://localhost:3306/ysg?serverTimezone=UTC&useSSL=false&" + "user=sen301&password=sen301";
return DriverManager.getConnection(conURL);
}
catch (SQLException ex) {
ex.printStackTrace();
throw new RepositoryException("Failed to get direct connection to database server");
}
catch (Exception ex) {
ex.printStackTrace();
throw new RepositoryException(ex);
}
}
private static void closeStatement(Statement stmt){
if (stmt != null) {
try {
stmt.close();
stmt = null;
}
catch (SQLException ex) {
ex.printStackTrace();
}
}
}
private static void closeConnection(Connection conn){
if (conn != null) {
try {
conn.close();
conn = null;
}
catch (SQLException e) {
e.printStackTrace();
}
}
}
}
I'm trying to display all the data from different database table into a JTable using reflection but when i run the code I gen this kind of error:. The methods responsible for that are createViewAllQuery, ViewAll and createObjects from AbstractDAO class.
Any idea what the problem is? Thanks!
package project3;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import com.mysql.jdbc.PreparedStatement;
public class AbstractDAO<T>{
protected static final Logger LOGGER = Logger.getLogger(AbstractDAO.class.getName());
private final Class<T> type;
#SuppressWarnings("unchecked")
public AbstractDAO() {
this.type = (Class<T>)((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
private String createFindQuery(String field) {
StringBuilder sb = new StringBuilder();
sb.append("SELECT ");
sb.append(" * ");
sb.append(" FROM ");
sb.append(type.getSimpleName());
sb.append(" WHERE " + field + "=?");
return sb.toString();
}
private String createAddQuery(T object) throws IllegalArgumentException, IllegalAccessException {
StringBuilder sb = new StringBuilder();
sb.append("INSERT INTO ");
sb.append(type.getSimpleName());
sb.append(" VALUES (");
for(Field field : object.getClass().getDeclaredFields()) {
field.setAccessible(true);
if(field.get(object) instanceof Integer) {
sb.append(field.get(object));
sb.append(",");
}
else {
sb.append("'");
sb.append(field.get(object));
sb.append("',");
}
}
sb.deleteCharAt(sb.length()-1);
sb.append(");");
System.out.println(sb.toString());
return sb.toString();
}
private String createViewAllQuery() throws IllegalArgumentException, IllegalAccessException {
StringBuilder sb = new StringBuilder();
sb.append("SELECT * FROM ");
sb.append(type.getSimpleName());
sb.append(";");
return sb.toString();
}
public List<T> ViewAll() throws IllegalArgumentException, IllegalAccessException {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
String query = createViewAllQuery();
try {
connection = ConnectionFactory.getConnection();
statement = (PreparedStatement) connection.prepareStatement(query);
resultSet = statement.executeQuery();
return createObjects(resultSet);
} catch(SQLException e) {
LOGGER.log(Level.WARNING, type.getName() + "DAO:findByFirstName " + e.getMessage());
} finally {
ConnectionFactory.close(resultSet);
ConnectionFactory.close(statement);
ConnectionFactory.close(connection);
}
return null;
}
public JTable createTable(List<T> objects) throws IllegalArgumentException, IllegalAccessException {
ArrayList<String> columnNamesArrayList = new ArrayList<String>();
for(Field field : objects.get(0).getClass().getDeclaredFields()) {
field.setAccessible(true);
columnNamesArrayList.add(field.getName());
}
String[] columnNames = new String[columnNamesArrayList.size()];
columnNames = columnNamesArrayList.toArray(columnNames);
DefaultTableModel tableModel = new DefaultTableModel(columnNames, 0);
Iterator<T> i = objects.iterator();
while(i.hasNext()) {
T object = i.next();
ArrayList<Object> columnDataAsArrayList = new ArrayList<Object>();
for(Field field : object.getClass().getDeclaredFields()) {
field.setAccessible(true);
columnDataAsArrayList.add(field.get(object));
}
Object[] columnDataAsArray = new Object[columnDataAsArrayList.size()];
columnDataAsArray = columnDataAsArrayList.toArray(columnDataAsArray);
tableModel.addRow(columnDataAsArray);
}
JTable table = new JTable(tableModel);
return table;
}
public void add(T object) throws IllegalArgumentException, IllegalAccessException {
Connection connection = null;
PreparedStatement statement = null;
String query = createAddQuery(object);
try {
connection = ConnectionFactory.getConnection();
statement = (PreparedStatement) connection.prepareStatement(query);
statement.executeUpdate();
} catch(SQLException e) {
LOGGER.log(Level.WARNING, type.getName() + "DAO:findByFirstName " + e.getMessage());
} finally {
ConnectionFactory.close(statement);
ConnectionFactory.close(connection);
}
}
public List<T> findByFirstName(String firstName) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
String query = createFindQuery("first_name");
try {
connection = ConnectionFactory.getConnection();
statement = (PreparedStatement) connection.prepareStatement(query);
statement.setString(1, firstName);
resultSet = statement.executeQuery();
return createObjects(resultSet);
} catch(SQLException e) {
LOGGER.log(Level.WARNING, type.getName() + "DAO:findByFirstName " + e.getMessage());
} finally {
ConnectionFactory.close(resultSet);
ConnectionFactory.close(statement);
ConnectionFactory.close(connection);
}
return null;
}
public T findById(int id) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
String query = createFindQuery("id");
try {
connection = ConnectionFactory.getConnection();
statement = (PreparedStatement) connection.prepareStatement(query);
statement.setInt(1, id);
resultSet = statement.executeQuery();
return createObjects(resultSet).get(0);
} catch(SQLException e) {
LOGGER.log(Level.WARNING, type.getName() + "DAO:findById " + e.getMessage());
} finally {
ConnectionFactory.close(resultSet);
ConnectionFactory.close(statement);
ConnectionFactory.close(connection);
}
return null;
}
private List<T> createObjects(ResultSet resultSet){
List<T> list = new ArrayList<T>();
try {
try {
while(resultSet.next()) {
T instance = type.newInstance();
for(Field field: type.getDeclaredFields()) {
Object value = resultSet.getObject(field.getName());
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), type);
Method method = propertyDescriptor.getWriteMethod();
method.invoke(instance, value);
}
list.add(instance);
}
} catch (IllegalAccessException | SecurityException | IllegalArgumentException | InvocationTargetException | SQLException | IntrospectionException e) {
e.printStackTrace();
}
}catch(InstantiationException e) {
e.printStackTrace();
}
return list;
}
}
package project3;
import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.text.html.HTMLDocument.Iterator;
public class ProductsDAO extends AbstractDAO<Products>{
public ProductsDAO() {};
public static void main(String[] args) {
ProductsDAO p1 = new ProductsDAO();
//Products product1 = new Products(3, "cascaval", 5, " tip de branza facuta din lapte de vaca sau oaie", 4680);
try {
JTable table = new JTable();
table = p1.createTable(p1.ViewAll());
JFrame frame = new JFrame();
JScrollPane scrollPane = new JScrollPane(table);
frame.add(scrollPane, BorderLayout.CENTER);
frame.setSize(300, 150);
frame.setVisible(true);
/*List<Products> list = new ArrayList<Products>();
list = p1.ViewAll();
java.util.Iterator<Products> i = list.iterator();
while(i.hasNext()) {
Products x = i.next();
System.out.println(x.getDescription());
}*/
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
Here is one of the classes:
package project3;
public class Products {
private int id;
private String name;
private int price;
private String description;
private int stoc;
public Products(int id, String name, int price, String description, int stoc) {
super();
this.id = id;
this.name = name;
this.price = price;
this.description = description;
this.stoc = stoc;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getStoc() {
return stoc;
}
public void setStoc(int stoc) {
this.stoc = stoc;
}
}
Your class Products hasn't got a default-constructor (so no method <init>), but you're trying to use that in
T instance = type.newInstance();
Since the Method isn't there the NoSuchMethodException is thrown.
You either have to add a default-constructor like
public Products() {
...
}
or call the constructor with arguments (probably harder to do ;)
I have a method getalldetails (query) which will get details from the database. I want to call this method in multiple classes and based on query. It should fetch the data from the database. Query will be passed dynamically. I am trying to do in following way. Please correct me and advise me hwo to use only one method for data retrieval in whole project.
I am facing these issues:
Return type of result set and calling of method and re use of result. Please guide me and help me
For eg: In DatabaseDAO.java class
public class DatabaseDAO {
public static void main(String[] args) {
public ResultSet getalldetails(String query){
ResultSet rs = null;
try{
PreparedStatement stmt = con.prepareStatement(query);
rs = stmt.executeQuery();
}
catch (SQLException e){
e.printStackTrace();
}
return rs;
}
}
Suppose , I have two classes Employee and Product.java. I want to call this method in both classes . Below is my code:
public class Employee {
String query ="Select * from Employee";
ResultSet rs=null;
List<EmployeeDto> emp= new ArrayList<EmployeeDto>();
DatabaseDAO.getalldetails(query);
while (rs .has next)
{
EmployeeDto qd=new EmployeeDto();
qd.setidrs.getInt("id"));
qd.setname(rs.getString("name"));
qd.setrollno(rs.getString("rollno"));
emp.add(qd);
}
}
Similarly, I have Product.java . I want to call same method to retrieval data form DB based on query based.
public class Product {
String query ="Select * from Product";
ResultSet rs=null;
List<ProductDto> emp= new ArrayList<ProductDto>();
DatabaseDAO.getalldetails(query);
while (rs .has next)
{
ProductDto qd=new ProductDto();
pd.setidrs.getInt("prodid"));
pd.setname(rs.getString("prodname"));
pd.setrollno(rs.getString("item"));
prod.add(pd);
}
}
I want to use one method in whole project to retrieve the data from DB . Means I want to do reusability of method. Please help me on this.
You can make it a static method in a class. Say Database. And you can access it anywhere by importing the Database class and calling Database.getalldetails (query)
As an aside, i see in your code, that you have defined getalldetails inside the main method. You should put it outside.
In the Employee class, you place code inside a class, but outside a method/constructor. Add a Constructor or a method and put the code there
Well, This can be an example of your concept.
I call it a DBMain class which has a entry point of bot classes, the Product and the Employee class by the DatabaseDAO class.
First, make an instance of the DatabaseDAO class then initialize the database connection.
DatabaseDAO dbDAO = new DatabaseDAO();
dbDAO.initConnection();
Second, create both Employee and Product class with the DatabaseDAO instance as a parameter.
Employee emp = new Employee(dbDAO);
Product prd = new Product(dbDAO);
Finally, you can retrieve the data from both instance of class by calling methods, getEmployeeList and getProductList each then close the connection owned by the DAO class.
try {
emplist = emp.getEmployeeList();
prdlist = prd.getProductList();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
dbDAO.closeConnection();
}
The structure of the classes would be the same,
For example, the getProductList() looks:
public List<ProductDto> getProductList() throws SQLException {
ResultSet rs = null;
List<ProductDto> prd = new ArrayList<ProductDto>();
rs = dataDAO.getalldetails(query);
while (rs.next()) {
ProductDto qd = new ProductDto();
qd.setProdid(rs.getInt("prodid"));
qd.setProdname(rs.getString("prodname"));
qd.setItem(rs.getString("item"));
prd.add(qd);
}
rs.close();
return prd;
}
You can call getalldetails method in the DatabaseDAO instance and make the resultset a list of dto object.
The Employee and Product class:
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class Employee {
private static final String query = "Select * from Employee";
final DatabaseDAO dataDAO;
Employee(final DatabaseDAO dataDAO) {
this.dataDAO = dataDAO;
}
public List<EmployeeDto> getEmployeeList() throws SQLException {
ResultSet rs = null;
List<EmployeeDto> emp = new ArrayList<EmployeeDto>();
rs = dataDAO.getalldetails(query);
while (rs.next()) {
EmployeeDto qd = new EmployeeDto();
qd.setId(rs.getInt("id"));
qd.setName(rs.getString("name"));
qd.setRollno(rs.getString("rollno"));
emp.add(qd);
}
rs.close();
return emp;
}
}
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class Product {
private static final String query = "Select * from Product";
final DatabaseDAO dataDAO;
Product(final DatabaseDAO dataDAO) {
this.dataDAO = dataDAO;
}
public List<ProductDto> getProductList() throws SQLException {
ResultSet rs = null;
List<ProductDto> prd = new ArrayList<ProductDto>();
rs = dataDAO.getalldetails(query);
while (rs.next()) {
ProductDto qd = new ProductDto();
qd.setProdid(rs.getInt("prodid"));
qd.setProdname(rs.getString("prodname"));
qd.setItem(rs.getString("item"));
prd.add(qd);
}
rs.close();
return prd;
}
}
The Dao class - DatabaseDAO, this class has a structure only, you can make your connection object depending on databases.
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DatabaseDAO {
private Connection con;
public DatabaseDAO()
{
}
public void initConnection()
{
}
public Connection getDBConnection()
{
return con;
}
public void closeConnection()
{
try {
this.con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public ResultSet getalldetails(String query) {
ResultSet rs = null;
try {
PreparedStatement stmt = con.prepareStatement(query);
rs = stmt.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
}
The main method class here:
import java.sql.SQLException;
import java.util.List;
public class DBMain {
public static void main(String[] args)
{
DatabaseDAO dbDAO = new DatabaseDAO();
dbDAO.initConnection();
Employee emp = new Employee(dbDAO);
Product prd = new Product(dbDAO);
List<EmployeeDto> emplist = null;
List<ProductDto> prdlist = null;
try {
emplist = emp.getEmployeeList();
prdlist = prd.getProductList();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
dbDAO.closeConnection();
}
}
}
Then, the dto classes left, EmpolyeeDto and ProductDto might be as follows:
public class EmployeeDto {
private int id;
private String name;
private String rollno;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRollno() {
return rollno;
}
public void setRollno(String rollno) {
this.rollno = rollno;
}
}
public class ProductDto {
private int prodid;
private String prodname;
private String item;
public int getProdid() {
return prodid;
}
public void setProdid(int prodid) {
this.prodid = prodid;
}
public String getProdname() {
return prodname;
}
public void setProdname(String prodname) {
this.prodname = prodname;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
}
I got a tableview with a tablecolumn ("ID").
How can i link the ID to show the value?
For example: ID 90 has to be "Shop" and ID 91 has to be "Wallmart"..
I'm using 2 tables:
Person(id, personName, personShopID)
Items(id, shopName)
PersonShopID links to ITEMS id and i have to show the shopName instead of the ID..
Note: I'm using JavaFX and i'm getting data from mysql database and i'm using tcShopName.setCellValueFactory(new PropertyValueFactory<>("personShopID"));
kind regards !
package databag;
import java.sql.Timestamp;
import java.sql.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import vivesgoal.controller.CustomDate;
/**
*
* #author Lowie Menu
*/
public class PersoonBag {
private int id;
private String naam;
private String voornaam;
private Date geboortedatum;
private String opmerking;
private boolean isTrainer;
private int ploeg_id;
public PersoonBag(int id, String naam, String voornaam, Date geboortedatum, String opmerking,boolean isTrainer, int ploeg_id){
this.id=id;
this.naam=naam;
this.voornaam=voornaam;
this.geboortedatum=geboortedatum;
this.opmerking=opmerking;
this.isTrainer=isTrainer;
this.ploeg_id=ploeg_id;
}
public PersoonBag()
{
}
public int getId() {
return id;
}
public String getNaam() {
return naam;
}
public String getVoornaam() {
return voornaam;
}
public Date getGeboortedatum() {
return geboortedatum;
}
public String getGeboortedatumAlter(){
DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
String datum = df.format(geboortedatum);
return datum;
}
public CustomDate getMyDate(){
return new CustomDate(geboortedatum.getTime());
}
public java.util.Date getGeboortedatumUtil(){
return geboortedatum;
}
public String getOpmerking() {
return opmerking;
}
public boolean isIsTrainer() {
return isTrainer;
}
public int getPloeg_id() {
return ploeg_id;
}
public void setId(int id) {
this.id = id;
}
public void setNaam(String naam) {
this.naam = naam;
}
public void setVoornaam(String voornaam) {
this.voornaam = voornaam;
}
public void setGeboortedatum(Date geboortedatum) {
this.geboortedatum =geboortedatum;
}
public void setOpmerking(String opmerking) {
this.opmerking = opmerking;
}
public void setIsTrainer(boolean isTrainer) {
this.isTrainer = isTrainer;
}
public void setPloeg_id(int ploeg_id) {
this.ploeg_id = ploeg_id;
}
}
and class Team (dutch ploeg)
package databag;
/**
*
* #author Lowie Menu
*/
public class PloegBag {
private int id;
private String naam;
private String niveau;
private int trainer_id;
public PloegBag(int id, String naam, String niveau, int trainer_id){
this.id = id;
this.naam = naam;
this.niveau = niveau;
this.trainer_id = trainer_id;
}
public PloegBag(){
}
public void setId(int id) {
this.id = id;
}
public void setNaam(String naam) {
this.naam = naam;
}
public void setNiveau(String niveau) {
this.niveau = niveau;
}
public void setTrainer_id(int trainer_id){
this.trainer_id=trainer_id;
}
public int getId() {
return id;
}
public String getNaam() {
return naam;
}
public String getNiveau() {
return niveau;
}
public int getTrainer_id(){
return trainer_id;
}
}
Note: i'm trying to link ploeg_id from PersoonBag to the name of PloegBag(ploegnaam).
This sql code gets me the name of the club matching the id
select * from persoon AS p INNER JOIN ploeg AS ploeg ON p.ploeg_id =ploeg.id where ploeg.naam=?"
Update: no value in ploeg.naam? maybe issue here
p
ublic ArrayList<PersoonBag> zoekAlleSpelers() throws DBException, ApplicationException {
ArrayList<PersoonBag> pb = new ArrayList<>();
try (Connection conn = ConnectionManager.getConnection();) {
try(PreparedStatement stmt = conn.prepareStatement(
"select * from persoon inner join ploeg where persoon.ploeg_id = ploeg.id");) {
// execute voert elke sql-statement uit, executeQuery enkel de eenvoudige
stmt.execute();
// result opvragen (en automatisch sluiten)
try (ResultSet rs = stmt.getResultSet()) {
// van alle rekennigen uit de database,
// RekeningBag-objecten maken en in een RekeningVector steken
while (rs.next()) {
PersoonBag p = new PersoonBag();
PloegBag ploeg = new PloegBag();
// ploeg.setId(rs.getInt("id"));
ploeg.setNaam(rs.getString("naam"));
p.setId(rs.getInt("id"));
p.setNaam(rs.getString("naam"));
p.setVoornaam(rs.getString("voornaam"));
p.setGeboortedatum(rs.getDate("geboortedatum"));
p.setOpmerking(rs.getString("opmerking"));
p.setIsTrainer(rs.getBoolean("isTrainer"));
p.setPloeg_id(ploeg);
pb.add(p);
}
return pb;
} catch (SQLException sqlEx) {
throw new DBException(
"SQL-exception in zoekAlleRekeningen - resultset");
}
} catch (SQLException sqlEx) {
throw new DBException(
"SQL-exception in zoekAlleRekeningen - statement");
}
} catch (SQLException sqlEx) {
throw new DBException(
"SQL-exception in zoekAlleRekeningen - connection");
}
}
Still have'nt found the issue.. this is function to store the data from the sql query in the table note: this works only ploegname isn't showing
PersoonDB pdb = new PersoonDB();
ArrayList<PersoonBag> persoonbag = new ArrayList<>();
try {
ArrayList<PersoonBag> spelersLijst = pdb.zoekAlleSpelers();
for (PersoonBag r : spelersLijst) {
PersoonBag speler = new PersoonBag(r.getId(),r.getNaam(), r.getVoornaam(),r.getMyDate(),r.getOpmerking(), r.isIsTrainer(),r.getPloeg_id());
persoonbag.add(speler);
}
ObservableList<PersoonBag> spelers = FXCollections.observableArrayList(persoonbag);
taSpelers.setItems(spelers);
Cell items:
#FXML
private TableView<PersoonBag> taSpelers;
#FXML
private TableColumn tcFamilienaam;
#FXML
private TableColumn tcVoornaam;
#FXML
private TableColumn tcOpmerking;
#FXML
private TableColumn<PersoonBag, CustomDate> tcGeboortedatum;
#FXML
private TableColumn<PersoonBag, PloegBag> tcPloeg;
#Override
public void initialize(URL url, ResourceBundle rb) {
tcFamilienaam.setCellValueFactory(new PropertyValueFactory<>("naam"));
tcVoornaam.setCellValueFactory(new PropertyValueFactory<>("voornaam"));
tcGeboortedatum.setCellValueFactory(new PropertyValueFactory<PersoonBag, CustomDate>("geboortedatum"));
tcOpmerking.setCellValueFactory(new PropertyValueFactory<>("opmerking"));
tcPloeg.setCellValueFactory(new PropertyValueFactory<>("ploeg"));
tcPloeg.setCellFactory(tc -> new TableCell<PersoonBag, PloegBag>() {
#Override
public void updateItem(PloegBag ploeg, boolean empty) {
if (empty || ploeg ==null){
setText("");
} else{
setText(ploeg.getNaam());
}
}
});
UPDATE!!! i'm almost there! It's getting the 'naam' data from persoon instead of 'naam' from ploeg!
issue:
while (rs.next()) {
PloegBag ploeg = new PloegBag();
ploeg.setId(rs.getInt("id"));
ploeg.setNaam(rs.getString("naam"));
PersoonBag p = new PersoonBag();
p.setId(rs.getInt("id"));
p.setNaam(rs.getString("naam"));
p.setVoornaam(rs.getString("voornaam"));
p.setGeboortedatum(rs.getDate("geboortedatum"));
p.setOpmerking(rs.getString("opmerking"));
p.setIsTrainer(rs.getBoolean("isTrainer"));
p.setPloeg(ploeg);
pb.add(p);
}
when i'm putting niveau instead of 'naam' it's get me the correct matching result! now i need the name..!
Instead of storing the id of the linked item, store a reference to the item itself. So your PersoonBag class will look like:
public class PersoonBag {
private int id;
private String naam;
private String voornaam;
private Date geboortedatum;
private String opmerking;
private boolean isTrainer;
private PloegBag ploeg;
public PersoonBag(int id, String naam, String voornaam, Date geboortedatum, String opmerking,boolean isTrainer, PloegBag ploeg){
this.id=id;
this.naam=naam;
this.voornaam=voornaam;
this.geboortedatum=geboortedatum;
this.opmerking=opmerking;
this.isTrainer=isTrainer;
this.ploeg=ploeg;
}
public PersoonBag()
{
}
public PloegBag getPloeg() {
return ploeg ;
}
public void setPloeg(PloegBag ploeg) {
this.ploeg = ploeg ;
}
// other get/set methods ...
}
Now you can load everything at once using an inner join in the SQL:
String sql = "select * from persoon inner join ploeg where persoon.ploeg_id = ploeg.id";
PreparedStatement statement = connection.prepareStatement(sql);
ResultSet rs = statement.executeQuery();
List<Persoon> persoonList = new ArrayList<>();
while (rs.next()) {
PloegBag ploeg = new PloegBag();
// populate ploeg with data from rs...
PersoonBag persoon = new PersoonBag();
persoon.setPloeg(ploeg);
// populate persoon with remaining data from rs...
persoonList.add(persoon);
}
(Obviously you can modify the SQL code, e.g. to retrieve specific items from the database, or just generally to improve it, etc.)
Now your JavaFX code looks like:
TableView<PersoonBag> persoonTable = new TableView<>();
TableColumn<PersoonBag, PloegBag> tcPloeg = new TableColumn<>("Ploeg");
tcPloeg.setCellValueFactory(new PropertyValueFactory<>("ploeg"));
// other columns...
To get the cells to display the value you need from the PloegBag, there are two ways. The "quick and dirty" way is just to define a toString() method in the PloegBag class:
public class PloegBag {
// ...
#Override
public String toString() {
return naam ;
}
}
This isn't very satisfactory, though, as you might want to toString() method to do something else for other reasons in your application. The "proper" way is to use a cell factory:
tcPloeg.setCellFactory(tc -> new TableCell<PersoonBag, PloegBag>() {
#Override
public void updateItem(PloegBag ploeg, boolean empty) {
if (empty || ploeg == null) {
setText(null);
} else {
setText(ploeg.getNaam());
}
}
});
1) establish a Connection to your database from your Java-program by using JDBC:
private static Connection getDBConnection() {
Connection connection = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDatabase?autoReconnect=true&user=myUser&password=myPass");
} catch (ClassNotFoundException | SQLException e) {
System.out.println("Error on getDBCOnnection "+e.toString());
}
return connection;
}
2) Query your Items table in a query like this:
SELECT shopName FROM Items WHERE ID = 90
Java:
public static ResultSet runQuery(String query) {
if(conn == null){
conn = getDBConnection();
}
Statement stmt;
ResultSet rs;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery(query);
return rs;
} catch (SQLException e) {
System.out.println(e + " " + e.getMessage());
return null;
}
}
3) Read the result
ResultSet rs = runQuery(query);
String result = rs.getString(1);
Hibernate could do it all for you, including queries... just saying... Although steep learning curve if doing it for the first time... You need to model your container object to have these fields, for example person would have:
class Person{
long id;
String name;
String shopName;
...
}
Then in your data service (provider of data) you would query for that, lets say:
SELECT p.id, p.name, s.name
FROM person p, shop s
WHERE p.shopId = s.shopId;
and provide simple rowmapper
#Ovrride
public Person mapRow(ResultSet rs, int rowNum) throws SQLException {
Person person = new Person(rs.getInt("personId"), rs.getString("personName"), rs.getString("shopName"));
return person;
}
You end up with list of Persons, which you can operate on within app. As someone mentioned earlier, you would want to do this, beforehand. Every time you need that list you would hit a local cache, instead of going back to DB. You could set a policy to refresh cache if needed.