A javabean is a custom class which often represents real-world data and encapsulates private properties by public getter and setter methods. For example, User, Product, Order, etc.
Javabeans
A javabean is a custom class which often represents real-world data and encapsulates private properties by public getter and setter methods. For example, User
, Product
, Order
, etc. In applications using a database, they are often 1:1 mapped to a database table. A single database row can then be represented by a single javabean instance.
Basic example
Here's an example of a javabean representing an User
(some newlines are omitted for brevity):
public class User implements java.io.Serializable {
// Properties.
private Long id;
private String name;
private Date birthdate;
// Getters.
public Long getId() { return id; }
public String getName() { return name; }
public Date getBirthdate() { return birthdate; }
// Setters.
public void setId(Long id) { this.id = id; }
public void setName(String name) { this.name = name; }
public void setBirthdate(Date birthdate) { this.birthdate = birthdate; }
// Important java.lang.Object overrides.
public boolean equals(Object other) {
return (other instanceof User) && (id != null) ? id.equals(((User) other).id) : (other == this);
}
public int hashCode() {
return (id != null) ? (getClass().hashCode() + id.hashCode()) : super.hashCode();
}
public String toString() {
return String.format("User[id=%d,name=%s,birthdate=%d]", id, name, birthdate);
}
}
Implementing Serializable
is mandatory, in order to be able to persist or transfer javabeans outside Java's memory; E.G. on a disk drive, a database, or over the network. In case of web applications, some servers will do that with HTTP sessions (e.g. save to disk before restart, or share with other servers in cluster). Any internal variables that do not have getters/setters should be marked transient
to prevent them from being serialized.
Implementing toString()
is not mandatory, but it is very useful if you'd like to be able to log/print the object to a logger/stdout and see a bit more detail than only com.example.User@1235678
.
Implementing equals()
and hashCode()
is mandatory for the case you'd like to collect them in a Set
or a HashMap
, otherwise different instances of javabeans which actually contain/represent the same data would be treated as different representations.
Code generation
A bit sane IDE like Eclipse/IntelliJ/Netbeans can autogenerate all necessary constructors and methods based on only a bunch of fields. So you could just start off with only the necessary fields:
public class User implements java.io.Serializable {
private Long id;
private String name;
private Date birthdate;
}
And then right click somewhere in the source code and choose Source and then you'll get a list of various useful Javabean-related options such as generating of getters/setters, hashCode()
/equals()
and toString()
.
Usage example - JDBC
In for example a JDBC database access object (DAO) class you can use it to create a list of users wherein you store the data of the User
table in the database:
public List<User> list() throws SQLException {
List<User> users = new ArrayList<User>();
try (
Connection connection = database.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT id, name, birthdate FROM User");
ResultSet resultSet = statement.executeQuery();
) {
while (resultSet.next()) {
User user = new User();
user.setId(resultSet.getLong("id"));
user.setName(resultSet.getString("name"));
user.setBirthdate(resultSet.getDate("birthdate"));
users.add(user);
}
}
return users;
}
Usage example - Servlet
In for example a Servlet class you can use it to transfer data from the database to the UI:
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
List<User> users = userDAO.list();
request.setAttribute("users", users);
request.getRequestDispatcher("/WEB-INF/users.jsp").forward(request, response);
}
Usage example - JSP
In for example a JSP page you can access it by EL, which follows the javabean conventions, to display the data:
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Birthdate</th>
</tr>
<c:forEach items="${users}" var="user">
<tr>
<td>${user.id}</td>
<td><c:out value="${user.name}" /></td>
<td><fmt:formatDate value="${user.birthdate}" pattern="yyyy-MM-dd" /></td>
</tr>
</c:forEach>
</table>
(note: the <c:out>
is just to prevent XSS holes while redisplaying user-controlled input as string)