summaryrefslogtreecommitdiff
path: root/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example
diff options
context:
space:
mode:
authorKamal Wickramanayake <kamal@inbox.lk>2026-04-25 21:53:33 +0530
committerKamal Wickramanayake <kamal@inbox.lk>2026-04-25 21:53:33 +0530
commit4afcff940551079617e8f4116e52bb0ef9df7fcc (patch)
treecbaed6a2a53c7d032bfafaa38b94e4fc607f3e76 /spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example
parent7b08f1155e1cb8bf263c3570eeb119970407a037 (diff)
Added Spring Framework sample code
Diffstat (limited to 'spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example')
-rw-r--r--spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/Account.java21
-rw-r--r--spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManager.java21
-rw-r--r--spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManagerImpl.java73
-rw-r--r--spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/AccountDAO.java15
-rw-r--r--spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/jdbc/JDBCAccountDAO.java94
-rw-r--r--spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/tx/TxAccountManager.java109
-rw-r--r--spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/web/BankGateway.java59
7 files changed, 392 insertions, 0 deletions
diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/Account.java b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/Account.java
new file mode 100644
index 0000000..6222af8
--- /dev/null
+++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/Account.java
@@ -0,0 +1,21 @@
+package com.example.spring.bank;
+
+import java.math.BigDecimal;
+
+public class Account {
+ private int accountNumber;
+ private BigDecimal balance;
+
+ public int getAccountNumber() {
+ return accountNumber;
+ }
+ public void setAccountNumber(int accountNumber) {
+ this.accountNumber = accountNumber;
+ }
+ public BigDecimal getBalance() {
+ return balance;
+ }
+ public void setBalance(BigDecimal balance) {
+ this.balance = balance;
+ }
+}
diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManager.java b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManager.java
new file mode 100644
index 0000000..f299d60
--- /dev/null
+++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManager.java
@@ -0,0 +1,21 @@
+package com.example.spring.bank;
+
+import java.math.BigDecimal;
+
+public interface AccountManager {
+
+ public Account create();
+
+ public Account find(int accountNumber);
+
+ public Account deposit(int accountNumber, BigDecimal amount);
+ public Account withdraw(int accountNumber, BigDecimal amount);
+
+ public void delete(int accountNumber);
+
+ /** Returns the first account */
+ public Account transfer(int accountNumber1, int accountNumber2, BigDecimal amount);
+
+ public void chargeForLowBalance(BigDecimal minimumBalance, BigDecimal amount);
+
+}
diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManagerImpl.java b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManagerImpl.java
new file mode 100644
index 0000000..39dc63e
--- /dev/null
+++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManagerImpl.java
@@ -0,0 +1,73 @@
+package com.example.spring.bank;
+
+import java.math.BigDecimal;
+import java.util.Iterator;
+import java.util.List;
+
+import com.example.spring.bank.dao.AccountDAO;
+
+public class AccountManagerImpl implements AccountManager {
+
+ private AccountDAO accountDAO;
+
+ public void setAccountDAO(AccountDAO accountDAO) {
+ this.accountDAO = accountDAO;
+ }
+
+ @Override
+ public void chargeForLowBalance(BigDecimal minimumBalance, BigDecimal amount) {
+ List<Account> accounts = accountDAO.findAccountsWithLowBalance(minimumBalance);
+ for (Iterator<Account> iterator = accounts.iterator(); iterator.hasNext();) {
+ Account account = (Account) iterator.next();
+ // Check if the balance will go beyond 0. If yes, set the balance to 0
+ account.setBalance(account.getBalance().subtract(amount));
+ accountDAO.update(account);
+ }
+ }
+
+ @Override
+ public Account create() {
+ return accountDAO.createAccount();
+ }
+
+ @Override
+ public Account find(int accountNumber) {
+ return accountDAO.getAccount(accountNumber);
+ }
+
+ @Override
+ public void delete(int accountNumber) {
+ accountDAO.delete(accountNumber);
+ }
+
+ @Override
+ public Account deposit(int accountNumber, BigDecimal amount) {
+ Account account = accountDAO.getAccount(accountNumber);
+ account.setBalance(account.getBalance().add(amount));
+ accountDAO.update(account);
+
+ return account;
+ }
+
+ @Override
+ public Account withdraw(int accountNumber, BigDecimal amount) {
+ Account account = accountDAO.getAccount(accountNumber);
+ account.setBalance(account.getBalance().subtract(amount));
+ accountDAO.update(account);
+
+ return account;
+ }
+
+ @Override
+ public Account transfer(int accountNumber1, int accountNumber2, BigDecimal amount) {
+ Account account1 = accountDAO.getAccount(accountNumber1);
+ account1.setBalance(account1.getBalance().subtract(amount));
+ accountDAO.update(account1);
+
+ Account account2 = accountDAO.getAccount(accountNumber2);
+ account2.setBalance(account2.getBalance().add(amount));
+ accountDAO.update(account2);
+
+ return account1;
+ }
+} \ No newline at end of file
diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/AccountDAO.java b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/AccountDAO.java
new file mode 100644
index 0000000..735aed2
--- /dev/null
+++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/AccountDAO.java
@@ -0,0 +1,15 @@
+package com.example.spring.bank.dao;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import com.example.spring.bank.Account;
+
+public interface AccountDAO {
+ public Account createAccount();
+ public Account getAccount(int accountNumber);
+ public void update(Account account);
+ public void delete(int accountNumber);
+ public List<Account> findAllAccounts();
+ public List<Account> findAccountsWithLowBalance(BigDecimal lessThanAmount);
+}
diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/jdbc/JDBCAccountDAO.java b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/jdbc/JDBCAccountDAO.java
new file mode 100644
index 0000000..d285a89
--- /dev/null
+++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/jdbc/JDBCAccountDAO.java
@@ -0,0 +1,94 @@
+package com.example.spring.bank.dao.jdbc;
+
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+
+import javax.sql.DataSource;
+
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.PreparedStatementCreator;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.jdbc.support.GeneratedKeyHolder;
+import org.springframework.jdbc.support.KeyHolder;
+
+import com.example.spring.bank.Account;
+import com.example.spring.bank.dao.AccountDAO;
+
+public class JDBCAccountDAO implements AccountDAO {
+
+ private JdbcTemplate jdbcTemplate;
+
+ public void setDataSource(DataSource dataSource) {
+ this.jdbcTemplate = new JdbcTemplate(dataSource);
+ }
+
+
+ @Override
+ public Account createAccount() {
+// Connection con = dataSource.getConnection();
+// PreparedStatement stmt = con.prepareStatement("...", autoGeneratedKeys);
+// stmt.execute();
+// con.close();
+
+
+ final String INSERT_SQL = "insert into account (balance) values(0)";
+
+ KeyHolder keyHolder = new GeneratedKeyHolder();
+ jdbcTemplate.update(
+ new PreparedStatementCreator() {
+ public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
+ PreparedStatement ps =
+ connection.prepareStatement(INSERT_SQL, new String[] {"account_number"});
+ // ps.setString(1, name);
+ return ps;
+ }
+ }, keyHolder);
+
+ Account account = new Account();
+ // keyHolder.getKey() now contains the generated key
+ account.setAccountNumber(keyHolder.getKey().intValue());
+ account.setBalance(new BigDecimal("0.0"));
+
+ return account;
+ }
+
+ @Override
+ public void delete(int accountNumber) {
+ jdbcTemplate.update("delete from account where account_number = ?", Integer.valueOf(accountNumber));
+ }
+
+ @Override
+ public List<Account> findAccountsWithLowBalance(BigDecimal lessThanAmount) {
+ return this.jdbcTemplate.query( "select * from account where balance < ?", new Object[] {lessThanAmount.doubleValue()}, new AccountMapper());
+ }
+
+ @Override
+ public List<Account> findAllAccounts() {
+ return this.jdbcTemplate.query( "select * from account", new AccountMapper());
+ }
+
+ @Override
+ public Account getAccount(int accountNumber) {
+ return this.jdbcTemplate.queryForObject( "select * from account where account_number = ?", new Object[] {accountNumber}, new AccountMapper());
+ }
+
+ @Override
+ public void update(Account account) {
+ this.jdbcTemplate.update("update account set balance = ? where account_number = ?", account.getBalance(), account.getAccountNumber());
+ }
+
+
+ private static final class AccountMapper implements RowMapper<Account> {
+
+ public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
+ Account account = new Account();
+ account.setAccountNumber(rs.getInt("account_number"));
+ account.setBalance(rs.getBigDecimal("balance"));
+ return account;
+ }
+ }
+} \ No newline at end of file
diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/tx/TxAccountManager.java b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/tx/TxAccountManager.java
new file mode 100644
index 0000000..a5b310d
--- /dev/null
+++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/tx/TxAccountManager.java
@@ -0,0 +1,109 @@
+package com.example.spring.bank.tx;
+
+import java.math.BigDecimal;
+
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.support.TransactionCallback;
+import org.springframework.transaction.support.TransactionCallbackWithoutResult;
+import org.springframework.transaction.support.TransactionTemplate;
+
+import com.example.spring.bank.Account;
+import com.example.spring.bank.AccountManager;
+
+/**
+ * This class decorates a given AccountManager by adding transaction boundaries.
+ *
+ * @author kamal
+ *
+ */
+public class TxAccountManager implements AccountManager {
+
+ private AccountManager accountManager;
+
+ public void setAccountManager(AccountManager accountManager) {
+ this.accountManager = accountManager;
+ }
+
+ private TransactionTemplate txTemplate;
+
+ public void setTxManager(DataSourceTransactionManager txManager) {
+ txTemplate = new TransactionTemplate(txManager);
+ }
+
+ @Override
+ public Account create() {
+ return txTemplate.execute(new TransactionCallback<Account>() {
+ @Override
+ public Account doInTransaction(TransactionStatus arg0) {
+ return accountManager.create();
+ }
+ });
+ }
+
+ @Override
+ public Account find(int accountNumber) {
+ return accountManager.find(accountNumber);
+ }
+
+ @Override
+ public Account deposit(int accountNumber, BigDecimal amount) {
+ return txTemplate.execute(new TransactionCallback<Account>() {
+
+ @Override
+ public Account doInTransaction(TransactionStatus arg0) {
+ return accountManager.deposit(accountNumber, amount);
+ }
+ });
+ }
+
+ @Override
+ public Account withdraw(int accountNumber, BigDecimal amount) {
+ return txTemplate.execute(new TransactionCallback<Account>() {
+
+ @Override
+ public Account doInTransaction(TransactionStatus arg0) {
+ return accountManager.withdraw(accountNumber, amount);
+ }
+ });
+ }
+
+ @Override
+ public void delete(int accountNumber) {
+ txTemplate.execute(new TransactionCallbackWithoutResult() {
+
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus arg0) {
+ accountManager.delete(accountNumber);
+ }
+ });
+ }
+
+ @Override
+ public void chargeForLowBalance(BigDecimal minimumBalance, BigDecimal amount) {
+ txTemplate.execute(new TransactionCallbackWithoutResult() {
+
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus arg0) {
+ accountManager.chargeForLowBalance(minimumBalance, amount);
+ }
+ });
+ }
+
+ @Override
+ public Account transfer(int accountNumber1, int accountNumber2, BigDecimal amount) {
+ return txTemplate.execute(new TransactionCallback<Account>() {
+
+ @Override
+ public Account doInTransaction(TransactionStatus status) {
+ try {
+ return accountManager.transfer(accountNumber1, accountNumber2, amount);
+ } catch (Exception e) {
+ // Some exception occurred.
+ status.setRollbackOnly();
+ throw e;
+ }
+ }
+ });
+ }
+}
diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/web/BankGateway.java b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/web/BankGateway.java
new file mode 100644
index 0000000..e7908d5
--- /dev/null
+++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/web/BankGateway.java
@@ -0,0 +1,59 @@
+package com.example.spring.bank.web;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+import com.example.spring.bank.AccountManager;
+
+/**
+ * Servlet implementation class BankGateway
+ */
+public class BankGateway extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @see HttpServlet#HttpServlet()
+ */
+ public BankGateway() {
+ super();
+ }
+
+ /**
+ * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
+ */
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ getServletContext().getRequestDispatcher("/deposit.jsp").forward(request, response);
+ }
+
+ /**
+ * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
+ */
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
+ AccountManager am = ctx.getBean("accountManager", AccountManager.class);
+
+ int accountNumber = Integer.parseInt(request.getParameter("accountNumber"));
+ BigDecimal amount = new BigDecimal(request.getParameter("amount"));
+
+ // How to use a session scoped bean (Example only)
+// DepositForm form = (DepositForm) ctx.getBean("depositForm");
+// form.setAccountNumber(accountNumber);
+// form.setAmount(amount);
+ // End of example
+
+
+ am.deposit(accountNumber, amount);
+
+ // We can dispatch to a success page if we prefer!
+ getServletContext().getRequestDispatcher("/deposit.jsp").forward(request, response);
+ }
+
+}