Commit 01641dd7 by Patryk Czarnik

dostęp do bazy danych sklep

parent ddbe504e
package sklep.db;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import sklep.model.Customer;
public class CustomerDAO {
private final DBConnection db;
CustomerDAO(DBConnection db) {
this.db = db;
}
public Customer findByEmail(String email) throws DBException, RecordNotFound {
final String sql = "SELECT * FROM customers WHERE customer_email = ?";
try (PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql)) {
stmt.setString(1, email);
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
return customerFromRS(rs);
} else {
throw new RecordNotFound("Cannot find customer with email " + email);
}
}
} catch (SQLException e) {
throw new DBException("SQL error in CustomerDAO.findById: " + e.getMessage(), e);
}
}
public List<Customer> readAll() throws DBException {
final String sql = "SELECT * FROM customers";
try (PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql)) {
try (ResultSet rs = stmt.executeQuery()) {
return customerListFromRS(rs);
}
} catch (SQLException e) {
throw new DBException("SQL error in CustomerDAO.readAll: " + e.getMessage(), e);
}
}
private List<Customer> customerListFromRS(ResultSet rs) throws SQLException {
List<Customer> records = new ArrayList<>();
while (rs.next()) {
Customer product = customerFromRS(rs);
records.add(product);
}
return records;
}
private Customer customerFromRS(ResultSet rs) throws SQLException {
return new Customer(
rs.getString("customer_email"),
rs.getString("customer_name"),
rs.getString("phone_number"),
rs.getString("address"),
rs.getString("postal_code"),
rs.getString("city"));
}
public void insert(Customer customer) throws DBException {
// używać gdy obiekt ma wpisane ID (tu: email)
final String sql = "INSERT INTO customers("
+ "customer_email, customer_name, phone_number, address, postal_code, city)"
+ " VALUES (?, ?, ?, ?, ?, ?)";
try(PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql)) {
stmt.setString(1, customer.getEmail());
stmt.setString(2, customer.getName());
stmt.setString(3, customer.getPhoneNumber());
stmt.setString(4, customer.getAddress());
stmt.setString(5, customer.getPostalCode());
stmt.setString(6, customer.getCity());
stmt.executeUpdate();
} catch (SQLException e) {
throw new DBException("Error during INSERT CUSTOMER", e);
}
}
public boolean update(Customer customer) throws DBException {
final String sql = "UPDATE customers SET "
+ " customer_name=?, phone_number=?, address=?, postal_code=?, city=?"
+ " WHERE customer_email = ?";
try(PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql)) {
stmt.setString(1, customer.getName());
stmt.setString(2, customer.getPhoneNumber());
stmt.setString(3, customer.getAddress());
stmt.setString(4, customer.getPostalCode());
stmt.setString(5, customer.getCity());
stmt.setString(6, customer.getEmail());
int count = stmt.executeUpdate();
return count > 0;
} catch (SQLException e) {
throw new DBException("Error during UPDATE CUSTOMER", e);
}
}
public void save(Customer customer) throws DBException {
if(customer.getEmail() == null) {
throw new IllegalArgumentException("Customer email cannot be null");
} else {
if(! update(customer)) {
insert(customer);
}
}
}
public boolean delete(String email) throws DBException {
final String sql = "DELETE FROM customers WHERE customer_email = ?";
try(PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql)) {
stmt.setString(1, email);
int count = stmt.executeUpdate();
return count > 0;
} catch (SQLException e) {
throw new DBException("Error during DELETE CUSTOMER", e);
}
}
public boolean delete(Customer customer) throws DBException {
return delete(customer.getEmail());
}
}
package sklep.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class DBConnection implements AutoCloseable {
private Connection sqlConnection;
private DBConnection(Connection sqlConnection) {
this.sqlConnection = sqlConnection;
}
public static DBConnection open() throws DBException {
return open(false);
}
public static DBConnection open(boolean autoCommit) throws DBException {
try {
Properties props = DBSettings.load();
if(props.containsKey("driver_class")) {
Class.forName(props.getProperty("driver_class"));
}
Connection c = DriverManager.getConnection(props.getProperty("url") , props);
c.setAutoCommit(autoCommit);
return new DBConnection(c);
} catch (ClassNotFoundException | SQLException e) {
throw new DBException("Cannot connect to postgresql: " + e, e);
}
}
public static DBConnection openLocalhost() throws DBException {
try {
Connection c = DriverManager.getConnection("jdbc:postgresql://localhost/sklep", "kurs", "abc123");
c.setAutoCommit(false);
return new DBConnection(c);
} catch (SQLException e) {
throw new DBException("Cannot connect to postgresql: " + e, e);
}
}
@Override
public void close() {
try {
if (sqlConnection != null) {
sqlConnection.close();
sqlConnection = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public Connection getSqlConnection() {
return sqlConnection;
}
public void commit() throws DBException {
try {
sqlConnection.commit();
} catch (SQLException e) {
throw new DBException("Error during commit: " + e.getMessage(), e);
}
}
public void rollback() throws DBException {
try {
sqlConnection.rollback();
} catch (SQLException e) {
throw new DBException("Error during rollback: " + e.getMessage(), e);
}
}
public ProductDAO productDAO() {
return new ProductDAO(this);
}
public CustomerDAO customerDAO() {
return new CustomerDAO(this);
}
public OrderDAO orderDAO() {
return new OrderDAO(this);
}
}
package sklep.db;
public class DBException extends SklepException {
public DBException() {
super();
}
public DBException(String message, Throwable cause) {
super(message, cause);
}
public DBException(String message) {
super(message);
}
}
package sklep.db;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class DBSettings {
public static final String DB_SETTINGS_SYSTEM_PROPERTY = "sklep.db_settings_location";
private static final String INTERNAL_DEFAULT_PROPERTIES = "/sklep.properties";
private static DBSettings dbSettings; // singleton
private final Properties props;
private DBSettings() throws DBException {
props = new Properties();
String systemProperty = System.getProperty(DB_SETTINGS_SYSTEM_PROPERTY);
try(InputStream input = systemProperty != null
? new FileInputStream(new File(systemProperty))
: DBSettings.class.getResourceAsStream(INTERNAL_DEFAULT_PROPERTIES) ) {
props.load(input);
} catch (IOException e) {
//e.printStackTrace();
throw new DBException("Cannot read settings. " + e, e);
}
}
public static synchronized DBSettings getInstance() throws DBException {
// Dla klasy typu "singleton" w aplikacji powstaje tylko jedna instancja (obiekt) tej klasy.
// Dostęp do tego obiektu odbywa się poprzez metodę statyczną taką jak ta.
// Tutaj mamy "leniwą inicjalizację", czyli obiekt jest tworzony przy pierwszej próbie dostepu.
if(dbSettings == null) {
dbSettings = new DBSettings();
}
return dbSettings;
}
public Properties getProperties() {
return props;
}
public static Properties load() throws DBException {
return getInstance().getProperties();
}
}
package sklep.db;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import sklep.model.Order;
import sklep.model.OrderProduct;
public class OrderDAO {
private static final String[] ID_COLUMNS = {"order_id", "order_date"};
private final DBConnection db;
OrderDAO(DBConnection db) {
this.db = db;
}
public Order findById(int orderId) throws DBException, RecordNotFound {
final String sql = "SELECT * FROM orders WHERE order_id = ?";
try (PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql)) {
stmt.setInt(1, orderId);
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
return orderFromRS(rs);
} else {
throw new RecordNotFound("Cannot find order with id " + orderId);
}
}
} catch (SQLException e) {
throw new DBException("SQL error in OrderDAO.findById: " + e.getMessage(), e);
}
}
public List<Order> readAll() throws DBException {
final String sql = "SELECT * FROM orders ORDER BY order_id";
try (PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql)) {
try (ResultSet rs = stmt.executeQuery()) {
return orderListFromRS(rs);
}
} catch (SQLException e) {
throw new DBException("SQL error in OrderDAO.readAll: " + e.getMessage(), e);
}
}
public List<Order> customerOrders(String email) throws DBException {
final String sql = "SELECT * FROM orders WHERE customer_email = ? ORDER BY order_id";
try (PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql)) {
stmt.setString(1, email);
try (ResultSet rs = stmt.executeQuery()) {
return orderListFromRS(rs);
}
} catch (SQLException e) {
throw new DBException("SQL error in OrderDAO.customerOrders: " + e.getMessage(), e);
}
}
private List<Order> orderListFromRS(ResultSet rs) throws SQLException, DBException {
List<Order> orders = new ArrayList<>();
while (rs.next()) {
Order order = orderFromRS(rs);
orders.add(order);
}
return orders;
}
private Order orderFromRS(ResultSet rs) throws SQLException, DBException {
Order order = Order.ofDbFields(
rs.getInt("order_id"),
rs.getString("customer_email"),
rs.getTimestamp("order_date"),
rs.getString("status"));
order.addProducts(orderProductsForOrder(order.getOrderId()));
return order;
}
List<OrderProduct> orderProductsForOrder(int orderId) throws DBException {
final String sql = "SELECT * FROM order_products WHERE order_id = ? ORDER BY product_id";
try (PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql)) {
stmt.setInt(1, orderId);
try (ResultSet rs = stmt.executeQuery()) {
List<OrderProduct> ops = new ArrayList<>();
while(rs.next()) {
ops.add(orderProductFromRS(rs));
}
return ops;
}
} catch (SQLException e) {
throw new DBException("SQL error in OrderDAO.customerOrders: " + e.getMessage(), e);
}
}
private OrderProduct orderProductFromRS(ResultSet rs) throws SQLException {
return new OrderProduct(rs.getInt("order_id"), rs.getInt("product_id"), rs.getInt("quantity"), rs.getBigDecimal("actual_price"));
}
}
package sklep.db;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import sklep.model.Product;
/* DAO - Data Access Object(s)
Dostęp do baz danych oparty o takie zasady:
tabelom bazodanowym odpowiadają klasy w naszej aplikacji
np. dla tabeli products mamy klasę Product (w pakiecie model)
dla takie pary tabela products + klasa Product tworzymy klasę narzędziową ProductDAO , której zadaniem jest obsługa tej tabeli: odczyt, zapis, wyszukiwanie, i inne operacje jeśli są potrzebne.
*/
public class ProductDAO {
private static final BigDecimal MAX_PRICE = new BigDecimal(1_000_000_000);
private static final String[] ID_COLUMNS = {"product_id"};
private final DBConnection db;
ProductDAO(DBConnection db) {
this.db = db;
}
public Product findById(int productId) throws DBException, RecordNotFound {
final String sql = "SELECT * FROM products WHERE product_id = ?";
try (PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql)) {
stmt.setInt(1, productId);
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
return productFromRS(rs);
} else {
throw new RecordNotFound("Cannot find product with id " + productId);
}
}
} catch (SQLException e) {
throw new DBException("SQL error in ProductDAO.findById: " + e.getMessage(), e);
}
}
public List<Product> readAll() throws DBException {
final String sql = "SELECT * FROM products ORDER BY product_id";
try (PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql)) {
try (ResultSet rs = stmt.executeQuery()) {
return productListFromRS(rs);
}
} catch (SQLException e) {
throw new DBException("SQL error in ProductDAO.readAll: " + e.getMessage(), e);
}
}
public List<Product> findByPrice(BigDecimal minPrice, BigDecimal maxPrice) throws DBException {
final String sql = "SELECT * FROM products WHERE price BETWEEN ? AND ? ORDER BY product_id";
if(minPrice == null)
minPrice = BigDecimal.ZERO;
if(maxPrice == null)
maxPrice = MAX_PRICE;
try (PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql)) {
stmt.setBigDecimal(1, minPrice);
stmt.setBigDecimal(2, maxPrice);
try (ResultSet rs = stmt.executeQuery()) {
return productListFromRS(rs);
}
} catch (SQLException e) {
throw new DBException("SQL error in ProductDAO.findByPrice: " + e.getMessage(), e);
}
}
private List<Product> productListFromRS(ResultSet rs) throws SQLException {
List<Product> products = new ArrayList<>();
while (rs.next()) {
Product product = productFromRS(rs);
products.add(product);
}
return products;
}
private Product productFromRS(ResultSet rs) throws SQLException {
return new Product(
rs.getInt("product_id"),
rs.getString("product_name"),
rs.getBigDecimal("price"),
rs.getBigDecimal("vat"),
rs.getString("description"));
}
public void insert(Product product) throws DBException {
// używać gdy obiekt ma wpisane ID
final String sql = "INSERT INTO products("
+ " product_id, product_name, price, vat, description)"
+ " VALUES (?, ?, ?, ?, ?)";
try(PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql)) {
stmt.setInt(1, product.getProductId());
stmt.setString(2, product.getProductName());
stmt.setBigDecimal(3, product.getPrice());
stmt.setBigDecimal(4, product.getVat());
stmt.setString(5, product.getDescription());
stmt.executeUpdate();
} catch (SQLException e) {
throw new DBException("Error during INSERT PRODUCT", e);
}
}
public void insertNew(Product product) throws DBException {
// używać gdy obiekt nie ma wpisanego ID (productID == null)
final String sql = "INSERT INTO products("
+ " product_name, price, vat, description)"
+ " VALUES (?, ?, ?, ?)";
try(PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql, ID_COLUMNS)) {
stmt.setString(1, product.getProductName());
stmt.setBigDecimal(2, product.getPrice());
stmt.setBigDecimal(3, product.getVat());
stmt.setString(4, product.getDescription());
stmt.executeUpdate();
try (ResultSet rs = stmt.getGeneratedKeys()) {
if(rs.next()) {
// w obiekcie, który mamy w pamięci, uzupełniamy brakujące ID na podstawie tego, co wygenerowała baza
product.setProductId(rs.getInt(1));
}
};
} catch (SQLException e) {
throw new DBException("Error during INSERT PRODUCT", e);
}
}
public boolean update(Product product) throws DBException {
final String sql = "UPDATE products SET "
+ " product_name = ?, price = ?, vat = ?, description = ?"
+ " WHERE product_id = ?";
try(PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql)) {
stmt.setString(1, product.getProductName());
stmt.setBigDecimal(2, product.getPrice());
stmt.setBigDecimal(3, product.getVat());
stmt.setString(4, product.getDescription());
stmt.setInt(5, product.getProductId());
int count = stmt.executeUpdate();
return count > 0;
} catch (SQLException e) {
throw new DBException("Error during UPDATE PRODUCT", e);
}
}
public void save(Product product) throws DBException {
if(product.getProductId() == null) {
// wstawiamy nowy rekord korzystajac z sekwecji
insertNew(product);
} else {
if(! update(product)) {
insert(product);
}
}
}
public boolean delete(int productId) throws DBException {
final String sql = "DELETE FROM products WHERE product_id = ?";
try(PreparedStatement stmt = db.getSqlConnection().prepareStatement(sql)) {
stmt.setInt(1, productId);
int count = stmt.executeUpdate();
return count > 0;
} catch (SQLException e) {
throw new DBException("Error during DELETE PRODUCT", e);
}
}
public boolean delete(Product product) throws DBException {
return delete(product.getProductId());
}
}
package sklep.db;
public class RecordNotFound extends SklepException {
public RecordNotFound() {
super();
}
public RecordNotFound(String message) {
super(message);
}
}
package sklep.db;
public class SklepException extends Exception {
public SklepException() {
super();
}
public SklepException(String message, Throwable cause) {
super(message, cause);
}
public SklepException(String message) {
super(message);
}
public SklepException(Throwable cause) {
super(cause);
}
}
url=jdbc:postgresql://localhost:5432/sklep
driver_class=org.postgresql.Driver
user=kurs
password=abc123
photo_dir=/home/patryk/sklep/foto
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment