activejdbc - activerecord implementation in java
DESCRIPTION
ActiveJDBC is a fast ORM an implementation of ActiveRecord in JavaTRANSCRIPT
![Page 1: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/1.jpg)
ActiveJDBC == ActiveRecord for Java
By Igor PolevoyAugust 2010
![Page 2: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/2.jpg)
Who the heck is Igor Polevoy?and why should we trust him?
• Developer like you• Architect• Teach Java/Rails at DePaul IPD• Battle-beaten on IT projects• Currently hacking away at Groupon,
Chicago
![Page 3: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/3.jpg)
..but why?
• Hibernate• JDO• JPA• iBatis• Castor• Torque• JPersist• …20 more??
![Page 4: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/4.jpg)
Dissatisfaction
• Hibernate: very powerful, but complicated, hard to setup, people have theories how it works, feels like a straight jacket, hard to learn
• JPA – different configuration on every platform, not as feature reach as Hibernate, feels like a black box.
• Most of all: getters/setters• Not OO!
![Page 5: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/5.jpg)
ActiveRecord just feels right
• DHH is a great API designer• AR simple to use, yet provides a level of
sophistication• Does not try to solve every problem under
sun, but covers 80% of what you need; you can get your work done faster…much faster!
• Complicated DB schemas ==usually== wrong design
![Page 6: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/6.jpg)
Who are parents of invention?
If necessity is a motherthen…
laziness is its father!
![Page 7: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/7.jpg)
ActiveJDBC Design principles
• Should infer metadata from DB• Should be very easy to work with• Should reduce amount of code to a minimum• No configuration, just conventions• Conventions are overridable in code• No need to learn another language• No need to learn another QL SQL is sufficient• Code must be lightweight and intuitive, should read like
English• No sessions, no "attaching, reattaching"• No persistence managers.• No classes outside your own models.• Models are lightweight, no transient fields• No proxying. What you write is what you get (WYWIWYG :))• Should have the least possible resistance to startup a project• No useless getters and setters (they just pollute code). You
can still write them if you like.• No DAOs and DTOs this is mostly junk code anyway
![Page 8: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/8.jpg)
ActiveJDBC is thin
• The main design principle:– thin!!!– 4 – 5 methods on stack traces
• Fast: simple non-scientific performance test: read 50K records from DB:– 2 times slower than JDBC– 40% times faster than Hibernate– no cache enabled
• No dependencies...almost– Slf4j– OSCache (only if needed)
• Size ~ 100k jar
![Page 9: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/9.jpg)
Surrogate PKs
• Same as ActiveRecord• Easy with MySQL, PostgreSQL• Harder with Oracle (but doable, more
SQL, see website)
![Page 10: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/10.jpg)
Writing Models (Entities)
Fully functional model:
public class Person extends Model {}
•Maps to table PEOPLE
•Know all necessary details about this table from database
•Immediately ready for CRUD operations
![Page 11: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/11.jpg)
Select
List<Person> johns =
Person.where(“last_name =‘John’”);
//iterate:for(Person p: people){log(p);
}
![Page 12: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/12.jpg)
Select with associations
class Address extends Model{}//table ADDRESSES has column person_id
Person p = Person.findFirst(“ssn = ?”,”123-34-5678”);
List<Address> addresses = p.getAll(Address.class);
Same API exactly for One to Many, Many to Many and Polymorphic associations!
![Page 13: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/13.jpg)
Select with Fluent Interfaces
List<Person> people = Person.where(“age > 21”)
.limit(40).offset(20).orderBy("age asc");
![Page 14: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/14.jpg)
Create new data
Person p = new Person();p.set("first_name", "John");p.set("last_name", "Doe");p.set("dob", "1935-12-06");p.saveIt();
![Page 15: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/15.jpg)
Create shortcuts (method chaining)
Person p = new Person(); p.set("name", "John") .set("last_name","Doe") .set("dob", "1935-12-06") .saveIt();
![Page 16: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/16.jpg)
Create class shortcut
Person.createIt("first_name", "Sam", "last_name", "Margulis", "dob", "2001-01-07");
Arguments: name, value, name1, value1, etc., reads like English
![Page 17: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/17.jpg)
Validations
public class Person extends Model { static{ validatePresenceOf("first_name","last_name"; } }
![Page 18: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/18.jpg)
Validation, fluent interfaces style
public class Percentage extends Model { static{ validateNumericalityOf("total") .allowNull(true) .greaterThan(0) .lessThan(100) .onlyInteger() .message("incorrect 'total'"); }}
![Page 19: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/19.jpg)
save() and saveit()
• Same as save and save! in ActiveRecord
![Page 20: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/20.jpg)
One to Many
User:public class User extends Model {}
Address:public class Address extends Model {}
List<Address> addresses = user.getAll(Address.class);
Condition: table ADDRESSES needs to have column user_id
![Page 21: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/21.jpg)
Many to many
Model for table DOCTORS:public class Doctor extends Model {}
Model for table PATIENTS:public class Patient extends Model {}
List<Patient> patients = doctor.getAll(Patient.class);
or:
List<Doctor> doctors = patient.getAll(Doctor.class);
• Condition: have table DOCTORS_PATIENTS with columns doctor_id, patient_id
![Page 22: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/22.jpg)
Adding/removing associated entries
Adding:user.add(address); //one to manydoctor.add(patient); //many to manyarticle.add(tag); //polymorphicRemoving:user.remove(address); //one to manydoctor.remove(patient); //many to manyarticle.remove(tag); //polymorphic
![Page 23: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/23.jpg)
Auto-generated fields
• created_at – set at creation time
• updated_at – set at update time, as well as batch updates
• id (can override name, value generated by DB)
![Page 24: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/24.jpg)
Caching
@Cached
public class Library extends Model {}
Supports efficient clustering (courtesy OSCache)
![Page 25: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/25.jpg)
Life-cycle callbacks
void beforeSave(); void afterSave(); void beforeCreate(); void afterCreate(); void beforeDelete(); void afterDelete(); void beforeValidation(); void afterValidation();
![Page 26: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/26.jpg)
Callback example
public class User extends Model{
public void beforeSave(){
set("password" encryptPassword());
}
private String encryptPassword(){
//do what it takes
return encrypted;
}
}
![Page 27: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/27.jpg)
Lazy/EagerActiveJDBC is lazy by default. If you need to load eager, use include():
List<User> users = User.findAll().orderBy("id") .include(Address.class);
Addresses are loaded eagerly.Include works for:• One to many children• One to many parents• Many to many
![Page 28: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/28.jpg)
Logging
Uses SFL4J – hookup a log system de jur By default will not log anything Will log everything at INFO level: java Dactivejdbc.log
com.acme.YourProgram
• Will log whatever matches regexp: Dactivejdbc.log=yourregexp● Can change matching expressionat run time
![Page 29: ActiveJDBC - ActiveRecord implementation in Java](https://reader033.vdocuments.mx/reader033/viewer/2022042512/557646c8d8b42ac31b8b4e56/html5/thumbnails/29.jpg)
Questions
?