orm is an offensive anti-pattern

24
/20 @yegor256 1 ORM is an Oensive Anti-Pattern Yegor Bugayenko

Upload: yegor-bugayenko

Post on 16-Jan-2017

272 views

Category:

Software


1 download

TRANSCRIPT

Page 1: ORM is an Offensive Anti-Pattern

/20@yegor256 1

ORM is an OffensiveAnti-Pattern

Yegor Bugayenko

Page 2: ORM is an Offensive Anti-Pattern

/20@yegor256 2

what’s wrongwith data?

Page 3: ORM is an Offensive Anti-Pattern

/20@yegor256 3

ANSI Ctypedef struct { int x; int y; } Point;

void moveTo(Point p, int dx, int dy) { p.x += dx; if (p.x > 640) { p.x = 640; } p.y += dy; if (p.y > 480) { p.y = 480; } }

void draw(Point p, Canvas c) { c.put(p.x, p.y, “black”); }

Page 4: ORM is an Offensive Anti-Pattern

/20@yegor256 4

typedef struct { int x; int y; int color; // here! int scale; // here! } Point;

void moveTo(Point p, int dx, int dy) { p.x += dx; if (p.x > 640) { p.x = 640; } p.y += dy; if (p.y > 480) { p.y = 480; } }

void draw(Point p, Canvas c) { c.put(p.x, p.y, “black”); }

Page 5: ORM is an Offensive Anti-Pattern

/20@yegor256 5

maintainability

command & control trust & delegatevs

Page 6: ORM is an Offensive Anti-Pattern

/20@yegor256 6

class Point { private int x; private int y; void moveTo(int dx, int dy) { this.x += dx; if (this.x > 640) { this.x = 640; } this.y += dy; if (this.y > 480) { this.y = 480; } } void draw(Canvas c) { c.put(this.x, this.y, “black”); } }

Page 7: ORM is an Offensive Anti-Pattern

/20@yegor256 7

encapsulation

Page 8: ORM is an Offensive Anti-Pattern

/20@yegor256 8

Java

class Point { private int x; private int y; public int getX() { return this.x; } public int getX() { return this.y; } public void setX(int x) { this.x = x; } public void setY(int y) { this.y = y; } }

class PointUtils { static void moveTo(Point p, int dx, int dy) { p.setX(p.getX() + dx); if (p.getX() > 640) { p.setX(640); } p.setY(p.getY() + dy); if (p.getY() > 480) { p.setY(480); } } static void draw(Point p, Canvas c) { c.put(p.getX(), p.getY(), “black”); } }

Page 9: ORM is an Offensive Anti-Pattern

/20@yegor256 9

ORM/JPA/Hibernate

Page 10: ORM is an Offensive Anti-Pattern

/20@yegor256 10

@Entity @Table(name = "point") public class Point { private int id; @Id @GeneratedValue public int getId() { return this.id; } @Column(name = "x") public int getX() { return this.x; } public void setX(int x) { this.x = x; } @Column(name = "y") public int getY() { return this.y; } public void setY(int y) { this.y = y; } }

Page 11: ORM is an Offensive Anti-Pattern

/20@yegor256 11

void static moveTo(int id, int dx, int dy) { Session session = factory.openSession(); try { Transaction txn = session.beginTransaction(); Query query = session.createQuery(“SELECT p FROM point WHERE id=:id”); query.setParameter(“:id”, id); Point p = query.list().get(0); p.setX(p.getX() + dx); p.setY(p.getY() + dy); session.update(p); txn.commit(); } catch (HibernateException ex) { txn.rollback(); } finally { session.close(); } }

Page 12: ORM is an Offensive Anti-Pattern

/20@yegor256 12

PostgreSQL

JDBC

UPDATE point SET x = “100”, y = “120” WHERE id = 123

p.getX(); p.getY(); statement.executeUpdate();setX()

Query query = session.createQuery(“SELECT p FROM point WHERE id=:id”); query.setParameter(“:id”, id); Point p = query.list().get(0); p.setX(p.getX() + dx); p.setY(p.getY() + dy); session.update(p);

update()Point

Session

setY()

Page 13: ORM is an Offensive Anti-Pattern

/20@yegor256 13

JDBCPoint

Session

client

Page 14: ORM is an Offensive Anti-Pattern

/20@yegor256 14

what is the alternative?

Page 15: ORM is an Offensive Anti-Pattern

/20@yegor256 15

JDBC

Point

adapter

client

Page 16: ORM is an Offensive Anti-Pattern

/20@yegor256 16

PostgreSQL

JDBC

UPDATE point SET x = “100”, y = “120” WHERE id = 123

statement.executeUpdate();

Point p = new Point(123, db); p.moveTo(50, 70);

moveTo()

Point

x.update(“point”) .set(“x”, this.x) .set(“y”, this.y) .where(“id”, this.id) .execute();jOOQ

Page 17: ORM is an Offensive Anti-Pattern

/20@yegor256 17

class Point { private final DB db; private final int id; public void moveTo(int dx, int dy) { this.db.update(“point”) .set(“x”, ??) .set(“y”, ??) .where(“id”, this.id) .execute(); } }

Page 18: ORM is an Offensive Anti-Pattern

/20@yegor256 18

no mapping!

Page 19: ORM is an Offensive Anti-Pattern

/20@yegor256 19

jOOQ

jcabi-jdbc

JDBC JDBI

DbUtils

Yank

Page 20: ORM is an Offensive Anti-Pattern

/20@yegor256 20

Volume 2

Section 6.5

Page 21: ORM is an Offensive Anti-Pattern

/20@yegor256 21

Point p = new Point(new Cached(mysql)); p.draw(canvas1); p.draw(canvas2);

cache

Page 22: ORM is an Offensive Anti-Pattern

/20@yegor256 22

class Point extends ActiveRecord { protected int x; protected int y; void moveTo(int dx, int dy) { this.x += dx; this.y += dy; this.update(); // from parent class } }

ActiveRecord

Page 23: ORM is an Offensive Anti-Pattern

/20@yegor256 23

class Point { void moveUp(int dy) { // UPDATE point SET y = ? } void moveRight(int dx) { // UPDATE point SET x = ? } void moveTo(int dx, int dy) { // UPDATE point SET x = ?, y = ? } }

updates

Page 24: ORM is an Offensive Anti-Pattern

/20@yegor256 24

db = new TransactionAwareDB(db); db.start(); try { Point p1 = new Point(1, db); Point p2 = new Point(2, db); p1.moveTo(15, 30); p2.moveTo(7, 13); db.commit(); } catch (Exception ex) { db.rollback(); }

transactions