ORM for Java: Comparison and Examples
ORM (Object-Relational Mapping) is a technology that links the object-oriented Java model with relational databases. It relieves the developer from writing boilerplate SQL code and allows working with data as regular Java objects. In Java, three approaches are most popular: Hibernate (full-featured ORM), MyBatis (SQL mapper), and JPA (Java standard). In this article, we will compare them with practical examples.
1. JPA (Java Persistence API)
JPA is a specification (standard), not a specific implementation. The most popular implementation is Hibernate, but there are others (EclipseLink, OpenJPA). JPA provides annotations for entity mapping and supports JPQL (Java Persistence Query Language).
Example of a JPA entity:
import javax.persistence.*;
@Entity@Table(name = "users")public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
@Column(name = "username", nullable = false, length = 50) private String username;
@Column(name = "email") private String email;
// getters and setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; }}Example of saving via EntityManager:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-persistence-unit");EntityManager em = emf.createEntityManager();
em.getTransaction().begin();User user = new User();user.setUsername("ivan");user.setEmail("ivan@example.com");em.persist(user);em.getTransaction().commit();
em.close();emf.close();2. Hibernate
Hibernate is the most mature and feature-rich ORM for Java. It fully implements JPA but also has its own extensions. Hibernate automatically generates SQL, manages caching, supports lazy loading, and cascade operations.
Example of mapping with Hibernate (using JPA annotations):
import org.hibernate.annotations.Cache;import org.hibernate.annotations.CacheConcurrencyStrategy;
@Entity@Table(name = "orders")@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)public class Order { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "order_seq") @SequenceGenerator(name = "order_seq", sequenceName = "order_sequence", allocationSize = 1) private Long id;
@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") private User user;
@Column(name = "total_amount") private Double totalAmount;
// getters and setters}Example of a query using Hibernate Criteria API:
Session session = sessionFactory.openSession();CriteriaBuilder builder = session.getCriteriaBuilder();CriteriaQuery<User> query = builder.createQuery(User.class);Root<User> root = query.from(User.class);query.select(root).where(builder.equal(root.get("username"), "ivan"));
List<User> users = session.createQuery(query).getResultList();session.close();3. MyBatis
MyBatis is not a full-fledged ORM, but an SQL Mapper. It does not generate SQL automatically, but provides a flexible mechanism for writing your own SQL queries with mapping results to Java objects. MyBatis is ideal when you need full control over SQL and performance.
Example of mapping in XML (UserMapper.xml):
<mapper namespace="com.example.mapper.UserMapper"> <select id="selectUser" resultType="User">\