【ActiveJdbc】03
一、查詢API
簡單條件篩選:
List<Person> list = Person.where("name = 'John'")
動態引數條件:
List<Person> list = Person.where("name = ?", "John");
處理大型結果集:
在之前的所有結果中,整個結果集都被載入到記憶體中。
這種方法在結果相對較小的情況下很好,但對於非常大的資料集可能會成為效能瓶頸。
下面的方法有點讓人想起 SAX 方法,從資料庫中讀取超大資料集,對於找到的每一條記錄,它都會產生一個回撥。
在該回調中,您可以執行對應用程式有意義的任何操作。
這種方法的優點是不需要分配大量記憶體。
這通常是批處理的首選方法。將此視為來自資料庫的資料流。
Person.find("name='John'", new ModelListener<Person>() { public void onModel(Person person) { System.out.println("Found person: " + person); } });
只查詢一條記錄
使用findFirst
方法可以只找到一條記錄。
顧名思義,即使查詢可以產生多條記錄,也只會返回第一條記錄。
Person person = Person.findFirst("id = 2");//parametrized: person = Person.findFirst("id = ?", 2); ...
查詢所有記錄
這是一個方法或從表中返回所有記錄,請小心使用,因為這會將它們全部載入到記憶體中(當您開始處理結果時,而不是在呼叫此方法時)
List<Person> list = Person.findAll(); for(Person p: list){ //<==== this line of code will initiate the actual query to DB System.out.println(p); }
Active的記錄插入
有許多(更簡潔的)模型建立方法,這是最簡單和不言自明的:
這個記錄插入之後,是會返回主鍵ID的,可以留作聯調的操作業務
Person p = new Person(); p.set("first_name", "Marilyn"); p.set("last_name", "Monroe"); p.set("dob", "1935-12-06"); p.saveIt(); System.out.println(p.getId());// <== this will print an ID assigned by DB.
查詢該表總記錄數:
long personCount = Person.count();
待條件總記錄:
計算一些記錄同樣容易,您所要做的就是提供標準。
long johnCount = Person.count("name = ? ", "John");
原始SQL
如果查詢真的很複雜,你總是可以像這樣使用原始 SQL:
作者沒有提供太多的條件封裝,一般寫業務都是使用這個方法
高度自定義,還是寫原始SQL實現資料層
List<Book> books = Book.findBySQL("select books.*, address from books, libraries where books.lib_id = libraries.id order by address");
二、分頁&排序
1、限制結果
在取景器
的方法,如find()
,findAll()
和where()
返回的一個例項LazyList
。
這個類有一個方法叫做limit(int)
.當您的程式開始時,它將限制結果集中的許多結果:
List<Person> people = People.findAll().limit(20);
2、偏移量
獲得第一頁後,您可能想要獲得下一頁。
這是通過 offset 方法完成的,在同一個LazyList
類中找到,如下所示:
List<Person> people = People.findAll().limit(40).offset(20);
3、排序
通常,您會在一個語句中限制、抵消和排序結果:
List<Person> people = People.findAll().limit(40).offset(20).orderBy("age asc");
有時這種程式設計風格被稱為Fluent Interfaces並歸功於 Martin Fowler。這種 API 風格簡潔、易讀且不言自明。
4、翻頁
儘管limit
,offset
和orderBy
它們本身都是非常簡單和強大的方法,
但 ActiveJDBC 還提供了一個方便的類,稱為Paginator
專為 Web 應用程式設計的:
Paginator p = new Paginator(Page.class, 10, "description like ?", "%Java%").orderBy("created_at desc"); List<Page> items = p.getPage(1); List<Page> items = p.getPage(2);
此類的例項是輕量級的,通常附加到會話中。可以查詢當前顯示的頁面:
int currentPage = paginator.getCurrentPage();
對於這樣的頁數:
int pageCount = paginator.pageCount();
在 Web 應用程式的上下文中使用這個類可以很容易地通過結果集構建分頁。
三、常用範圍
很多時候,開發人員對同一個表使用相同的過濾器來按一列或多列對記錄進行分類,例如獲取營銷部門的成員:
如果你發現自己一遍又一遍地做同樣的事情,你可以把它抽象成一個範圍:
public class Employee extends Model { static { addScope("marketing", "department = 'marketing'"); } }
之後,只需指出您需要的範圍:
List<Employee> marketers = Employee.scope("marketing").all();
組合範圍
您可以在同一請求中組合多個範圍。如果您在模型上定義了多個範圍:
public class Employee extends Model { static { addScope("marketing", "department = 'marketing'"); addScope("active", "active = 1"); } }
然後你可以組合這些範圍:
List<Employee> activeMarketers = Employee.scopes("marketing", "active").all();
追加條件:
可以where()
像往常一樣使用該方法進一步過濾:
List<Employee> activeMarketers = Employee.scopes("marketing", "active").where("position_level = ?", level).orderBy("created_at desc");
所有正常的機制和行為仍然存在。
範圍允許抽象出平凡的請求並使程式碼更具可讀性。
四、為欄位自動賦值
ActiveJdbc會自動為這兩個欄位進行自動賦值:
created_at & updated_at
五、批量操作:
全表更新:
Person.updateAll("last_name = ?", "Smith");
條件更新:
Person.update("name = ?, last_name = ?", "name like ?", "Steve", "Johnson", "%J%");
表記錄全刪:
Person.deleteAll();
條件刪除:
Person.delete("age > ?", "10");
六、執行策略(惰性 &激進)
作者對執行策略預設是使用惰性的
惰性的意思就是,只有我們呼叫結果集的內容的時候,才會真的去訪問資料庫查詢
List<User> users = User.findAll(); // or User.where(".. query here"); for(User u: users){ System.out.println(u); }
上面這段案例,第一段查詢所有給users
這個時候users是空的,因為users沒有用來做任何事情
到下面執行Foreach的時候,users呼叫了,這才觸發惰性載入,activeJdbc採取訪問資料庫拿資料過來
如果要保證集合中有資料,也就是必須讓activeJdbc去訪問資料庫,把資料帶過來
作者的建議是必須呼叫結果
文件後面是對關聯關係的執行策略描述,工作方面反而不設定這種關聯關係,需要維護成本
七、型別轉換&值轉換:
檢視型別?
Person p = Person.findAll().get(0);
System.out.println("DOB type: " + p.get("dob").getClass());
一般返回的是Object,專案裡面是手動強轉或者toString
設定日期格式化轉換:
日期轉換器
日期轉換器可以在格式化字串和 java.sql.Date 之間進行轉換。這是一個將日期轉換器註冊到dob
屬性的示例:
public class Person extends Model { static { dateFormat("MM/dd/yyyy", "dob"); } }
以及如何使用它們:
Person p = new Person(); // will convert String to java.sql.Date p.setDate("dob", "06/23/1912"); // will convert Date to String, if dob value in model is of type Date String str = p.getString("dob"); // will convert Date to String p.setString("dob", new Date()); // will convert String to java.sql.Date, if dob value in model is of type String Date date = p.getDate("dob");
時間戳轉換:
時間戳轉換器與日期轉換器相同,但可以在 java.sql.Timestamp 之間進行轉換。下面是一個宣告的例子:
public class Message extends Model { static{ timestampFormat("yyyy.MM.dd G 'at' HH:mm:ss z", "send_time"); } }
空白到零轉換器
空白到空轉換器將任何java.lang.String
空值或僅包含空格的值轉換為空值。
它適用於任何 getter 或 setter。這是一個將其註冊到兩個屬性的示例:
public class Person extends Model { static { blankToNull("name", "last_name"); } }
零到零轉換器
零到空轉換器用作空白到空轉換器,但將java.lang.Number
等於零的值轉換為空。以下是宣告示例:
public class Salary extends Model { static { zeroToNull("bonus"); } }
八、JSON化
https://javalite.io/generation_of_json
轉XML處理上次WSDL弄過類似的,之後就沒寫過了
轉JSON用的場景就很多了,前後端互動,JsonDoc型別儲存
https://javalite.io/json