Skip to content

Instantly share code, notes, and snippets.

@mcamou
Last active December 14, 2015 08:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcamou/5058109 to your computer and use it in GitHub Desktop.
Save mcamou/5058109 to your computer and use it in GitHub Desktop.
Ejemplos para el debate sobre ORM de MadridJUG
##### JPA - embedding
@Embeddable
public class AuditInfo implements Serializable {
protected static final long serialVersionUID = 1L;
@Temporal(TemporalType.TIMESTAMP)
@Column(nullable = false)
private Date createdAt;
@Temporal(TemporalType.TIMESTAMP)
@Column(nullable = false)
private Date updatedAt;
@Column(nullable = false)
private String createdBy;
@Column(nullable = false)
private String updatedBy;
//... getters and setters...
}
@Entity
public abstract class Person {
protected static final long serialVersionUID = 1L;
@Embedded
private AuditInfo auditInfo;
//... more Person stuff...
}
##### ActiveRecord - Embedding
class AuditInfo {
attr_reader :created_at, :updated_at, :created_by, :updated_by
# ... constructor
}
class Person < ActiveRecord::Base
composed_of :audit_info, :class_name => "AuditInfo", :mapping => %w(created_at, updated_at, created_by, updated_by)
# More Person stuff...
end
##### DataMapper - embedding
class Person
include DataMapper::Resource
property :audit_info, AuditInfo # Embedded Value
#... more Person stuff
end
class AuditInfo
include DataMapper::EmbeddedValue
property :created_at, String
property :created_by, String
property :updated_at, String
property :updated_by, String
end
##### JPA - Single-table inheritance
@Entity
@Table(name = "unidad")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "tipo_unidad")
public abstract class Unidad {
...
}
@Entity
@DiscriminatorValue("UnidadConjunto")
public class UnidadConjunto extends Unidad {
...
}
##### ActiveRecord - Single-table inheritance
class Unidad < ActiveRecord::Base
set_inheritance_column('tipo_unidad')
# ...
end
class UnidadConjunto < Unidad
# ...
end
##### DataMapper - Single-table inheritance
class Unidad
include DataMapper::Resource
property :tipo_unidad, Discriminator
# ...
end
class UnidadConjunto < Unidad
# ...
end
##### JPA - Multiple-table inheritance
@Entity
@Table(name = "unidad")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "tipo_unidad")
public abstract class Unidad {
...
}
@Entity
@DiscriminatorValue("UnidadConjunto")
public class UnidadConjunto extends Unidad {
...
}
##### JPA - Concrete-table inheritance
@Entity
@Table(name = "unidad")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn(name = "tipo_unidad")
public abstract class Unidad {
...
}
@Entity
@DiscriminatorValue("UnidadConjunto")
public class UnidadConjunto extends Unidad {
...
}
##### JPA - relaciones
@Entity
public class Operador {
# 1:N
@OneToMany(mappedBy = "operador_id", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@PrivateOwned
private Collection<Direccion> direcciones = new ArrayList<Direccion>();
# N:N sin atributos en la tabla intermedia
@JoinTable(name = "oper_zona", joinColumns = {
@JoinColumn(name = "operador_id", referencedColumnName = "id")}, inverseJoinColumns = {
@JoinColumn(name = "zona_id", referencedColumnName = "id")})
@ManyToMany
private Collection<Zona> zonas = new ArrayList<Zona>();
// ....
}
@Entity
public class Direccion {
# N:1
@JoinColumn(name = "operador_id", referencedColumnName = "id")
@ManyToOne
private Operador operador_id;
//...
}
##### DataMapper y ActiveRecord - relaciones
http://datamapper.org/docs/associations.html
DataMapper Terminology ActiveRecord Terminology
has n has_many
has 1 has_one
belongs_to belongs_to
has n, :things, :through => Resource has_and_belongs_to_many
has n, :things, :through => :model has_many :association, :through => Model
##### ActiveRecord - relaciones
class Operador
has_many :direccions
has_many :zonas :through => OperZona
end
class Direccion
belongs_to :operador
end
##### JPA - relación autorreferencial
@Entity
public class Employee implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@ManyToOne
private A manager;
@OneToMany(mappedBy="manager")
private Collection<A> subordinates;
// ... More Employee stuff
}
##### ActiveRecord - relación autorreferencial
http://railscasts.com/episodes/163-self-referential-association
http://johnford.is/has_many-through-self-referential-example/
##### DataMapper - relación autorreferencial
http://datamapper.org/docs/associations.html
##### ActiveRecord - relaciones bidireccionales
class Listing < ActiveRecord::Base
has_many :communications, inverse_of: :listing
end
class Communication < ActiveRecord::Base
belongs_to :listing, inverse_of: :communications
end
##### DataMapper - relaciones bidireccionales
https://github.com/datamapper/dm-core/issues/82
##### JPA - eager vs. lazy
@Entity
public class Person {
@Id
public Integer id;
public String name;
@ManyToOne(fetch=FetchType.LAZY or EAGER)
public Address address;
}
##### JPA - Fetch Joins (eager vs. lazy)
SELECT p FROM Person p JOIN FETCH p.address
##### ActiveRecord - eager vs. lazy
http://www.spritle.com/blogs/2011/03/17/eager-loading-and-lazy-loading-in-rails-activerecord/
Person.find(:all, :include => [ :address ]).each {
#...
}
Post.includes([:author, :comments]).where(['comments.approved = ?', true]).all
##### DataMapper - eager vs. lazy
http://datamapper.org/articles/spotlight_on_laziness.html
class Post
include DataMapper::Resource
property :id, Serial # auto_incrementing primary key
property :title, String, :lazy => true # intentionally lazy
property :body, Text # lazy by default
end
##### DataMapper - contextual lazy loading
class Post
include DataMapper::Resource
property :id, Serial
property :title, String, :lazy => [ :summary, :brief ]
property :body, Text, :lazy => [ :summary ]
end
##### DataMapper.repository(:summary) do
Post.first
end
##### JPA (EclipseLink): Paginación de resultados (cursores, N+1)
Query query = em.createQuery("SELECT e FROM Employee e ORDER BY e.lastName ASC, e.firstName ASC");
query.setHint("eclipselink.cursor.scrollable", true);
ScrollableCursor scrollableCursor = (ScrollableCursor)query.getSingleResult();
List<Employee> emps = scrollableCursor.next(10);
TypedQuery<Contact> query = em.createQuery("SELECT c FROM Contact c WHERE c.name = :NAME ORDER BY c.id", Contact.class);
query.setParameter("NAME", "Liam");
List<Contact> results = new PagingList<Contact>(query, 20);
##### ActiveRecord: paginación de resultados
User.find_each(:batch_size => 20) do |user|
NewsLetter.weekly_deliver(user)
end
##### DataMapper: Ad-hoc queries
http://stackoverflow.com/questions/993868/complex-datamapper-query-association
class User
def item_views
repository.adapter.query "SELECT i.id, i.title, COUNT(*) as 'num'
FROM actions a
JOIN items i on i.id = a.item_id
WHERE a.user_id = {USERID}
GROUP by a.id
ORDER BY num DESC
LIMIT 10;"
end
end
# repository.adapter.query returns an Array of structs so you could do things like user.item_views[0].title
##### JPA: Complex joins (JPQL)
List result = em.createQuery (
"SELECT e.name, e.department.name \
FROM Project p JOIN p.employees e \
WHERE p.name = ?1 \
ORDER BY e.name")
.setParameter(1,projectName)
.getResultList();
##### ActiveRecord: Complex joins
http://guides.rubyonrails.org/active_record_querying.html#joining-tables
##### DataMapper: Complex joins (QueryPath)
Customer.all(Customer.orders.order_lines.item.sku.like => "%BLUE%")
##### OpenSessionInView
http://dev.eclipse.org/mhonarc/lists/eclipselink-users/msg05753.html
##### Persist vs. Merge
http://stackoverflow.com/questions/1069992/jpa-entitymanager-why-use-persist-over-merge
http://www.java.net/node/667740
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment