Ebean Demo

1.简单易于学习和使用(简化hibernate,只有一个jar包)

2.使用标准的JPA annotation,即: @@OneToMany等;

3.提供Sessionless API,也就是说没有merge,flush等方法。(这也是Ebean与Hibernatet等ORM的重要区别之一);

4.通过Autofetch*进行自动查询调优;支持级联保存和删除。

5.链式查询语言

6.L1、L2 缓存

7.集成Lucene文本搜索。

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,布布扣,bubuko.com

时间: 2024-08-06 16:06:26

Ebean Demo的相关文章

微信h5支付demo微信H5支付demo非微信浏览器支付demo微信wap支付

一.首先先确定H5支付权限已经申请!(需要微信h5支付demo的可以加 851 488 243 备注:h5支付) 二.开发流程 1.用户在商户侧完成下单,使用微信支付进行支付 2.由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB 3.统一下单接口返回支付相关参数给商户后台,如支付跳转url(参数名"mweb_url"),商户通过mweb_url调起微信支付中间页 4.中间页进行H5权限的校验,安全性检查(此处常见错误请见下文) 5.如支付成

Maven+SpringMVC+Freemarker入门Demo

1 参考http://blog.csdn.net/haishu_zheng/article/details/51490299,用第二种方法创建一个名为mavenspringmvcfreemarker的Maven工程. 2 文件目录结构如下图所示 3 在pom.xml中添加springmvc和freemarker的依赖包,添加完之后的完整内容为 [html] view plain copy <project xmlns="http://maven.apache.org/POM/4.0.0&q

Spring Security入门Demo

一.spring Security简介 SpringSecurity,这是一种基于Spring AOP和Servlet过滤器的安全框架.它提供全面的安全性解决方案,同时在Web请求级和方法调用级处理身份确认和授权.在Spring Framework基础上,Spring Security充分利用了依赖注入(DI,Dependency Injection)和面向切面技术. 二.建立工程 参考http://blog.csdn.net/haishu_zheng/article/details/51490

沫沫金Echarts移动端demo

鄙视百度!!! 官网给的Demo支持自动大小,确不给完整的源码XXX 自己动手,丰衣足食 http://echarts.baidu.com/demo.html#bar-tick-align 用最基本的柱状图官网代码 简单两步,实现移动端自适应大小 //1.下载Echarts <script src="dep/Echarts/echarts-all-3.js"></script> //2.chart容器宽度自适应 <!-- 为ECharts准备一个具备大小(

Flask---使用Bootstrap新建第一个demo

Flask---使用Bootstrap新建第一个demo 参考自http://www.jianshu.com/p/417bcbad82fb 还有<Flask web开发> 前端用到Bootstrap开源框架,Bootstrap是客户端框架,后台当然就是Flask了. 服务器需要做的只是提供引用了Bootstrap层叠样式表(CSS)和JS文件的html响应,并且在html.css和js代码中实例化需要的组件,这些操作的最理想的执行环境就是模板 关于模板的介绍及其实现原理:https://kb.

struts2和hibernate整合的小Demo

jar包下载地址 创建一个web项目. 导入jar包 配置web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="

移动端上传照片 预览+draw on Canvas demo(解决iOS等设备照片旋转90度的bug)

背景: 本人的一个移动端H5项目,需求如下: 手机相册选取或拍摄照片后在页面上预览 然后绘制在canvas画布上. 这里,我们先看一个demo(http://jsfiddle.net/q3011893/83qfqpk8/embedded/) 操作步骤: 1.点击选择文件,拍摄一张照片,此时"预览:"文字下会显示你刚才拍摄的照片: 2.再点击"draw on Canvas",该按钮下的画布会绘制你刚才拍摄的照片. 正常的结果: 正文: 让input file支持拍照+

爬虫2:html页面+beautifulsoap模块+post方式+demo

爬取html页面,有时需要设置参数post方式请求,生成json,保存文件中. 1)引入模块 import requests from bs4 import BeautifulSoup url_ = 'http://www.c.....................' 2)设置参数 datas = { 'yyyy':'2014', 'mm':'-12-31', 'cwzb':"incomestatements", 'button2':"%CC%E1%BD%BB",

Nancy之基于Self Hosting的补充小Demo

前面把Hosting Nancy with ASP.NET.Self Hosting Nancy和Hosting Nancy with OWIN 以demo的形式简单描述了一下. 这篇是为Self Hosting Nancy.和Owin 下面的Self Hosting作个补充. 首先是Self Hosting Nancy的补充: 这里主要是介绍一下Topshelf 官网:http://topshelf-project.com/ GitHub地址:https://github.com/Topshe