diff options
| author | Kamal Wickramanayake <kamal@inbox.lk> | 2026-04-25 21:53:33 +0530 |
|---|---|---|
| committer | Kamal Wickramanayake <kamal@inbox.lk> | 2026-04-25 21:53:33 +0530 |
| commit | 4afcff940551079617e8f4116e52bb0ef9df7fcc (patch) | |
| tree | cbaed6a2a53c7d032bfafaa38b94e4fc607f3e76 /spring-framework/07-user-jdbc-ds-transaction/src/main | |
| parent | 7b08f1155e1cb8bf263c3570eeb119970407a037 (diff) | |
Added Spring Framework sample code
Diffstat (limited to 'spring-framework/07-user-jdbc-ds-transaction/src/main')
10 files changed, 510 insertions, 0 deletions
diff --git a/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/FinancialPlannerApp.java b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/FinancialPlannerApp.java new file mode 100644 index 0000000..24b4675 --- /dev/null +++ b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/FinancialPlannerApp.java @@ -0,0 +1,45 @@ +package com.example.fp; + +import java.util.List; + +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class FinancialPlannerApp { + + /** + * @param args + */ + public static void main(String[] args) { + + AbstractApplicationContext ctx = new ClassPathXmlApplicationContext(new String[] {"classpath:META-INF/spring/applicationContext.xml"}); + + // Register a shutdown hook with the JVM runtime, closing this context on JVM shutdown unless it has already been closed at that time. + // Delegates to doClose() for the actual closing procedure. + // This will trigger the destroy-method of the DataSource in our application (for example, in case of unexpected JVM shutdown). + ctx.registerShutdownHook(); + + UserManager userManager = ctx.getBean("userManager", UserManager.class); + + // Create an account + System.out.println("Creating users..."); + + userManager.create(new User("Kamal", "Kamal Wickramanayake", "abc123", true)); + userManager.create(new User("Rajith", "Rajith Virajana", "abc123", true)); + userManager.create(new User("Uththama", "Uththama Yapa", "abc123", true)); + + List<User> users = userManager.findAll(); + + for (User user : users) { + System.out.println(user); + } + + User newUser = new User("Kamal2", "Kamal Wickramanayake", "abc123", true); + System.out.println(newUser); + userManager.create(newUser); + System.out.println(newUser); + + ctx.close(); + } + +} diff --git a/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/User.java b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/User.java new file mode 100644 index 0000000..d940b63 --- /dev/null +++ b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/User.java @@ -0,0 +1,115 @@ +package com.example.fp; + +public class User { + private Integer uid; + private String username; + private String fullName; + private String password; + private boolean active; + + public User() { + super(); + } + + public User(String username, String fullName, String password, boolean active) { + super(); + this.username = username; + this.fullName = fullName; + this.password = password; + this.active = active; + } + + + public User(Integer uid, String username, String fullName, String password, boolean active) { + super(); + this.uid = uid; + this.username = username; + this.fullName = fullName; + this.password = password; + this.active = active; + } + + public Integer getUid() { + return uid; + } + public void setUid(Integer uid) { + this.uid = uid; + } + + public String getUsername() { + return username; + } + public void setUsername(String username) { + this.username = username; + } + public String getFullName() { + return fullName; + } + public void setFullName(String fullName) { + this.fullName = fullName; + } + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } + public boolean isActive() { + return active; + } + public void setActive(boolean active) { + this.active = active; + } + + @Override + public String toString() { + return "User [uid=" + uid + ", username=" + username + ", fullName=" + fullName + ", active=" + active + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (active ? 1231 : 1237); + result = prime * result + ((fullName == null) ? 0 : fullName.hashCode()); + result = prime * result + ((password == null) ? 0 : password.hashCode()); + result = prime * result + uid; + result = prime * result + ((username == null) ? 0 : username.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + User other = (User) obj; + if (active != other.active) + return false; + if (fullName == null) { + if (other.fullName != null) + return false; + } else if (!fullName.equals(other.fullName)) + return false; + if (password == null) { + if (other.password != null) + return false; + } else if (!password.equals(other.password)) + return false; + if (uid != other.uid) + return false; + if (username == null) { + if (other.username != null) + return false; + } else if (!username.equals(other.username)) + return false; + return true; + } + + + + +} diff --git a/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/UserManager.java b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/UserManager.java new file mode 100644 index 0000000..2412617 --- /dev/null +++ b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/UserManager.java @@ -0,0 +1,17 @@ +package com.example.fp; + +import java.util.List; + +public interface UserManager { + + public void create(User user); + + public User find(int uid); + public List<User> findAll(); + + public void delete(int uid); + + public void update(User user); + + public void setPassword(int uid, String plainTextPassword); +} diff --git a/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/UserManagerImpl.java b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/UserManagerImpl.java new file mode 100644 index 0000000..ad2a58d --- /dev/null +++ b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/UserManagerImpl.java @@ -0,0 +1,78 @@ +package com.example.fp; + +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.List; + +import com.example.fp.dao.UserDAO; + +public class UserManagerImpl implements UserManager { + + private UserDAO userDAO; + + public void setUserDAO(UserDAO userDAO) { + this.userDAO = userDAO; + } + + @Override + public void create(User user) { + user.setPassword(calculatePasswordHash(user.getPassword())); + userDAO.create(user); + } + + @Override + public User find(int uid) { + return userDAO.find(uid); + } + + @Override + public List<User> findAll() { + return userDAO.findAll(); + } + + @Override + public void delete(int uid) { + userDAO.delete(uid); + } + + @Override + public void update(User user) { + userDAO.update(user); + } + + @Override + public void setPassword(int uid, String plainTextPassword) { + User user = userDAO.find(uid); + + user.setPassword(calculatePasswordHash(plainTextPassword)); + + userDAO.update(user); + } + + public static String calculatePasswordHash(String plainText) { + + try { + // Static getInstance method is called with hashing MD5 + MessageDigest md = MessageDigest.getInstance("MD5"); + + // digest() method is called to calculate message digest + // of an input digest() return array of byte + byte[] messageDigest = md.digest(plainText.getBytes()); + + // Convert byte array into signum representation + BigInteger no = new BigInteger(1, messageDigest); + + // Convert message digest into hex value + String hashtext = no.toString(16); + while (hashtext.length() < 32) { + hashtext = "0" + hashtext; + } + + return hashtext; + } catch (NoSuchAlgorithmException e) { + // For specifying wrong message digest algorithms + throw new RuntimeException(e); + } + } +}
\ No newline at end of file diff --git a/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/dao/UserDAO.java b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/dao/UserDAO.java new file mode 100644 index 0000000..b0215b1 --- /dev/null +++ b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/dao/UserDAO.java @@ -0,0 +1,14 @@ +package com.example.fp.dao; + +import java.util.List; + +import com.example.fp.User; + +public interface UserDAO { + public void create(User user); + public User find(int uid); + public User find(String username); + public void delete(int uid); + public List<User> findAll(); + public void update(User user); +} diff --git a/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/dao/jdbc/JDBCUserDAO.java b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/dao/jdbc/JDBCUserDAO.java new file mode 100644 index 0000000..80d77af --- /dev/null +++ b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/dao/jdbc/JDBCUserDAO.java @@ -0,0 +1,94 @@ +package com.example.fp.dao.jdbc; + +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.fp.User; +import com.example.fp.dao.UserDAO; + +public class JDBCUserDAO implements UserDAO { + + private JdbcTemplate jdbcTemplate; + + public void setDataSource(DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + + @Override + public void create(User user) { + + final String INSERT_SQL = "insert into user_account (username, full_name, password, active) values(?, ?, ?, ?)"; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + jdbcTemplate.update( + new PreparedStatementCreator() { + public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { + PreparedStatement ps = + connection.prepareStatement(INSERT_SQL, new String[] {"uid"}); + ps.setString(1, user.getUsername()); + ps.setString(2, user.getFullName()); + ps.setString(3, user.getPassword()); + ps.setInt(4, user.isActive() ? 1 : 0); + return ps; + } + }, keyHolder); + + // keyHolder.getKey() now contains the generated key + user.setUid(keyHolder.getKey().intValue()); + } + + @Override + public void delete(int uid) { + jdbcTemplate.update("delete from user_account where uid = ?", Integer.valueOf(uid)); + } + + @Override + public List<User> findAll() { + return this.jdbcTemplate.query( "select * from user_account", new UserMapper()); + } + + + @Override + public User find(int uid) { + return this.jdbcTemplate.queryForObject( "select * from user_account where uid = ?", new Object[] {Integer.valueOf(uid)}, new UserMapper()); + } + + + @Override + public User find(String username) { + return this.jdbcTemplate.queryForObject( "select * from user_account where username = ?", new Object[] {username}, new UserMapper()); + } + + + @Override + public void update(User user) { + this.jdbcTemplate.update("update user_account set username = ?, full_name = ?, password = ?, active = ? where uid = ?", + user.getUsername(), user.getFullName(), user.getPassword(), user.isActive() ? 1 : 0, user.getUid()); + } + + + private static final class UserMapper implements RowMapper<User> { + + public User mapRow(ResultSet rs, int rowNum) throws SQLException { + User user = new User(); + user.setUid(rs.getInt("uid")); + user.setUsername(rs.getString("username")); + user.setFullName(rs.getString("full_name")); + user.setPassword(rs.getString("password")); + user.setActive(rs.getBoolean("active")); + return user; + } + } +}
\ No newline at end of file diff --git a/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/tx/TxUserManager.java b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/tx/TxUserManager.java new file mode 100644 index 0000000..4bb6d05 --- /dev/null +++ b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/fp/tx/TxUserManager.java @@ -0,0 +1,88 @@ +package com.example.fp.tx; + +import java.util.List; + +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallbackWithoutResult; +import org.springframework.transaction.support.TransactionTemplate; + +import com.example.fp.User; +import com.example.fp.UserManager; + +/** + * This class decorates a given AccountManager by adding transaction boundaries. + * + * @author kamal + * + */ +public class TxUserManager implements UserManager { + + private UserManager userManager; + + public void setUserManager(UserManager userManager) { + this.userManager = userManager; + } + + private TransactionTemplate txTemplate; + + public void setTxManager(DataSourceTransactionManager txManager) { + txTemplate = new TransactionTemplate(txManager); + } + + + @Override + public User find(int uid) { + return userManager.find(uid); + } + + + @Override + public void delete(int uid) { + txTemplate.execute(new TransactionCallbackWithoutResult() { + + @Override + protected void doInTransactionWithoutResult(TransactionStatus arg0) { + userManager.delete(uid); + } + }); + } + + @Override + public void create(User user) { + txTemplate.execute(new TransactionCallbackWithoutResult() { + + @Override + protected void doInTransactionWithoutResult(TransactionStatus arg0) { + userManager.create(user); + } + }); + } + + @Override + public List<User> findAll() { + return userManager.findAll(); + } + + @Override + public void update(User user) { + txTemplate.execute(new TransactionCallbackWithoutResult() { + + @Override + protected void doInTransactionWithoutResult(TransactionStatus arg0) { + userManager.update(user); + } + }); + } + + @Override + public void setPassword(int uid, String plainTextPassword) { + txTemplate.execute(new TransactionCallbackWithoutResult() { + + @Override + protected void doInTransactionWithoutResult(TransactionStatus arg0) { + userManager.setPassword(uid, plainTextPassword); + } + }); + } +} diff --git a/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/spring/App.java b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/spring/App.java new file mode 100644 index 0000000..2fd9e86 --- /dev/null +++ b/spring-framework/07-user-jdbc-ds-transaction/src/main/java/com/example/spring/App.java @@ -0,0 +1,11 @@ +package com.example.spring; + +import com.example.fp.FinancialPlannerApp; + +public class App { + public static void main(String[] args) { + // Actually, BankApp is the class with the main method. + // It should have been executed directly instead of this class. + FinancialPlannerApp.main(args); + } +} diff --git a/spring-framework/07-user-jdbc-ds-transaction/src/main/resources/META-INF/spring/applicationContext.xml b/spring-framework/07-user-jdbc-ds-transaction/src/main/resources/META-INF/spring/applicationContext.xml new file mode 100644 index 0000000..9b85cd3 --- /dev/null +++ b/spring-framework/07-user-jdbc-ds-transaction/src/main/resources/META-INF/spring/applicationContext.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:jdbc="http://www.springframework.org/schema/jdbc" + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/jdbc + http://www.springframework.org/schema/jdbc/spring-jdbc.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context.xsd"> + + <context:property-placeholder location="classpath:META-INF/spring/jdbc.properties"/> + + <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close" > + <property name="driverClassName" value="${jdbc.driverClassName}"/> + <property name="url" value="${jdbc.url}"/> + <property name="username" value="${jdbc.username}"/> + <property name="password" value="${jdbc.password}"/> + </bean> + + <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> + <property name="dataSource" ref="dataSource"/> + </bean> + + <bean id="userDAO" class="com.example.fp.dao.jdbc.JDBCUserDAO" > + <property name="dataSource" ref="dataSource"/> + </bean> + + <bean id="userManagerWithNoTransactionSupport" class="com.example.fp.UserManagerImpl"> + <property name="userDAO" ref="userDAO"/> + </bean> + + <bean id="userManager" class="com.example.fp.tx.TxUserManager"> + <property name="userManager" ref="userManagerWithNoTransactionSupport"/> + <property name="txManager" ref="txManager"/> + </bean> + +</beans>
\ No newline at end of file diff --git a/spring-framework/07-user-jdbc-ds-transaction/src/main/resources/META-INF/spring/jdbc.properties b/spring-framework/07-user-jdbc-ds-transaction/src/main/resources/META-INF/spring/jdbc.properties new file mode 100644 index 0000000..83220af --- /dev/null +++ b/spring-framework/07-user-jdbc-ds-transaction/src/main/resources/META-INF/spring/jdbc.properties @@ -0,0 +1,9 @@ +jdbc.driverClassName=com.mysql.cj.jdbc.Driver +#jdbc.url=jdbc:mysql://localhost/bankdb?useSSL=false +#jdbc.url=jdbc:mysql://localhost/bankdb?useLegacyDatetimeCode=false&serverTimezone=UTC +jdbc.url=jdbc:mysql://localhost/bankdb?serverTimezone=Asia/Colombo +jdbc.username=bankdbuser +jdbc.password=abc123 + +#jdbc.driverClassName=org.postgresql.Driver +#jdbc.url=jdbc:postgresql://localhost/bank |
