使用JPAContainer开发Vaadin应用
Vaadin JPAContainer是Vaadin的一个数据组件,使用JPA检索和存储数据。提供了许多JavaEE应用系统开箱即用的特性,像延迟加载、高级过滤器、嵌套的属性名称和缓存等。虽然没有解决开发JavaEE应用面临的所有问题,但是可以让JavaEE应用的开发稍微容易一些。
JPAContainer不需要特定的JPA实现和特定的数据库。它生成的标准JPA-QL查询可以在任何JPA实现中正确执行。但是只是在Hibernate和EclipseLink下做过测试。
首先介绍在Eclipse下开发JPA应用的步骤,然后介绍使用JPAContainer构建Vaadin应用。
1、 在Eclipse下安装vaadin插件
2、 在Eclipse下建立JPA项目
(1)名称:jpavaadin
(2)选择tomcat6.0作为目标运行环境
(3)选择jpa2.0
(4)Configuration选择vaadin java 6 servlet2.4
(5)选择hibernate作为持久化框架
(6)建立数据库连接:jpavaadinmysql,并选择之
(7)勾选将jdbc驱动程序加入build path
(8)设置项目的包:cn.com.dareway.jpavaadin
(9)vaadin版本目前是6.6.4
3、 在生成的目录结构中,选择persistence.xml文件,并打开。
(1)在connection页中,transactiontype选择resource local
(2)选择populate from connection,选择前面定义的数据库连接japvaadinmysql,此时persistence.xml的内容如下:
<?xml version="1.0"encoding="UTF-8"?>
<persistence version="2.0"xmlns="http://java.sun.com/xml/ns/persistence"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/persistencehttp://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="jpavaadin"transaction-type="RESOURCE_LOCAL">
<properties>
<property name="javax.persistence.jdbc.url"value="jdbc:mysql://localhost:3306/agilewide"/>
<property name="javax.persistence.jdbc.user"value="xzs"/>
<property name="javax.persistence.jdbc.password"value="xzsxzs"/>
<property name="javax.persistence.jdbc.driver"value="com.mysql.jdbc.Driver"/>
</properties>
</persistence-unit>
</persistence>
(3)在属性中增加下述属性设置:
<property name="hibernate.show_sql"value="false"/>
<property name="hibernate.format_sql"value="false"/>
<property name="hibernate.dialect"value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.hbm2ddl.auto"value="create"/>
其中:
hibernate.hbm2ddl.auto可以是validate| update | create | create-drop
validate 加载hibernate时,验证创建数据库表结构 create 每次加载hibernate,重新创建数据库表结构 create-drop 加载hibernate时创建,退出是删除表结构 update 加载hibernate自动更新数据库结构
在生产环境中应该:
<property name="hibernate.hbm2ddl.auto"value="none"/>
4、 在src下建立实体包:cn.com.dareway.jpavaadin.entity
5、 在实体包下建立实体定义Person
package cn.com.dareway.jpavaadin.entity;
import java.io.Serializable;
import java.lang.Integer;
import java.lang.String;
import javax.persistence.*;
/**
* Entity implementation class for Entity:Person
*
*/
@Entity
public class Person implements Serializable {
@Id
@GeneratedValue
private Integer id;
private String name;
private Integer age;
private staticfinal longserialVersionUID = 1L;
public Person() {
super();
}
public Integer getId() {
return this.id;
}
public voidsetId(Integer id) {
this.id =id;
}
public String getName() {
return this.name;
}
public voidsetName(String name) {
this.name =name;
}
public Integer getAge() {
return this.age;
}
public voidsetAge(Integer age) {
this.age =age;
}
}
其中id字段加上@GeneratedValue注解,表示自动生成值。
6、 建立实体管理工厂和实体管理器
private EntityManagerFactory emf;
private EntityManager em;
emf = Persistence.createEntityManagerFactory("jpavaadin");
em = emf.createEntityManager();
其中:japvaadin是在persistence.xml 中定义的持久化单元。
7、 操纵实体持久化
Personp1 = new Person();
p1.setName("xzs");
p1.setAge(10);
em.getTransaction().begin();
em.persist(p1);
em.getTransaction().commit();
final List<Person> list = em.createQuery("selectp from Person p")
.getResultList();
for (Person current : list) {
final String name = current.getName();
mainWindow.addComponent(new Label(name));
}
8、 把hibernate 发行包中的必须库文件复制到WEB-INF/lib下。
antlr-2.7.6.jar
commons-collections-3.1.jar
dom4j-1.6.1.jar
javassist-3.12.0.GA.jar
jta-1.1.jar
slf4j-api-1.6.1.jar
9、 复制mysql的jdbc驱动程序到WEB-INF/lib下。
10、复制slf4j的slf4j-nop-1.6.1.jar到WEB-INF/lib下。
11、运行程序
12、发现在mysql数据库中中文存在乱码,对persistence.xml进行修改:
<propertyname="javax.persistence.jdbc.url"value="jdbc:mysql://localhost:3306/agilewide?useUnicode=true&characterEncoding=UTF-8"/>
url中增加?useUnicode=true&characterEncoding=UTF-8
注意其中的&用&amp;代替。
到目前为止,只是使用JPA访问代码,直接操纵数据库中的数据。下面使用Vaadin的Add-ons,即vaadin的扩展数据组件:JPAContainer来操纵数据库。
13、构建EntityProvider
MutableLocalEntityProvider<Person>myEntityProvider = new MutableLocalEntityProvider<Person>(Person.class,em);
14、构建EntityContainer
finalEntityContainer<Person> container = newJPAContainer<Person>(Person.class);
15、建立container与provider之间的关联
container.setEntityProvider(myEntityProvider);
16、让container处于自动提交状态,对container中数据的改变立即提交到数据库中
container.setAutoCommit(true);
17、将container与table组件关联,在table中显示container中的数据
final Table tab = new Table();
tab.setContainerDataSource(container);
tab.setSelectable(true);
tab.setImmediate(true);
18、增加一行数据
Person p = new Person();
p.setName("1234");
EntityItem<Person> myNewItem =container.createEntityItem(p);
// Do something with the item, e.g. open amodal dialog
Object id =container.addEntity(myNewItem.getEntity());
19、删除table中选中的行
if (tab.getValue() != null) {
container.removeItem(tab.getValue());
} else {
mainWindow.showNotification("请选中一行");
}
20、使用Form编辑table中选中的行
final Form personEditor = new Form();
personEditor.setSizeFull();
personEditor.getLayout().setMargin(true);
personEditor.setImmediate(true);
personEditor.setVisible(false);
下述代码在table的valueChange事件中:
if (tab.getValue() != null){
personEditor.setItemDataSource(tab.getItem(tab.getValue()));
personEditor.setVisibleItemProperties(new String[]{"name","age"});
} else{
personEditor.setItemDataSource(null);
}
personEditor.setVisible(personEditor.getItemDataSource()!= null);
21、设置table的可见栏目
tab.setVisibleColumns(newString[] {"name", "age"});
22、设置table的栏目头
tab.setColumnHeaders(newString[]{"姓名","年龄"});
23、设置Form的可见字段
personEditor.setVisibleItemProperties(newString[]{"name","age"});
下面介绍使用c3p0数据库连接池。
24、修改persistence.xml文件,增加以下属性:
<!-- 使用c3p0数据库连接池 -->
<property name="hibernate.connection.provider_class"
value="org.hibernate.connection.C3P0ConnectionProvider"/>
<property name="hibernate.c3p0.max_size" value="100" />
<property name="hibernate.c3p0.min_size" value="0" />
<property name="hibernate.c3p0.acquire_increment" value="1" />
<property name="hibernate.c3p0.idle_test_period" value="300" />
<property name="hibernate.c3p0.max_statements" value="0" />
<property name="hibernate.c3p0.timeout" value="100" />
其中:hibernate.connection.provider_class指明使用c3p0数据库连接池代替hibernate的默认数据库连接池。
<!-- 最大连接数 -->
<property name="hibernate.c3p0.max_size">20</property>
<!-- 最小连接数 -->
<property name="hibernate.c3p0.min_size">5</property>
<!-- 获得连接的超时时间,如果超过这个时间,会抛出异常,单位毫秒 -->
<property name="hibernate.c3p0.timeout">120</property>
<!-- 最大的PreparedStatement的数量 -->
<property name="hibernate.c3p0.max_statements">100</property>
<!-- 每隔120秒检查连接池里的空闲连接 ,单位是秒-->
<property name="hibernate.c3p0.idle_test_period">120</property>
<!-- 当连接池里面的连接用完的时候,C3P0一下获取的新的连接数 -->
<property name="hibernate.c3p0.acquire_increment">2</property>
<!-- 每次都验证连接是否可用 -->
<property name="hibernate.c3p0.validate">true</property>
21、需要把c3p0的库文件c3p0-0.9.1.jar复制到项目的库目录中。这个时候再运行系统,就使用c3p0数据库连接了。