* modify table module pattern * fix code smells * resolve conversation Co-authored-by: tao-sun2 <sustc18st@gmai.com> Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
This commit is contained in:
81
table-module/src/main/java/com/iluwatar/tablemodule/App.java
Normal file
81
table-module/src/main/java/com/iluwatar/tablemodule/App.java
Normal file
@ -0,0 +1,81 @@
|
||||
package com.iluwatar.tablemodule;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.h2.jdbcx.JdbcDataSource;
|
||||
|
||||
|
||||
/**
|
||||
* Table Module pattern is a domain logic pattern.
|
||||
* In Table Module a single class encapsulates all the domain logic for all
|
||||
* records stored in a table or view. It's important to note that there is no
|
||||
* translation of data between objects and rows, as it happens in Domain Model,
|
||||
* hence implementation is relatively simple when compared to the Domain
|
||||
* Model pattern.
|
||||
*
|
||||
* <p>In this example we will use the Table Module pattern to implement register
|
||||
* and login methods for the records stored in the user table. The main
|
||||
* method will initialise an instance of {@link UserTableModule} and use it to
|
||||
* handle the domain logic for the user table.</p>
|
||||
*/
|
||||
@Slf4j
|
||||
public final class App {
|
||||
private static final String DB_URL = "jdbc:h2:~/test";
|
||||
|
||||
/**
|
||||
* Private constructor.
|
||||
*/
|
||||
private App() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Program entry point.
|
||||
*
|
||||
* @param args command line args.
|
||||
* @throws SQLException if any error occurs.
|
||||
*/
|
||||
public static void main(final String[] args) throws SQLException {
|
||||
// Create data source and create the user table.
|
||||
final var dataSource = createDataSource();
|
||||
createSchema(dataSource);
|
||||
var userTableModule = new UserTableModule(dataSource);
|
||||
|
||||
// Initialize two users.
|
||||
var user1 = new User(1, "123456", "123456");
|
||||
var user2 = new User(2, "test", "password");
|
||||
|
||||
// Login and register using the instance of userTableModule.
|
||||
userTableModule.registerUser(user1);
|
||||
userTableModule.login(user1.getUsername(), user1.getPassword());
|
||||
userTableModule.login(user2.getUsername(), user2.getPassword());
|
||||
userTableModule.registerUser(user2);
|
||||
userTableModule.login(user2.getUsername(), user2.getPassword());
|
||||
|
||||
deleteSchema(dataSource);
|
||||
}
|
||||
|
||||
private static void deleteSchema(final DataSource dataSource)
|
||||
throws SQLException {
|
||||
try (var connection = dataSource.getConnection();
|
||||
var statement = connection.createStatement()) {
|
||||
statement.execute(UserTableModule.DELETE_SCHEMA_SQL);
|
||||
}
|
||||
}
|
||||
|
||||
private static void createSchema(final DataSource dataSource)
|
||||
throws SQLException {
|
||||
try (var connection = dataSource.getConnection();
|
||||
var statement = connection.createStatement()) {
|
||||
statement.execute(UserTableModule.CREATE_SCHEMA_SQL);
|
||||
}
|
||||
}
|
||||
|
||||
private static DataSource createDataSource() {
|
||||
var dataSource = new JdbcDataSource();
|
||||
dataSource.setURL(DB_URL);
|
||||
return dataSource;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.iluwatar.tablemodule;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
|
||||
/**
|
||||
* A user POJO that represents the data that will be read from the data source.
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@AllArgsConstructor
|
||||
public class User {
|
||||
private int id;
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
package com.iluwatar.tablemodule;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
||||
/**
|
||||
* This class organizes domain logic with the user table in the
|
||||
* database. A single instance of this class contains the various
|
||||
* procedures that will act on the data.
|
||||
*/
|
||||
@Slf4j
|
||||
public class UserTableModule {
|
||||
/**
|
||||
* Public element for creating schema.
|
||||
*/
|
||||
public static final String CREATE_SCHEMA_SQL =
|
||||
"CREATE TABLE IF NOT EXISTS USERS (ID NUMBER, USERNAME VARCHAR(30) "
|
||||
+ "UNIQUE,PASSWORD VARCHAR(30))";
|
||||
/**
|
||||
* Public element for deleting schema.
|
||||
*/
|
||||
public static final String DELETE_SCHEMA_SQL = "DROP TABLE USERS IF EXISTS";
|
||||
private final DataSource dataSource;
|
||||
|
||||
|
||||
/**
|
||||
* Public constructor.
|
||||
*
|
||||
* @param userDataSource the data source in the database
|
||||
*/
|
||||
public UserTableModule(final DataSource userDataSource) {
|
||||
this.dataSource = userDataSource;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Login using username and password.
|
||||
*
|
||||
* @param username the username of a user
|
||||
* @param password the password of a user
|
||||
* @return the execution result of the method
|
||||
* @throws SQLException if any error
|
||||
*/
|
||||
public int login(final String username, final String password)
|
||||
throws SQLException {
|
||||
var sql = "select count(*) from USERS where username=? and password=?";
|
||||
ResultSet resultSet = null;
|
||||
try (var connection = dataSource.getConnection();
|
||||
var preparedStatement =
|
||||
connection.prepareStatement(sql)
|
||||
) {
|
||||
var result = 0;
|
||||
preparedStatement.setString(1, username);
|
||||
preparedStatement.setString(2, password);
|
||||
resultSet = preparedStatement.executeQuery();
|
||||
while (resultSet.next()) {
|
||||
result = resultSet.getInt(1);
|
||||
}
|
||||
if (result == 1) {
|
||||
LOGGER.info("Login successfully!");
|
||||
} else {
|
||||
LOGGER.info("Fail to login!");
|
||||
}
|
||||
return result;
|
||||
} finally {
|
||||
if (resultSet != null) {
|
||||
resultSet.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new user.
|
||||
*
|
||||
* @param user a user instance
|
||||
* @return the execution result of the method
|
||||
* @throws SQLException if any error
|
||||
*/
|
||||
public int registerUser(final User user) throws SQLException {
|
||||
var sql = "insert into USERS (username, password) values (?,?)";
|
||||
try (var connection = dataSource.getConnection();
|
||||
var preparedStatement =
|
||||
connection.prepareStatement(sql)
|
||||
) {
|
||||
preparedStatement.setString(1, user.getUsername());
|
||||
preparedStatement.setString(2, user.getPassword());
|
||||
var result = preparedStatement.executeUpdate();
|
||||
LOGGER.info("Register successfully!");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.iluwatar.tablemodule;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
|
||||
/**
|
||||
* Tests that the table module example runs without errors.
|
||||
*/
|
||||
class AppTest {
|
||||
|
||||
@Test
|
||||
void shouldExecuteWithoutException() {
|
||||
assertDoesNotThrow(() -> App.main(new String[]{}));
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package com.iluwatar.tablemodule;
|
||||
|
||||
import org.h2.jdbcx.JdbcDataSource;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
class UserTableModuleTest {
|
||||
private static final String DB_URL = "jdbc:h2:~/test";
|
||||
|
||||
private static DataSource createDataSource() {
|
||||
var dataSource = new JdbcDataSource();
|
||||
dataSource.setURL(DB_URL);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws SQLException {
|
||||
try (var connection = DriverManager.getConnection(DB_URL);
|
||||
var statement = connection.createStatement()) {
|
||||
statement.execute(UserTableModule.DELETE_SCHEMA_SQL);
|
||||
statement.execute(UserTableModule.CREATE_SCHEMA_SQL);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() throws SQLException {
|
||||
try (var connection = DriverManager.getConnection(DB_URL);
|
||||
var statement = connection.createStatement()) {
|
||||
statement.execute(UserTableModule.DELETE_SCHEMA_SQL);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void loginShouldFail() throws SQLException {
|
||||
var dataSource = createDataSource();
|
||||
var userTableModule = new UserTableModule(dataSource);
|
||||
var user = new User(1, "123456", "123456");
|
||||
assertEquals(0, userTableModule.login(user.getUsername(),
|
||||
user.getPassword()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void loginShouldSucceed() throws SQLException {
|
||||
var dataSource = createDataSource();
|
||||
var userTableModule = new UserTableModule(dataSource);
|
||||
var user = new User(1, "123456", "123456");
|
||||
userTableModule.registerUser(user);
|
||||
assertEquals(1, userTableModule.login(user.getUsername(),
|
||||
user.getPassword()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerShouldFail() throws SQLException {
|
||||
var dataSource = createDataSource();
|
||||
var userTableModule = new UserTableModule(dataSource);
|
||||
var user = new User(1, "123456", "123456");
|
||||
userTableModule.registerUser(user);
|
||||
assertThrows(SQLException.class, () -> {
|
||||
userTableModule.registerUser(user);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerShouldSucceed() throws SQLException {
|
||||
var dataSource = createDataSource();
|
||||
var userTableModule = new UserTableModule(dataSource);
|
||||
var user = new User(1, "123456", "123456");
|
||||
assertEquals(1, userTableModule.registerUser(user));
|
||||
}
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
package com.iluwatar.tablemodule;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class UserTest {
|
||||
@Test
|
||||
void testCanEqual() {
|
||||
assertFalse((new User(1, "janedoe", "iloveyou"))
|
||||
.canEqual("Other"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCanEqual2() {
|
||||
var user = new User(1, "janedoe", "iloveyou");
|
||||
assertTrue(user.canEqual(new User(1, "janedoe",
|
||||
"iloveyou")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals1() {
|
||||
var user = new User(1, "janedoe", "iloveyou");
|
||||
assertNotEquals("42", user);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals2() {
|
||||
var user = new User(1, "janedoe", "iloveyou");
|
||||
assertEquals(user, new User(1, "janedoe",
|
||||
"iloveyou"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals3() {
|
||||
var user = new User(123, "janedoe", "iloveyou");
|
||||
assertNotEquals(user, new User(1, "janedoe",
|
||||
"iloveyou"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals4() {
|
||||
var user = new User(1, null, "iloveyou");
|
||||
assertNotEquals(user, new User(1, "janedoe",
|
||||
"iloveyou"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals5() {
|
||||
var user = new User(1, "iloveyou", "iloveyou");
|
||||
assertNotEquals(user, new User(1, "janedoe",
|
||||
"iloveyou"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals6() {
|
||||
var user = new User(1, "janedoe", "janedoe");
|
||||
assertNotEquals(user, new User(1, "janedoe",
|
||||
"iloveyou"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals7() {
|
||||
var user = new User(1, "janedoe", null);
|
||||
assertNotEquals(user, new User(1, "janedoe",
|
||||
"iloveyou"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals8() {
|
||||
var user = new User(1, null, "iloveyou");
|
||||
assertEquals(user, new User(1, null,
|
||||
"iloveyou"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals9() {
|
||||
var user = new User(1, "janedoe", null);
|
||||
assertEquals(user, new User(1, "janedoe",
|
||||
null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHashCode1() {
|
||||
assertEquals(-1758941372, (new User(1, "janedoe",
|
||||
"iloveyou")).hashCode());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHashCode2() {
|
||||
assertEquals(-1332207447, (new User(1, null,
|
||||
"iloveyou")).hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHashCode3() {
|
||||
assertEquals(-426522485, (new User(1, "janedoe",
|
||||
null)).hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetId() {
|
||||
var user = new User(1, "janedoe", "iloveyou");
|
||||
user.setId(2);
|
||||
assertEquals(2, user.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetPassword() {
|
||||
var user = new User(1, "janedoe", "tmp");
|
||||
user.setPassword("iloveyou");
|
||||
assertEquals("iloveyou", user.getPassword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetUsername() {
|
||||
var user = new User(1, "tmp", "iloveyou");
|
||||
user.setUsername("janedoe");
|
||||
assertEquals("janedoe", user.getUsername());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToString() {
|
||||
var user = new User(1, "janedoe", "iloveyou");
|
||||
assertEquals(String.format("User(id=%s, username=%s, password=%s)",
|
||||
user.getId(), user.getUsername(), user.getPassword()),
|
||||
user.toString());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user