diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a7d3c9d --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.idea/* +.class +out/ +target/ +logs/ \ No newline at end of file diff --git a/Accounting report.iml b/Accounting report.iml new file mode 100644 index 0000000..7a83844 --- /dev/null +++ b/Accounting report.iml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9213630 --- /dev/null +++ b/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + groupId + Accounting report + 1.0-SNAPSHOT + + + mysql + mysql-connector-java + 8.0.18 + + + org.projectlombok + lombok + 1.18.10 + + + + + \ No newline at end of file diff --git a/src/main/java/sample/Controller.java b/src/main/java/sample/Controller.java new file mode 100644 index 0000000..e27c1ed --- /dev/null +++ b/src/main/java/sample/Controller.java @@ -0,0 +1,118 @@ +package sample; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.scene.control.TableView; +import javafx.scene.control.TextField; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.input.MouseEvent; +import sample.dao.ProductDao; +import sample.model.Product; +import javafx.scene.control.TableColumn; +public class Controller { + + @FXML + public TextField fieldId; + @FXML + public TextField fieldName; + @FXML + public TextField fieldType; + @FXML + public TextField fieldWholesalePrice; + @FXML + public TextField fieldRetailPrice; + @FXML + public TextField fieldProvider; + @FXML + public TextField fieldCount; + ProductDao productDao = new ProductDao(); + private ObservableList productList = FXCollections.observableArrayList(); + @FXML + private TableView tableProduct; + @FXML + private TableColumn idColumn; + @FXML + private TableColumn nameColumn; + @FXML + private TableColumn typeColumn; + @FXML + private TableColumn wholesalePriceColumn; + @FXML + private TableColumn retailPriceColumn; + @FXML + private TableColumn providerColumn; + @FXML + private TableColumn countColumn; + + + // инициализируем форму данными + @FXML + private void initialize() { + initData(); + + // устанавливаем тип и значение которое должно хранится в колонке + idColumn.setCellValueFactory(new PropertyValueFactory("id")); + nameColumn.setCellValueFactory(new PropertyValueFactory("name")); + typeColumn.setCellValueFactory(new PropertyValueFactory("type")); + wholesalePriceColumn.setCellValueFactory(new PropertyValueFactory("wholesale_price")); + retailPriceColumn.setCellValueFactory(new PropertyValueFactory("retail_price")); + providerColumn.setCellValueFactory(new PropertyValueFactory("provider_id")); + countColumn.setCellValueFactory(new PropertyValueFactory("count")); + + + + // заполняем таблицу данными + tableProduct.setItems(productList); + + } + + // подготавливаем данные для таблицы + // вы можете получать их с базы данных + private void initData() { + + productList.addAll(productDao.getAll()); + +/* + productList.add(new Product(1, "Xiaomi A1","Телефон",500,600,0,1)); + productList.add(new Product(2, "Samsung Galaxy S5","Телефон",800,100,0,1)); + productList.add(new Product(3, "Iphone XS", "Телефон", 1000,1200,0,1)); + productList.add(new Product(4, "Nokia", "Телефон", 20,21,0,1)); + productList.add(new Product(5, "Samsung HotBench", "Мікрохвильова піч", 1000,1200,0,1)); + + for(Product product:productList) + productDao.create(product); +*/ + } + + public void onClickTableView(MouseEvent mouseEvent) { + int index = tableProduct.getSelectionModel().getSelectedIndex(); + fieldId.setText(Integer.toString(tableProduct.getSelectionModel().getTableView().getItems().get(index).getId())); + fieldName.setText(tableProduct.getSelectionModel().getTableView().getItems().get(index).getName()); + fieldType.setText(tableProduct.getSelectionModel().getTableView().getItems().get(index).getType()); + fieldRetailPrice.setText(Integer.toString(tableProduct.getSelectionModel().getTableView().getItems().get(index).getRetail_price())); + fieldWholesalePrice.setText(Integer.toString(tableProduct.getSelectionModel().getTableView().getItems().get(index).getWholesale_price())); + fieldProvider.setText(Integer.toString(tableProduct.getSelectionModel().getTableView().getItems().get(index).getProvider_id())); + fieldCount.setText(Integer.toString(tableProduct.getSelectionModel().getTableView().getItems().get(index).getCount())); + } + + public void onClickApply(MouseEvent mouseEvent) { + Product product = new Product(Integer.valueOf(fieldId.getText()),fieldName.getText(),fieldType.getText(), Integer.valueOf(fieldWholesalePrice.getText()),Integer.valueOf(fieldRetailPrice.getText()),Integer.valueOf(fieldProvider.getText()),Integer.valueOf(fieldCount.getText())); + if(!fieldId.getText().isEmpty() && productDao.findByID(Integer.valueOf(fieldId.getText()))!=null){ + productDao.updateProduct(product); + }else{ + productDao.create(product); + } + productList.clear(); + productList.addAll(productDao.getAll()); + + } + + public void onClickDelete(MouseEvent mouseEvent) { + if (!fieldId.getText().isEmpty() && productDao.findByID(Integer.valueOf(fieldId.getText())) != null) { + productDao.deleteById(Integer.valueOf(fieldId.getText())); + } + productList.clear(); + productList.addAll(productDao.getAll()); + } +} \ No newline at end of file diff --git a/src/main/java/sample/Main.java b/src/main/java/sample/Main.java new file mode 100644 index 0000000..31e20c6 --- /dev/null +++ b/src/main/java/sample/Main.java @@ -0,0 +1,26 @@ +package sample; + +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.stage.Stage; + +public class Main extends Application { + + @Override + public void start(Stage primaryStage) throws Exception{ + String fxmlFile = "/fxml/sample.fxml"; + FXMLLoader loader = new FXMLLoader(); + Parent root = (Parent) loader.load(getClass().getResourceAsStream(fxmlFile)); + + primaryStage.setTitle("Hello World"); + primaryStage.setScene(new Scene(root, 750, 300)); + primaryStage.show(); + } + + + public static void main(String[] args) { + launch(); + } +} diff --git a/src/main/java/sample/dao/ProductDao.java b/src/main/java/sample/dao/ProductDao.java new file mode 100644 index 0000000..b2f0271 --- /dev/null +++ b/src/main/java/sample/dao/ProductDao.java @@ -0,0 +1,117 @@ +package sample.dao; + +import sample.db.ConnectionPool; +import sample.model.Product; +import sample.model.Provider; + +import java.sql.*; +import java.util.ArrayList; +import java.util.List; + +public class ProductDao { + private ConnectionPool pool = ConnectionPool.getInstance(); + private final String INSERT_PRODUCT= "INSERT INTO trade_report.product (id, name, type, wholesale_price, retail_price, provider_id, count) VALUES (?, ?, ?, ?, ?, ?, ?)"; + private final String SELECT_ALL_PRODUCT= "SELECT * FROM trade_report.product"; + private final String DELETE_PRODUCT= "DELETE FROM trade_report.product WHERE id=?"; + private final String UPDATE_PRODUCT= "UPDATE trade_report.product SET name=?, type=?, wholesale_price=?, retail_price=?, provider_id=?, count=? WHERE ID=?"; + private final String SELECT_PRODUCT_BY_ID = "SELECT * FROM trade_report.product WHERE id=?"; + + public Integer create(Product product) { + int idUser = 0; + try (Connection connection = pool.takeConnection(); + PreparedStatement statement = connection.prepareStatement(INSERT_PRODUCT, Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, product.getId()); + statement.setString(2, product.getName()); + statement.setString(3, String.valueOf(product.getType())); + statement.setInt(4, product.getWholesale_price()); + statement.setInt(5, product.getRetail_price()); + statement.setInt(6, product.getProvider_id()); + statement.setInt(7, product.getCount()); + statement.executeUpdate(); + ResultSet resultSet = statement.getGeneratedKeys(); + if(resultSet.next()) + idUser = resultSet.getInt(1); + resultSet.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + return idUser; + } + + public List getAll() { + List products = new ArrayList<>(); + try (Connection connection = pool.takeConnection(); + PreparedStatement statement = connection.prepareStatement(SELECT_ALL_PRODUCT); + ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + Product product = retrieveEntity(resultSet); + products.add(product); + } + } catch (SQLException e) { + e.printStackTrace(); + } + return products; + } + + public Product findByID(int id){ + Product product = null; + try (Connection connection = pool.takeConnection(); + PreparedStatement statement = connection.prepareStatement(SELECT_PRODUCT_BY_ID)) { + statement.setInt(1, id); + ResultSet resultSet = statement.executeQuery(); + if (resultSet.next()) { + product = retrieveEntity(resultSet); + } + resultSet.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + return product; + } + + public boolean updateProduct(Product product){ + int idUser = 0; + try (Connection connection = pool.takeConnection(); + PreparedStatement statement = connection.prepareStatement(UPDATE_PRODUCT)) { + statement.setString(1, product.getName()); + statement.setString(2, String.valueOf(product.getType())); + statement.setInt(3, product.getWholesale_price()); + statement.setInt(4, product.getRetail_price()); + statement.setInt(5, product.getProvider_id()); + statement.setInt(6, product.getCount()); + statement.setInt(7, product.getId()); + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + + return true; ///fix this shit; + } + + public void deleteById(Integer id) { + try (Connection connection = pool.takeConnection(); + PreparedStatement statement = connection.prepareStatement(DELETE_PRODUCT)) { + statement.setInt(1, id); + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public Product retrieveEntity(ResultSet resultSet) { + Product product = new Product(); + try{ + product.setId(resultSet.getInt("id")); + product.setName(resultSet.getString("name")); + product.setType(resultSet.getString("type")); + product.setWholesale_price(resultSet.getInt("wholesale_price")); + product.setRetail_price(resultSet.getInt("retail_price")); + product.setProvider_id(resultSet.getInt("provider_id")); + product.setCount(resultSet.getInt("count")); + } catch (SQLException e) { + e.printStackTrace(); + } + return product; + } + +} diff --git a/src/main/java/sample/db/ConnectionPool.java b/src/main/java/sample/db/ConnectionPool.java new file mode 100644 index 0000000..ec0cc04 --- /dev/null +++ b/src/main/java/sample/db/ConnectionPool.java @@ -0,0 +1,364 @@ +package sample.db; + +import java.sql.*; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Executor; + +public class ConnectionPool { + private static ConnectionPool poolInstance = null; + private static volatile boolean isCreated = false; + + private BlockingQueue connections; + + private int poolSize; + private String url; + private String login; + private String password; + + public static ConnectionPool getInstance() { + if (!isCreated) { + synchronized (ConnectionPool.class) { + poolInstance = new ConnectionPool(); + isCreated = true; + } + } + return poolInstance; + } + + private ConnectionPool() { + this.poolSize = 10; + this.url = "jdbc:mysql://localhost:3306/trade_report?serverTimezone=Europe/Kiev&allowPublicKeyRetrieval=true&useSSL=false&useUnicode=yes&characterEncoding=UTF-8"; + this.login = "root"; + this.password = "Aqva3283."; + initPoolData(); + } + + private void initPoolData() { + connections = new ArrayBlockingQueue<>(poolSize); + for (int i = 0; i < poolSize; i++) { + try { + DriverManager.registerDriver(new com.mysql.jdbc.Driver()); + Connection connection = DriverManager.getConnection(url, login, password); + connection.setClientInfo("myName", "" + i); + connections.add(new PooledConnection(connection)); + } catch (SQLException e) { + } + } + } + + public Connection takeConnection() throws SQLException { + Connection connection; + try { + connection = connections.take(); + } catch (InterruptedException e) { + throw new SQLException(); + } + return connection; + } + + public void dispose() { + Connection connection; + while ((connection = connections.poll()) != null) { + try { + connection.commit(); + ((PooledConnection) connection).connectionClose(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + } + + + private class PooledConnection implements Connection { + + private Connection connection; + + PooledConnection(Connection connection) throws SQLException { + this.connection = connection; + this.connection.setAutoCommit(true); + } + + private void connectionClose() throws SQLException{ + connection.close(); + } + + @Override + public void close() throws SQLException { + if (connection.isClosed()) { + throw new SQLException("Connection has already been closed."); + } + if (!connections.offer(this)) { + throw new SQLException("Unable to return used connection to the queue of available connections"); + } + } + + @Override + public boolean isClosed() throws SQLException { + return connection.isClosed(); + } + + @Override + public Statement createStatement() throws SQLException { + return connection.createStatement(); + } + + @Override + public PreparedStatement prepareStatement(String sql) throws SQLException { + return connection.prepareStatement(sql); + } + + @Override + public CallableStatement prepareCall(String sql) throws SQLException { + return connection.prepareCall(sql); + } + + @Override + public String nativeSQL(String sql) throws SQLException { + return connection.nativeSQL(sql); + } + + @Override + public void setAutoCommit(boolean autoCommit) throws SQLException { + connection.setAutoCommit(autoCommit); + } + + @Override + public boolean getAutoCommit() throws SQLException { + return connection.getAutoCommit(); + } + + @Override + public void commit() throws SQLException { + connection.commit(); + } + + @Override + public void rollback() throws SQLException { + connection.rollback(); + } + + @Override + public DatabaseMetaData getMetaData() throws SQLException { + return connection.getMetaData(); + } + + @Override + public void setReadOnly(boolean readOnly) throws SQLException { + connection.setReadOnly(readOnly); + } + + @Override + public boolean isReadOnly() throws SQLException { + return connection.isReadOnly(); + } + + @Override + public void setCatalog(String catalog) throws SQLException { + connection.setCatalog(catalog); + } + + @Override + public String getCatalog() throws SQLException { + return connection.getCatalog(); + } + + @Override + public void setTransactionIsolation(int level) throws SQLException { + connection.setTransactionIsolation(level); + } + + @Override + public int getTransactionIsolation() throws SQLException { + return connection.getTransactionIsolation(); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + return connection.getWarnings(); + } + + @Override + public void clearWarnings() throws SQLException { + connection.clearWarnings(); + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { + return connection.createStatement(); + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { + return connection.prepareStatement(sql); + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { + return connection.prepareCall(sql); + } + + @Override + public Map> getTypeMap() throws SQLException { + return connection.getTypeMap(); + } + + @Override + public void setTypeMap(Map> map) throws SQLException { + connection.setTypeMap(map); + } + + @Override + public void setHoldability(int holdability) throws SQLException { + connection.setHoldability(holdability); + } + + @Override + public int getHoldability() throws SQLException { + return connection.getHoldability(); + } + + @Override + public Savepoint setSavepoint() throws SQLException { + return connection.setSavepoint(); + } + + @Override + public Savepoint setSavepoint(String name) throws SQLException { + return setSavepoint(name); + } + + @Override + public void rollback(Savepoint savepoint) throws SQLException { + connection.rollback(); + } + + @Override + public void releaseSavepoint(Savepoint savepoint) throws SQLException { + connection.releaseSavepoint(savepoint); + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + return connection.createStatement(); + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + return connection.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability); + } + + @Override + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { + return connection.prepareStatement(sql, autoGeneratedKeys); + } + + @Override + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { + return connection.prepareStatement(sql, columnIndexes); + } + + @Override + public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { + return connection.prepareStatement(sql, columnNames); + } + + @Override + public Clob createClob() throws SQLException { + return connection.createClob(); + } + + @Override + public Blob createBlob() throws SQLException { + return connection.createBlob(); + } + + @Override + public NClob createNClob() throws SQLException { + return connection.createNClob(); + } + + @Override + public SQLXML createSQLXML() throws SQLException { + return connection.createSQLXML(); + } + + @Override + public boolean isValid(int timeout) throws SQLException { + return connection.isValid(timeout); + } + + @Override + public void setClientInfo(String name, String value) throws SQLClientInfoException { + connection.setClientInfo(name, value); + } + + @Override + public void setClientInfo(Properties properties) throws SQLClientInfoException { + connection.setClientInfo(properties); + } + + @Override + public String getClientInfo(String name) throws SQLException { + return connection.getClientInfo(name); + } + + @Override + public Properties getClientInfo() throws SQLException { + return connection.getClientInfo(); + } + + @Override + public Array createArrayOf(String typeName, Object[] elements) throws SQLException { + return connection.createArrayOf(typeName, elements); + } + + @Override + public Struct createStruct(String typeName, Object[] attributes) throws SQLException { + return connection.createStruct(typeName, attributes); + } + + @Override + public void setSchema(String schema) throws SQLException { + connection.setSchema(schema); + } + + @Override + public String getSchema() throws SQLException { + return connection.getSchema(); + } + + @Override + public void abort(Executor executor) throws SQLException { + connection.abort(executor); + } + + @Override + public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { + connection.setNetworkTimeout(executor, milliseconds); + } + + @Override + public int getNetworkTimeout() throws SQLException { + return connection.getNetworkTimeout(); + } + + @Override + public T unwrap(Class iface) throws SQLException { + return unwrap(iface); + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return connection.isWrapperFor(iface); + } + } +} \ No newline at end of file diff --git a/src/main/java/sample/model/Product.java b/src/main/java/sample/model/Product.java new file mode 100644 index 0000000..f12c3b2 --- /dev/null +++ b/src/main/java/sample/model/Product.java @@ -0,0 +1,22 @@ +package sample.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor + +public class Product { + private int id; + private String name; + private String type; + private int wholesale_price; + private int retail_price; + private int provider_id; + private int count; + +} diff --git a/src/main/java/sample/model/Provider.java b/src/main/java/sample/model/Provider.java new file mode 100644 index 0000000..3758aa8 --- /dev/null +++ b/src/main/java/sample/model/Provider.java @@ -0,0 +1,16 @@ +package sample.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor + +public class Provider { + private int id; + private String name; +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..c724e8f --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,10 @@ +spring.datasource.url=jdbc:mysql://localhost:3306/trade_report?serverTimezone=Europe/Kiev&allowPublicKeyRetrieval=true&useSSL=false&useUnicode=yes&characterEncoding=UTF-8 +spring.datasource.username=root +spring.datasource.password=Aqva3283. +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.jpa.hibernate.ddl-auto=update +spring.jpa.database-platform=org.hibernate.dialect.MySQL57Dialect +spring.jpa.generate-ddl=true +spring.jpa.show-sql=true + + diff --git a/src/main/resources/fxml/sample.fxml b/src/main/resources/fxml/sample.fxml new file mode 100644 index 0000000..3926405 --- /dev/null +++ b/src/main/resources/fxml/sample.fxml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +