源碼地址:https://github.com/braisdom/ObjectiveSql/tree/master/springboot_examplejava
ObjectiveSQL(簡稱: objsql,中文譯爲: 對象化SQL或者面向對象SQL)是一種ORM 技術在Java 中的應用,其主要思想爲ActiveRecord,使傳統應用程序開發中的VO,PO等變爲真正的Java Class,不只擁有相關狀態,同時也應有相關行爲。ObjectiveSQL 基於JSR 269,實現了數據庫訪問的動態代碼生成,而且在其中封裝了關係型數據庫的經常使用邏輯,使得應用程序開發變得極其簡單,因爲動態代碼生成,ObjectiveSQL 不依賴外部依賴注入型框架,能夠在任何環境下獨立運行。git
SpringBoot 是一種快速構造應用程序的框架,以動態代理(Dynamic Proxy)爲主,基於Java Annotation 進行應用系統擴展點,從而實現對基礎框架無感的形式進行系統開發。github
ObjectiveSQL 和SpringBoot 能夠無縫結合,相似於Rails 中的WEB 和ActiveRecord 開發同樣,具體代碼以下:web
1)安裝IntelliJ IDEA 插件:Preferences/Settings -> Plugins -> Search with "ObjectiveSql" in market -> Installspring
2)添加Maven 依賴:sql
<dependency> <groupId>com.github.braisdom</groupId> <artifactId>objective-sql</artifactId> <version>1.3.5</version> </dependency>
3)Controller 定義:數據庫
import com.github.braisdom.example.RequestObject; import com.github.braisdom.example.ResponseObject; import com.github.braisdom.example.model.Member; import com.github.braisdom.example.model.Order; import org.springframework.web.bind.annotation.*; import java.sql.SQLException; import java.util.List; @RestController public class MembersController { /** * The post body is in "resources/json/create_member.json" */ @PostMapping("/members") public ResponseObject create(@RequestBody RequestObject rawMember) throws SQLException { Member dirtyMember = Member.newInstanceFrom(rawMember, false); Member member = Member.create(dirtyMember, true); return ResponseObject.createSuccessResponse(member); } @GetMapping("/members/{no}") public ResponseObject getMember(@PathVariable("no") String memberNo) throws SQLException { Member member = Member.queryByNo(memberNo); return ResponseObject.createSuccessResponse(member); } @GetMapping("/members") public ResponseObject getMembers() throws SQLException { List<Member> members = Member.queryAll(); return ResponseObject.createSuccessResponse(members); } @GetMapping("/members/{no}/orders") public ResponseObject getMemberOrders(@PathVariable("no") String no) throws SQLException { Member member = Member.queryByNo(no, Member.HAS_MANY_ORDERS, Order.HAS_MANY_ORDER_LINES); return ResponseObject.createSuccessResponse(member); } @PutMapping("/members/{no}") public ResponseObject updateMember(@PathVariable("no") String memberNo, @RequestBody RequestObject rawMember) throws SQLException { Member member = Member.queryByNo(memberNo); Member.update(member.getId(), Member.newInstanceFrom(rawMember), true); return ResponseObject.createSuccessResponse(); } @DeleteMapping("/members/{no}") public ResponseObject deleteMember(@PathVariable("no") String memberNo) throws SQLException { int deleteCount = Member.destroy("member_no = ?"); return ResponseObject.createSuccessResponse(deleteCount); } }
4)Model 定義:json
import com.github.braisdom.objsql.annotations.Column; import com.github.braisdom.objsql.annotations.DomainModel; import com.github.braisdom.objsql.annotations.Queryable; import com.github.braisdom.objsql.annotations.Relation; import com.github.braisdom.objsql.relation.RelationType; import java.util.List; @DomainModel public class Member { @Queryable @Column(updatable = false) private String no; @Queryable private String name; private Integer gender; private String mobile; private String otherInfo; @Relation(relationType = RelationType.HAS_MANY) private List<Order> orders; }
能夠看到,簡單的DomainModel 無需定義任務方法,就要以實現對數據庫的INSERT, UPDATE, DELETE, SELETE 等操做,這些方法均由ObjectiveSQL 自動生成,咱們再來看一下Member.class 反編譯後的代碼:springboot
import com.github.braisdom.objsql.BeanModelDescriptor; import com.github.braisdom.objsql.Databases; import com.github.braisdom.objsql.Persistence; import com.github.braisdom.objsql.PersistenceFactory; import com.github.braisdom.objsql.Query; import com.github.braisdom.objsql.QueryFactory; import com.github.braisdom.objsql.Tables; import com.github.braisdom.objsql.Validator.Violation; import com.github.braisdom.objsql.annotations.Column; import com.github.braisdom.objsql.annotations.DomainModel; import com.github.braisdom.objsql.annotations.PrimaryKey; import com.github.braisdom.objsql.annotations.Relation; import com.github.braisdom.objsql.annotations.Transient; import com.github.braisdom.objsql.reflection.ClassUtils; import com.github.braisdom.objsql.reflection.PropertyUtils; import com.github.braisdom.objsql.relation.RelationType; import com.github.braisdom.objsql.relation.Relationship; import com.github.braisdom.objsql.sql.AbstractTable; import com.github.braisdom.objsql.sql.DefaultColumn; import com.github.braisdom.objsql.sql.Select; import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; @DomainModel public class Member { @Column( updatable = false ) private String no; private String name; private Integer gender; private String mobile; private String otherInfo; @Relation( relationType = RelationType.HAS_MANY ) private List<Order> orders; @PrimaryKey( name = "id" ) private Long id; public static final String TABLE_NAME = Tables.getTableName(Member.class); @Transient private final Map<String, Object> rawAttributes = new HashMap(); public static final Relationship HAS_MANY_ORDERS = Relationship.createRelation(Member.class, "orders"); public Member() { } public final Member setNo(String no) { this.no = no; return this; } public final String getNo() { return this.no; } public final Member setName(String name) { this.name = name; return this; } public final String getName() { return this.name; } public final Member setGender(Integer gender) { this.gender = gender; return this; } public final Integer getGender() { return this.gender; } public final Member setMobile(String mobile) { this.mobile = mobile; return this; } public final String getMobile() { return this.mobile; } public final Member setOtherInfo(String otherInfo) { this.otherInfo = otherInfo; return this; } public final String getOtherInfo() { return this.otherInfo; } public final Member setOrders(List<Order> orders) { this.orders = orders; return this; } public final List<Order> getOrders() { return this.orders; } public static final Member queryByPrimaryKey(Long primaryKey, Relationship... relationships) throws SQLException { Query<Member> query = createQuery(); query.where("id = ?", new Object[]{primaryKey}); return (Member)query.queryFirst(relationships); } public final Member setId(Long id) { this.id = id; return this; } public final Long getId() { return this.id; } public static final Query<Member> createQuery() { QueryFactory queryFactory = Databases.getQueryFactory(); return queryFactory.createQuery(Member.class); } public static final Select<Member> createSelect() { return new Select(asTable()); } public static final Persistence<Member> createPersistence() { PersistenceFactory persistenceFactory = Databases.getPersistenceFactory(); return persistenceFactory.createPersistence(Member.class); } public final Member save(boolean skipValidation, boolean skipPrimaryKeyOnInserting) throws SQLException { PersistenceFactory persistenceFactory = Databases.getPersistenceFactory(); Persistence<Member> persistence = persistenceFactory.createPersistence(new BeanModelDescriptor(Member.class, skipPrimaryKeyOnInserting)); return (Member)persistence.save(this, skipValidation); } public final Member save(boolean skipValidation) throws SQLException { return this.save(skipValidation, false); } public static final Member create(Member dirtyObject, boolean skipValidation, boolean skipPrimaryKeyOnInserting) throws SQLException { PersistenceFactory persistenceFactory = Databases.getPersistenceFactory(); Persistence<Member> persistence = persistenceFactory.createPersistence(new BeanModelDescriptor(Member.class, skipPrimaryKeyOnInserting)); return (Member)persistence.insert(dirtyObject, skipValidation); } public static final Member create(Member dirtyObject, boolean skipValidation) throws SQLException { return create(dirtyObject, skipValidation, false); } public static final int[] create(Member[] dirtyObjects, boolean skipValidation, boolean skipPrimaryKeyOnInserting) throws SQLException { PersistenceFactory persistenceFactory = Databases.getPersistenceFactory(); Persistence<Member> persistence = persistenceFactory.createPersistence(new BeanModelDescriptor(Member.class, skipPrimaryKeyOnInserting)); return persistence.insert(dirtyObjects, skipValidation); } public static final int[] create(Member[] dirtyObjects, boolean skipValidation) throws SQLException { return create(dirtyObjects, skipValidation, false); } public static final Member update(Long id, Member dirtyObject, boolean skipValidation) throws SQLException { Persistence<Member> persistence = createPersistence(); return (Member)persistence.update(id, dirtyObject, skipValidation); } public static final int update(String updates, String predicates) throws SQLException { Persistence<Member> persistence = createPersistence(); return persistence.update(updates, predicates); } public static final int destroy(Long id) throws SQLException { Persistence<Member> persistence = createPersistence(); return persistence.delete(id); } public static final int destroy(String predicate) throws SQLException { Persistence<Member> persistence = createPersistence(); return persistence.delete(predicate); } public static final int execute(String sql, Object... params) throws SQLException { return Tables.execute(Member.class, sql, params); } public static final List<Member> query(String predicate, Object... params) throws SQLException { Query<Member> query = createQuery(); query.where(predicate, params); return query.execute(new Relationship[0]); } public static final List<Member> query(String predicate, Relationship[] relations, Object... params) throws SQLException { Query<Member> query = createQuery(); query.where(predicate, params); return query.execute(relations); } public static final List<Member> queryBySql(String sql, Object... params) throws SQLException { return Tables.query(Member.class, sql, params); } public static final Member queryFirst(String predicate, Relationship[] relations, Object... params) throws SQLException { Query<Member> query = createQuery(); query.where(predicate, params); return (Member)query.queryFirst(relations); } public static final Member queryFirst(String predicate, Object... params) throws SQLException { Query<Member> query = createQuery(); query.where(predicate, params); return (Member)query.queryFirst(new Relationship[0]); } public static final List<Member> queryAll(Relationship... relations) throws SQLException { Query<Member> query = createQuery(); query.where("", new Object[0]); return query.execute(relations); } public static final long count(String predicate, Object... params) throws SQLException { return Tables.count(Member.class, predicate, params); } public static final long countAll() throws SQLException { return Tables.count(Member.class, "", new Object[0]); } public final Violation[] validate() { return Tables.validate(this); } public static final Member newInstanceFrom(Map properties, boolean underLine) { Member bean = (Member)ClassUtils.createNewInstance(Member.class); PropertyUtils.populate(bean, properties, underLine); return bean; } public static final Member newInstanceFrom(Map properties) { return newInstanceFrom(properties, false); } public final Object getRawAttribute(String name) { return this.rawAttributes.get(name); } public final void setRawAttribute(String name, Object value) { this.rawAttributes.put(name, value); } public final Map<String, Object> getRawAttributes() { return this.rawAttributes; } public static final Member.Table asTable() { return new Member.Table(); } public static final Member queryByNo(String value, Relationship... relations) throws SQLException { Query<Member> query = createQuery(); String columnName = Tables.getColumnName(Member.class, "no"); query.where(String.format("%s = ?", "no"), new Object[]{value}); return (Member)query.queryFirst(relations); } public static final Member queryByName(String value, Relationship... relations) throws SQLException { Query<Member> query = createQuery(); String columnName = Tables.getColumnName(Member.class, "name"); query.where(String.format("%s = ?", "name"), new Object[]{value}); return (Member)query.queryFirst(relations); } public static final class Table extends AbstractTable { public final com.github.braisdom.objsql.sql.Column no; public final com.github.braisdom.objsql.sql.Column name; public final com.github.braisdom.objsql.sql.Column gender; public final com.github.braisdom.objsql.sql.Column mobile; public final com.github.braisdom.objsql.sql.Column otherInfo; public final com.github.braisdom.objsql.sql.Column orders; public final com.github.braisdom.objsql.sql.Column id; public final com.github.braisdom.objsql.sql.Column rawAttributes; private Table() { super(Member.class); this.no = DefaultColumn.create(Member.class, this, "no"); this.name = DefaultColumn.create(Member.class, this, "name"); this.gender = DefaultColumn.create(Member.class, this, "gender"); this.mobile = DefaultColumn.create(Member.class, this, "mobile"); this.otherInfo = DefaultColumn.create(Member.class, this, "otherInfo"); this.orders = DefaultColumn.create(Member.class, this, "orders"); this.id = DefaultColumn.create(Member.class, this, "id"); this.rawAttributes = DefaultColumn.create(Member.class, this, "rawAttributes"); } } }