Ebean Demo
ebean orm框架,其作者觉得hibernate的bean管理会话管理。难以在短时间明确,就自己搞了一套,就成了如今的ebean。
ebean被一些开发人员这觉得是一把瑞士军刀。能够看出一些程序猿对ebean的高度评价。以下是一些ebean的特点总结
1.简单易于学习和使用(简化hibernate,仅仅有一个jar包)
2.使用标准的JPA annotation,即: @@OneToMany等。
3.提供Sessionless API,也就是说没有merge,flush等方法。(这也是Ebean与Hibernatet等ORM的重要差别之中的一个);
4.通过Autofetch*进行自己主动查询调优。支持级联保存和删除。
5.链式查询语言
6.L1、L2 缓存
7.集成Lucene文本搜索。
以下是一段使用ebean的代码例子
package models;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.annotation.Formula;
import com.avaje.ebean.annotation.Transactional;
import com.avaje.ebean.cache.ServerCacheManager;
import play.data.validation.Constraints;
import play.db.ebean.Model;
import util.Util;
import javax.persistence.*;
import java.util.List;
/**
* Created by wangjun on 14-3-26.
*/
@Entity // ebean 所用的注解是jpa
//@Table(name = "user")
public class User extends Model {
@Id //@EmbeddedId 复杂id
public Long id; //默认命名约定:first_name maps to firstName
@Constraints.Required
public String username;
//@Column(name = "password")
public String password;
@ManyToOne(cascade = CascadeType.ALL)
//会载入address_id ,但不会载入整个address,这个和hibernate有差别。Ebean的延迟载入对于性能的影响不打,默认EAGER。最好打开
public Address address; //出身地
/*@OneToOne
public User mate;//配偶*/
/* @OneToMany(cascade = CascadeType.PERSIST)
public List<Address> addresses;//曾居住地 会在address端要求user_id 字段。能够用?ManyToMany取代*/
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.DETACH)
//cascade = CascadeType.ALL 级联情况下会自己主动插入car个中间表数据,默认不级联 。对于一些级联更新非常是有必要
public List<Car> cars;
@Formula(select = "(select count(*) from user_car c where c.user_id = ${ta}.id )")
// 计算拥有车的数量 ${ta} 代表表的别名 ,还能够写join
public int carSize;
//@Transient
//会满足上述条件后在调用此方法,全局验证
public String validate() {
if (username.equals("1")) {
return "Invalid email or password";
}
return null;
}
/* public List<ValidationError> validate() {
if ( username.equals("1")) {
return null;
}
return null;
}
public Map<ValidationError> validate() {
if ( username.equals("1")) {
return null;
}
return null;
}*/
public static Model.Finder<Long, User> find = new Model.Finder(Long.class, User.class);
//============自己主动抓取測试==start=================
public static User findById(Long id) {
User user = find.byId(id); //不抓取car,LAZY不select address_id
return user;
}
public static User findById(Long id, int loadType) {
User user = find.byId(id); //不抓取car,不抓取address
String name = null;
int size = 0;
if (loadType == 1)
name = user.address.province; //每次都会载入user
else if (loadType == 2)
size = user.cars.size(); //每次都会载入car
Util.report(name);
Util.report(size + "");
return user;
}
//连表查询測试
public static User findByIdLoadAddress(Long id) {
return find.fetch("address").fetch("cars").where().eq("id", id).findUnique(); // fetch= 生成join查询 不用fetch延迟载入,且不会生成join查询;
}
/**
* *
* TxType Descriptions
* TxType Description
* REQUIRED Runs in a Transaction. Will use an existing transaction if it exists, otherwise will create a new Transaction.
* REQUIRES_NEW Runs in a new Transaction. If a current transaction exists it will be suspended.
* MANDATORY Runs in the existing Transaction. If there is no current existing transaction an exception is thrown.
* SUPPORTS Use a transaction if it already exists. If it does not then the method runs without a transaction.
* NOT_SUPPORTS Always runs without a transaction. If one already exists then it is suspended.
* NEVER Always runs without a transaction. If one already exists then it throws an exception.
*
* @param type
*/
@Transactional// 打开事务。或通过beginTr.... endTr.. 或TxRunnable
public void saveUser(int type) {
Util.report("=============saveUser==start===============================");
if (type == 0) { //不级联情况保存
this.address.save(); // 保存用户前将用户输入的出生地也保存到数据库
this.save(); // 保存用户数据
this.saveManyToManyAssociations("cars"); //保存中间表
} else if (type == 1) { //假设设置级联car
this.save(); // 会级联插入car和中间表数据
}
Util.report("===============saveUser===end============================");
}
public void deleteUser(Long id) {
Ebean.delete(User.class, id);
}
/**
* *********************other test*********************
* public void updateUser() {
* this.update();
* }
* <p/>
* //批量操作
* public void deleteUser(List<User> users) {
* Ebean.delete(users);//批量删除
* Ebean.save(users);//批量保存
* }
* <p/>
* public void deleteUser() {
* this.delete();
* }
* ***************
*/
//L1 測试 事务级缓存或持久化上下文缓存
public static User find() {
Ebean.beginTransaction();
Car car1 = Car.find.byId(Long.valueOf(7));
Car car2 = Car.find.byId(Long.valueOf(8));
User user = User.findById(Long.valueOf(45));
if (user.cars.get(0).id == 7) { // 查到的car实例属于同一个实例
Util.report((user.cars.get(0) == car1) + "");
} else if (user.cars.get(0).id == 8) {
Util.report((user.cars.get(0) == car2) + "");
}
Ebean.endTransaction();
return user;
}
//L2 測试 bean cache and query cache
public static Address findAddress() {//手动指定使用缓存。同一时候设置为仅仅读。能够在model使用注解指定缓存策略。假设有改动缓存的bean,会自己主动维持缓存
Address address_ = Ebean.find(Address.class).setUseCache(true).setReadOnly(true).setId(56).findUnique();
List<Address> addressList = Ebean.find(Address.class).setUseQueryCache(true).setReadOnly(true).findList();
Util.report(addressList.size() + "");
return address_;
}
// 測试 不用cache 查询10000次
public static Car findCar() {
Car car = null;
for (int i = 0; i < 100000; i++) {
Car car_ = Ebean.find(Car.class, 1);
Util.report((car == car_) + "");
car = car_;
}
return car;
}
// 測试 不用cache 查询10000次
public static Car findCar2() {
Car car = null;
for (int i = 0; i < 10000; i++) { // 仅仅查1次
Car car_ = Ebean.getReference(Car.class, 1); // getReference 仅仅会载入创建存在id属性的bean。不会查询数据库。当得到这个bean,用id外的其他属性就会引发查询
Util.report((car == car_) + "");
car = car_;
}
return car;
}
//L1 測试 查询10000次
public static Address findAddressInL1() { // 仅仅查1次
// Address address_ = Ebean.find(Address.class, "56");
Address address = null;
Ebean.beginTransaction();
for (int i = 0; i < 10000; i++) {
Address address_ = Ebean.find(Address.class, 56);
Util.report((address == address_) + "");
address = address_;
}
Ebean.endTransaction();
return address;
}
//L2 測试 查询10000次
public static Address findAddressInL2() {
Address address = null;
for (int i = 0; i < 10000; i++) { // 查了数据库
Address address_ = Ebean.find(Address.class, 56);
// Address address_ = Ebean.find(Address.class).setUseCache(true).setReadOnly(true).setId(56).findUnique();
Util.report((address == address_) + "");
address = address_;
}
return address;
}
//L2 測试 查询10000次
public static Address findAddressInL22() {
Address address = null;
for (int i = 0; i < 10000; i++) { // 測试查了数据库
// Address address_ = Ebean.getReference(Address.class,56);
Address address_ = Ebean.find(Address.class).setUseCache(true).setReadOnly(true).setId(56).findUnique();
Util.report((address == address_) + "");
address = address_;
}
return address;
}
//L2 測试 抓取Address10000次 当第一次查询的时候会查询address,之后会从缓存取
public static Address findAddressInL222() {
Address address = null;
for (int i = 0; i < 10000; i++) { // 測试查了数据库
User user = User.findById(Long.valueOf(41));
Address address_ = user.address; // 数据从缓存内得到
Util.report((address == address_) + (address == null ?
null : address.province));
address = address_;
}
return address;
}
/**
* **
* Handling External Modification (
* via stored procedures etc
* )
* When you save/delete beans via Ebean.save() and Ebean.delete() etc Ebean will
* automatically maintain its cache (removing cached beans and cached queries as
* appropriate). However, you may often find yourself modifying the database outside of
* Ebean.
* For example, you could be using other frameworks, your own JDBC code, stored
* procedures, batch systems etc. When you do so (and you are using Ebean caching) then
* you can inform Ebean so that it invalidates appropriate parts of its cache.
*/
public void test() {
boolean inserts = true;
boolean updates = true;
boolean deletes = false;
// inform Ebean that some rows have been inserted and updated on address table Ebean will maintain the appropriate caches.
Ebean.externalModification("address", inserts, updates, deletes);
// clearAll() caches via the ServerCacheManager ...
ServerCacheManager serverCacheManager = Ebean.getServerCacheManager();
// Clear all the caches on the default/primary EbeanServer
serverCacheManager.clearAll();
// clear both the bean and query cache for Country beans ...
serverCacheManager.clear(Address.class);
// Warm the cache of Country beans
Ebean.runCacheWarming(Address.class);
}
@Override
public String toString() {
String result = "";
if (address == null)
result.concat("address:null");
else
result.concat("address:").concat(address.province).concat("-").concat(address.town);
return result;
}
}
Ebean Demo的更多相关文章
- 通过一个demo了解Redux
TodoList小demo 效果展示 项目地址 (单向)数据流 数据流是我们的行为与响应的抽象:使用数据流能帮我们明确了行为对应的响应,这和react的状态可预测的思想是不谋而合的. 常见的数据流框架 ...
- 很多人很想知道怎么扫一扫二维码就能打开网站,就能添加联系人,就能链接wifi,今天说下这些格式,明天做个demo
有些功能部分手机不能使用,网站,通讯录,wifi基本上每个手机都可以使用. 在看之前你可以扫一扫下面几个二维码先看看效果: 1.二维码生成 网址 (URL) 包含网址的 二维码生成 是大家平时最常接触 ...
- 在线浏览PDF之PDF.JS (附demo)
平台之大势何人能挡? 带着你的Net飞奔吧!:http://www.cnblogs.com/dunitian/p/4822808.html#skill 下载地址:http://mozilla.gith ...
- 【微框架】Maven +SpringBoot 集成 阿里大鱼 短信接口详解与Demo
Maven+springboot+阿里大于短信验证服务 纠结点:Maven库没有sdk,需要解决 Maven打包找不到相关类,需要解决 ps:最近好久没有写点东西了,项目太紧,今天来一篇 一.本文简介 ...
- vue双向数据绑定原理探究(附demo)
昨天被导师叫去研究了一下vue的双向数据绑定原理...本来以为原理的东西都非常高深,没想到vue的双向绑定真的很好理解啊...自己动手写了一个. 传送门 双向绑定的思想 双向数据绑定的思想就是数据层与 ...
- Android Studio-—使用OpenCV的配置方法和demo以及开发过程中遇到的问题解决
前提: 1.安装Android Studio(过程略) 2.官网下载OpenCV for Android 网址:http:opencv.org/downloads.html 我下载的是下图的版本 3. ...
- iOS之ProtocolBuffer搭建和示例demo
这次搭建iOS的ProtocolBuffer编译器和把*.proto源文件编译成*.pbobjc.h 和 *.pbobjc.m文件时,碰到不少问题! 搭建pb编译器到时没有什么问题,只是在把*.pro ...
- 钉钉开放平台demo调试异常问题解决:hostname in certificate didn't match
今天研究钉钉的开放平台,结果一个demo整了半天,这帮助系统写的也很难懂.遇到两个问题: 1.首先是执行demo时报unable to find valid certification path to ...
- 无限分级和tree结构数据增删改【提供Demo下载】
无限分级 很多时候我们不确定等级关系的层级,这个时候就需要用到无限分级了. 说到无限分级,又要扯到递归调用了.(据说频繁递归是很耗性能的),在此我们需要先设计好表机构,用来存储无限分级的数据.当然,以 ...
随机推荐
- 什么是马甲APP?怎么用马甲APP导流
一.什么是马甲APP? 马甲APP指的是为了让认识你的人猜不到,在常用的用户名外再注册的其他名字的APP. 二.马甲APP与真实APP的区别是什么?相同的地方是什么? 1.应用名称不一样. 2.关键词 ...
- JDBC 基础知识总结
1. 何谓JDBC --- Java Database Connectivity. 由Sun 公司提供的访问数据库的一组java类和接口,用来对数据库进行链接.发送SQL语句.处理返回结果,为开发 ...
- redis入门教程
21) Redis 简介Redis 是一个开源的使用 ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value 数据库.2) 数据类型2.1. Redis 的 KeyRedi ...
- spoj VFMUL FFT快速傅立叶变换模板题
题意:求两个数相乘. 第一次写非递归的fft,因为一个数组开小了调了两天TAT. #include<iostream> #include<cstring> #include&l ...
- ArrayList与Vector、HashMap与HashTable
摘自api: 1.ArrayList与Vector: 原文:This class(ArrayList) is roughly equivalent to Vector, except that it ...
- 【LA 5713 】 Qin Shi Huang's National Road System (MST)
[题意] 秦始皇要在n个城市之间修路,而徐福声可以用法术位秦始皇免费修1条路,每个城市还有人口数,现要求徐福声所修之路的两城市的人口数之和A尽量大,而使n个城市互通需要修的路长B尽量短,从而使得A/B ...
- JavaScript String支持的辅助format函数+【分页1】
/** ) { && ; i < arguments.length; i++) { : int.Parse(Request.Par ...
- hadoop2.2编程:DFS API 操作
1. Reading data from a hadoop URL 说明:想要让java从hadoop的dfs里读取数据,则java 必须能够识别hadoop hdfs URL schema, 因此我 ...
- SharePoint 2010 母版页制作的简单介绍
转:http://www.cnblogs.com/jianyus/archive/2012/01/11/2319621.html 1. 首先打开SharePoint Designer 2010,找到 ...
- linux .o,.a,.so文件解析
linux下文件的类型是不依赖于其后缀名的,但一般来讲:.o,是目标文件,相当于windows中的.obj文件.so 为共享库,是shared object,用于动态连接的,和dll差不多.a为静态库 ...