@@ -44,30 +44,46 @@ public class User {
4444 private Integer id;
4545 private String name;
4646 private String email;
47-
48- public User (Integer id , String name , String email ) {
49- this . id = id;
50- this . name = name;
51- this . email = email;
47+
48+ /**
49+ * User constructor.
50+ *
51+ * @param userId the unique identifier of the user
52+ * @param userName the name of the user
53+ * @param userEmail the email address of the user
54+ */
55+ public User (
56+ final Integer userId ,
57+ final String userName ,
58+ final String userEmail ) {
59+ this . id = userId;
60+ this . name = userName;
61+ this . email = userEmail;
5262 }
63+
64+ /**
65+ * Getters and setters
66+ */
5367 public Integer getId () {
5468 return id;
5569 }
70+
5671 public String getName () {
5772 return name;
5873 }
74+
75+ public void setName (final String userName ) {
76+ this . name = userName;
77+ }
78+
5979 public String getEmail () {
6080 return email;
6181 }
62-
63- public void setName (String name ) {
64- this . name = name;
82+ public void setEmail (final String userEmail ) {
83+ this . email = userEmail;
6584 }
6685
67- public void setEmail (String email ) {
68- this . email = email;
6986 }
70- }
7187```
7288
7389For convenience, we are storing the database configuration logic inside the same User class:
@@ -76,26 +92,31 @@ For convenience, we are storing the database configuration logic inside the same
7692
7793 // Credentials for in-memory H2 database.
7894
79- private static final String JDBC_URL = " jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" ;
80- private static final String USERNAME = " sa" ;
81- private static final String PASSWORD = " " ;
82-
95+ private static final String JDBC_URL = " jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" ;
96+ private static final String USERNAME = " sa" ;
97+ private static final String PASSWORD = " " ;
98+
99+
83100 // Establish a database connection.
84101
85- private static Connection connect() throws SQLException {
86- return DriverManager . getConnection(JDBC_URL , USERNAME , PASSWORD );
87- }
102+ private static Connection connect() throws SQLException {
103+ return DriverManager . getConnection(JDBC_URL , USERNAME , PASSWORD );
104+ }
88105
89106 // Initialize the table (required each time program runs
90107 // as we are using an in-memory DB solution).
91108
92- public static void initializeTable() throws SQLException {
93- String sql = " CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, email TEXT)" ;
94- try (Connection conn = connect();
95- Statement stmt = conn. createStatement()) {
96- stmt. execute(sql);
97- }
98- }
109+ public static void initializeTable() throws SQLException {
110+ String sql = " CREATE TABLE IF NOT EXISTS users (\n "
111+ + " id INTEGER PRIMARY KEY AUTO_INCREMENT,\n "
112+ + " name VARCHAR(255),\n "
113+ + " email VARCHAR(255)\n "
114+ + " );" ;
115+ try (Connection conn = connect();
116+ Statement stmt = conn. createStatement()) {
117+ stmt. execute(sql);
118+ }
119+ }
99120```
100121
101122After configuring the database, our User class will contain methods thar mimic the typical CRUD operations performed on a database entry:
@@ -114,7 +135,8 @@ public void save() throws SQLException {
114135 sql = " UPDATE users SET name = ?, email = ? WHERE id = ?" ;
115136 }
116137 try (Connection conn = connect();
117- PreparedStatement pstmt = conn. prepareStatement(sql, Statement . RETURN_GENERATED_KEYS )) {
138+ PreparedStatement pstmt = conn. prepareStatement(
139+ sql, Statement . RETURN_GENERATED_KEYS )) {
118140 pstmt. setString(1 , this . name);
119141 pstmt. setString(2 , this . email);
120142 if (this . id != null ) {
@@ -135,17 +157,22 @@ public void save() throws SQLException {
135157 * Find a user by ID.
136158 */
137159
138- public static User findById(int id) throws SQLException {
160+ public static Optional< User > findById(final int id) {
139161 String sql = " SELECT * FROM users WHERE id = ?" ;
140162 try (Connection conn = connect();
141163 PreparedStatement pstmt = conn. prepareStatement(sql)) {
142164 pstmt. setInt(1 , id);
143165 ResultSet rs = pstmt. executeQuery();
144166 if (rs. next()) {
145- return new User (rs. getInt(" id" ), rs. getString(" name" ), rs. getString(" email" ));
167+ return Optional . of(new User (
168+ rs. getInt(" id" ),
169+ rs. getString(" name" ),
170+ rs. getString(" email" )));
146171 }
172+ } catch (SQLException e) {
173+ LOGGER . error(" SQL error: {}" , e. getMessage(), e);
147174 }
148- return null ;
175+ return Optional . empty() ;
149176}
150177/**
151178 * Get all users.
@@ -158,7 +185,10 @@ public static List<User> findAll() throws SQLException {
158185 Statement stmt = conn. createStatement();
159186 ResultSet rs = stmt. executeQuery(sql)) {
160187 while (rs. next()) {
161- users. add(new User (rs. getInt(" id" ), rs. getString(" name" ), rs. getString(" email" )));
188+ users. add(new User (
189+ rs. getInt(" id" ),
190+ rs. getString(" name" ),
191+ rs. getString(" email" )));
162192 }
163193 }
164194 return users;
@@ -188,45 +218,59 @@ Finally, here is the Active Record Pattern in action:
188218``` java
189219public static void main(final String [] args) {
190220 try {
191- // Initialize the database and create the users table if it doesn't exist
221+ // Initialize the database and create the users table
192222 User . initializeTable();
193223 LOGGER . info(" Database and table initialized." );
194224
195225 // Create a new user and save it to the database
196- User user1
= new User (
null ,
" John Doe" ,
" [email protected] " );
226+ User user1 = new User (
227+ null ,
228+ " John Doe" ,
229+ 197230 user1. save();
198- LOGGER . info(" New user saved: {} with ID {}" , user1. getName(), user1. getId());
231+ LOGGER . info(" New user saved: {} with ID {}" ,
232+ user1. getName(), user1. getId());
199233
200234 // Retrieve and display the user by ID
201- User foundUser = User . findById(user1. getId());
202- if ( foundUser != null ) {
203- LOGGER . info(" User found: {} with email {}" , foundUser . getName(), foundUser . getEmail());
204- } else {
205- LOGGER . info(" User not found." );
206- }
235+ Optional< User > foundUser = User . findById(user1. getId());
236+ foundUser. ifPresentOrElse(
237+ user - > LOGGER . info(" User found: {} with email {}" ,
238+ user . getName(), user . getEmail()),
239+ () - > LOGGER . info(" User not found." )
240+ );
207241
208242 // Update the user’s details
209- assert foundUser != null ;
210- foundUser. setName(" John Updated" );
211- foundUser
. setEmail(
" [email protected] " );
212- foundUser. save();
213- LOGGER . info(" User updated: {} with email {}" , foundUser. getName(), foundUser. getEmail());
243+ Optional<User > foundUserOpt = User . findById(user1. getId());
244+ foundUserOpt. ifPresent(user - > {
245+ user. setName(" John Updated" );
246+ user
. setEmail(
" [email protected] " );
247+ try {
248+ user. save();
249+ } catch (SQLException e) {
250+ throw new RuntimeException (e);
251+ }
252+ LOGGER . info(" User updated: {} with email {}" ,
253+ user. getName(), user. getEmail());
254+ });
214255
215256 // Retrieve all users
216257 List<User > users = User . findAll();
217258 LOGGER . info(" All users in the database:" );
218259 for (User user : users) {
219- LOGGER . info(" ID: {}, Name: {}, Email: {}" , user. getId(), user. getName(), user. getEmail());
260+ LOGGER . info(" ID: {}, Name: {}, Email: {}" ,
261+ user. getId(), user. getName(), user. getEmail());
220262 }
221263
222264 // Delete the user
223- try {
224- LOGGER . info(" Deleting user with ID: {}" , foundUser. getId());
225- foundUser. delete();
226- LOGGER . info(" User successfully deleted!" );
227- } catch (Exception e) {
228- LOGGER . error(e. getMessage(), e);
229- }
265+ foundUserOpt. ifPresentOrElse(user - > {
266+ try {
267+ LOGGER . info(" Deleting user with ID: {}" , user. getId());
268+ user. delete();
269+ LOGGER . info(" User successfully deleted!" );
270+ } catch (Exception e) {
271+ LOGGER . error(" Error deleting user with ID: {}" , user. getId(), e);
272+ }
273+ }, () - > LOGGER . info(" User not found to delete." ));
230274
231275 } catch (SQLException e) {
232276 LOGGER . error(" SQL error: {}" , e. getMessage(), e);
@@ -237,14 +281,14 @@ public static void main(final String[] args) {
237281The program outputs:
238282
239283```
240- 19:34:53.731 [main] INFO com.iluwatar.activerecord.App -- Database and table initialized.
241- 19:34:53.755 [main] INFO com.iluwatar.activerecord.App -- New user saved: John Doe with ID 1
242- 19:34:53.759 [main] INFO com.iluwatar.activerecord.App -- User found: John Doe with email [email protected] 243- 19:34:53.762 [main] INFO com.iluwatar.activerecord.App -- User updated: John Updated with email [email protected] 244- 19:34:53.764 [main] INFO com.iluwatar.activerecord.App -- All users in the database:
245- 19:34:53.764 [main] INFO com.iluwatar.activerecord.App -- ID: 1, Name: John Updated, Email: [email protected] 246- 19:34:53.764 [main] INFO com.iluwatar.activerecord.App -- Deleting user with ID: 1
247- 19:34:53.768 [main] INFO com.iluwatar.activerecord.App -- User successfully deleted!
284+ 21:32:55.119 [main] INFO com.iluwatar.activerecord.App -- Database and table initialized.
285+ 21:32:55.128 [main] INFO com.iluwatar.activerecord.App -- New user saved: John Doe with ID 1
286+ 21:32:55.141 [main] INFO com.iluwatar.activerecord.App -- User found: John Doe with email [email protected] 287+ 21:32:55.145 [main] INFO com.iluwatar.activerecord.App -- User updated: John Updated with email [email protected] 288+ 21:32:55.145 [main] INFO com.iluwatar.activerecord.App -- All users in the database:
289+ 21:32:55.145 [main] INFO com.iluwatar.activerecord.App -- ID: 1, Name: John Updated, Email: [email protected] 290+ 21:32:55.146 [main] INFO com.iluwatar.activerecord.App -- Deleting user with ID: 1
291+ 21:32:55.147 [main] INFO com.iluwatar.activerecord.App -- User successfully deleted!
248292```
249293
250294## When to Use the Active Record Pattern in Java
0 commit comments