A console-based Bank Management System with admin/employee login, full CRUD on customers and accounts, deposit/withdraw/transfer with proper transaction handling, and complete transaction history — built to demonstrate exactly what TCS (and most fresher interviews) probe for: OOP, DBMS, SQL, JDBC, exception handling, and a real-world workflow.
- Login system with hashed passwords (SHA-256) and role-based access (ADMIN vs EMPLOYEE)
- Layered architecture — model / dao / service / util — so you can speak to separation of concerns, not just "I wrote one big file"
- Real JDBC transaction management — the fund transfer feature uses
setAutoCommit(false)+commit()/rollback()across two account updates, which is a genuinely strong DBMS talking point most fresher projects skip - Custom checked exceptions for business rules (insufficient balance, invalid amount, account not found, authentication failure)
- PreparedStatements everywhere — no string-concatenated SQL, so you can speak confidently about SQL injection prevention if asked
BankManagementSystem/
├── src/
│ ├── Main.java # Console menu, entry point
│ ├── model/
│ │ ├── Customer.java
│ │ ├── Account.java
│ │ ├── Transaction.java
│ │ └── Admin.java
│ ├── dao/
│ │ ├── CustomerDAO.java # CRUD via JDBC PreparedStatements
│ │ ├── AccountDAO.java
│ │ ├── TransactionDAO.java
│ │ └── AdminDAO.java
│ ├── service/
│ │ ├── BankService.java # Deposit/withdraw/transfer business logic
│ │ └── AuthService.java # Login logic
│ ├── exception/
│ │ ├── InsufficientBalanceException.java
│ │ ├── AccountNotFoundException.java
│ │ ├── InvalidAmountException.java
│ │ └── AuthenticationException.java
│ └── util/
│ ├── DBConnection.java # JDBC connection singleton
│ └── PasswordUtil.java # SHA-256 hashing
├── sql/
│ └── schema.sql # Database + tables + seed data
├── lib/ # Put mysql-connector-j JAR here
├── .vscode/
│ ├── launch.json
│ └── settings.json
└── README.md
Make sure MySQL Server is installed and running locally.
Open MySQL Workbench / CLI and run:
mysql -u root -p < sql/schema.sqlThis creates the bank_management_system database with all 4 tables and seed data
(3 sample customers, 3 accounts, 2 login users).
Download mysql-connector-j-9.7.0.jar from
https://dev.mysql.com/downloads/connector/j/ (or Maven Central) and place it inside
the lib/ folder.
In src/util/DBConnection.java, update:
private static final String PASSWORD = "your_mysql_password";to your actual MySQL root password.
- Open the
BankManagementSystemfolder in VSCode (Extension Pack for Java required). - VSCode should auto-detect the JAR in
lib/via.vscode/settings.json. If not, right-click the jar → "Add Folder to Java Source Path" isn't needed — instead use Java Projects → Referenced Libraries → Add Jar Folder in the Java sidebar and point it tolib/. - Open
src/Main.javaand pressF5.
cd BankManagementSystem
mkdir -p bin
javac -cp "lib/*" -d bin $(find src -name "*.java")
java -cp "bin:lib/*" Main # Mac/Linux
java -cp "bin;lib/*" Main # Windows| Username | Password | Role |
|---|---|---|
| admin | admin123 | ADMIN |
| employee | employee123 | EMPLOYEE |
Employees can do everything except delete customers or close accounts — those are restricted to ADMIN to demonstrate role-based access control.
- Add / View / Search / Update / Delete Customer
- Open Account / View All Accounts / Close Account (Admin only)
- Deposit, Withdraw, Transfer Funds (atomic, transactional)
- View Transaction History per account
- Role-based menu restrictions
"Walk me through your project."
"It's a Bank Management System with a layered architecture — model, DAO, service, and utility packages. Login is role-based: admins can delete customers and close accounts, employees can't. All database access goes through DAO classes using JDBC PreparedStatements, and the actual business rules — like blocking a withdrawal that exceeds balance — live in a service layer, not in the DAO or the menu code."
"How did you handle the fund transfer between two accounts safely?"
"I used a JDBC transaction. I set
autoCommit(false), debit one account, credit the other, insert both transaction records, then commit. If anything throws an exception in between — say the destination account doesn't exist — I roll back the entire transaction so neither balance gets touched. That's the classic DBMS atomicity problem, and handling it at the JDBC level rather than hoping nothing fails was a deliberate design choice."
"How are passwords stored?"
"I never store plaintext passwords — I hash them with SHA-256 before storing and before comparing on login. For a production system I'd use bcrypt or PBKDF2 with salting since SHA-256 alone is fast to brute-force, but it demonstrates the concept at a fresher-project level."
"Why DAO pattern instead of writing SQL directly in Main?"
"Separation of concerns — if I ever swap MySQL for PostgreSQL, only the DAO layer changes. It also makes the code testable and keeps SQL out of the UI/menu logic."
"What would you improve given more time?"
"Connection pooling (HikariCP) instead of a single static connection, bcrypt for passwords, pagination for large customer lists, and probably a Swing/JavaFX GUI instead of console I/O."
admins(admin_id PK, username, password, role)
customers(customer_id PK, name, email, phone, address)
accounts(account_number PK, customer_id FK -> customers, account_type, balance, status)
transactions(transaction_id PK, account_number FK -> accounts, type, amount, transaction_date, remarks)
accounts.customer_id and transactions.account_number are foreign keys with
ON DELETE CASCADE, so deleting a customer cleans up their accounts and history —
worth mentioning if asked about referential integrity.