Facebook Twitter LinkedIn E-mail
magnify
Home Posts tagged "Vaadin"

Vaadin Web应用开发教程(51): 总结

到目前为止基本介绍了开发Vaadin使用的基本方法,包括概述,UI组件,布局方法,主题的使用,数据绑定及SQLContainer,可以满足初学者的需求,其它关于开发自定义UI组件,AJAX,使用插件,测试等后面在Vaadin高级进阶时在介绍。
为方便查询,下面列出Vaadin Web应用开发教程相关文章。

  1. Vaadin Web应用开发教程(1):概述
  2. Vaadin Web应用开发教程(2):安装开发环境
  3. Vaadin Web应用开发教程(3):Vaadin应用程序框架介绍
  4. Vaadin Web应用开发教程(4):开始编写Web应用
  5. Vaadin Web应用开发教程(5):Vaadin Web应用的基本组成部分
  6. Vaadin Web应用开发教程(6):使用资源
  7. Vaadin Web应用开发教程(7):UI组件概述
  8. Vaadin Web应用开发教程(8):UI组件-Label
  9. Vaadin Web应用开发教程(9):UI组件-Link
  10. Vaadin Web应用开发教程(10):UI组件-TextField
  11. Vaadin Web应用开发教程(11):UI组件-TextArea
  12. Vaadin Web应用开发教程(12):UI组件-PasswordField
  13. Vaadin Web应用开发教程(13):UI组件-RichTextArea
  14. Vaadin Web应用开发教程(14):UI组件-DateField
  15. Vaadin Web应用开发教程(15):UI组件-Button
  16. Vaadin Web应用开发教程(16):UI组件-Checkbox
  17. Vaadin Web应用开发教程(17):UI组件-Select 组件
  18. Vaadin Web应用开发教程(18):UI组件-Table 组件
  19. Vaadin Web应用开发教程(19):UI组件-Tree 组件
  20. Vaadin Web应用开发教程(20):UI组件-MenuBar组件
  21. Vaadin Web应用开发教程(21):UI组件-Embedded组件
  22. Vaadin Web应用开发教程(22):UI组件-Upload组件
  23. Vaadin Web应用开发教程(23):UI组件-Form组件
  24. Vaadin Web应用开发教程(24):UI组件-ProgressIndicator组件
  25. Vaadin Web应用开发教程(25):UI组件-Slider组件
  26. Vaadin Web应用开发教程(26):UI组件-LoginForm组件
  27. Vaadin Web应用开发教程(27):UI组件-自定义组件
  28. Vaadin Web应用开发教程(28):UI布局-概述
  29. Vaadin Web应用开发教程(29):UI布局-VerticalLayout和HorizontalLayout布局
  30. Vaadin Web应用开发教程(30):UI布局-GridLayout布局
  31. Vaadin Web应用开发教程(31):UI布局-FormLayout布局
  32. Vaadin Web应用开发教程(32):UI布局-Panel
  33. Vaadin Web应用开发教程(33):UI布局-HorizontalSplitPanel和VerticalSplitPanel布局
  34. Vaadin Web应用开发教程(34):UI布局-TabSheet布局
  35. Vaadin Web应用开发教程(35):UI布局-Accordion布局
  36. Vaadin Web应用开发教程(36):UI布局-AbsoluteLayout 布局
  37. Vaadin Web应用开发教程(37):可视化界面编辑插件
  38. Vaadin Web应用开发教程(38):使用主题-概述
  39. Vaadin Web应用开发教程(39):使用主题-CSS简介
  40. Vaadin Web应用开发教程(40):使用主题-创建和应用新主题
  41. Vaadin Web应用开发教程(41):数据绑定-概述
  42. Vaadin Web应用开发教程(42):数据绑定-Property接口
  43. Vaadin Web应用开发教程(43): 使用Item接口管理一组Property
  44. Vaadin Web应用开发教程(44): 使用Container接口管理一组Item
  45. Vaadin Web应用开发教程(45): SQLContainer 概述
  46. Vaadin Web应用开发教程(46): 开始使用SQLContainer
  47. Vaadin Web应用开发教程(47): SQLContainer-过滤及排序
  48. Vaadin Web应用开发教程(48): SQLContainer-编辑
  49. Vaadin Web应用开发教程(49): SQLContainer-引用其它SQLContainer
  50. Vaadin Web应用开发教程(50): SQLContainer-使用FreeformQuery
 

Vaadin Web应用开发教程(50): SQLContainer-使用FreeformQuery

在大部分情况下使用TableQuery就可以满足应用要求,如果需要使用复杂查询,比如多表查询,则可以使用FreeformQuery。 缺省情况下FreeformQuery为只读,如果需要支持写操作,可以自行实现FreeformQueryDelegate接口。

// Read-only queries
public StatementHelper getCountStatement()
public StatementHelper getQueryStatement(int offset, int limit)
public StatementHelper getContainsRowQueryStatement(Object... keys)

// Filtering and sorting
public void setFilters(List<Filter> filters)
public void setFilters(List<Filter> filters,
                       FilteringMode filteringMode)
public void setOrderBy(List<OrderBy> orderBys)
 
// Write support
public int storeRow(Connection conn, RowItem row)
public boolean removeRow(Connection conn, RowItem row)

本例使用多表查询,查询语句如下:

SELECT C.FIRSTNAME , C.LASTNAME , INV.ID,INV.TOTAL 
FROM CUSTOMER C 
INNER JOIN INVOICE INV
ON C.ID=INV.CUSTOMERID;
void openTable(VerticalLayout layout){
	try {
		JDBCConnectionPool pool = new SimpleJDBCConnectionPool(
				"org.hsqldb.jdbc.JDBCDriver",
				"jdbc:hsqldb:file:/hsqldb/data/sample", "SA", "", 2, 5);
		FreeformQuery query = new FreeformQuery(
				"SELECT C.FIRSTNAME , " +
				"C.LASTNAME , INV.ID,INV.TOTAL " +
				"FROM CUSTOMER C " +
				"INNER JOIN INVOICE INV " +
				"ON C.ID=INV.CUSTOMERID;", pool, "ID");
		SQLContainer container = new SQLContainer(query);
		Table table = new Table("All Invoices", container);
		table.setSelectable(true);

		layout.addComponent(table);
		
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	}

到目前为止,基本介绍完SQLContainer的用法,不过整体来说SQLContainer虽然使用简单方便,当功能有限,对应复杂的数据库应用还是可以直接使用JDBC和JPA等。

 

Vaadin Web应用开发教程(49): SQLContainer-引用其它SQLContainer

数据库表之间存在参考关键,这对应到数据库通常为外键引用。Vaadin 的SQLContainer提供了不同SQLContainer之间引用的有限支持,但其实现主要是通过Java 代码来实现的,并不需要数据库的表之间一定要有外键定义。
给一个SQLContainer添加引用的方法为:

public void addReference(SQLContainer refdCont,
                         String refingCol, String refdCol);

refdCont为被引用的SQLContainer,refingCol 为源SQLContainer对应的列名,refdCol为目标SQLContainer被参照的列名。
要注意的是SQLContainer不支持同一个SQLContainer参照自身。

还是以Customer ,Invoice 为例。 显示所有Invoice,但点击某个Invoice,显示对应的Customer的姓名。

void openTable(VerticalLayout layout){
	try {
		JDBCConnectionPool pool = new SimpleJDBCConnectionPool(
				"org.hsqldb.jdbc.JDBCDriver",
				"jdbc:hsqldb:file:/hsqldb/data/sample", "SA", "", 2, 5);
		TableQuery customers = new TableQuery("CUSTOMER", pool);
		customers.setVersionColumn("OPTLOCK");
		TableQuery invoices = new TableQuery("INVOICE", pool);
		customers.setVersionColumn("OPTLOCK");
		final SQLContainer customerContainer
                        = new SQLContainer(customers);
		final SQLContainer invoiceContainer
                       = new SQLContainer(invoices);
		Table table = new Table("All Invoices", invoiceContainer);
		table.setSelectable(true);

		// Send changes in selection immediately to server.
		table.setImmediate(true);

		invoiceContainer.addReference(customerContainer, 
                           "CUSTOMERID", "ID");
		
		table.addListener(new ItemClickListener(){

			public void itemClick(ItemClickEvent event) {
				RowItem rowItem=(RowItem)event.getItem();
						
				RowItem customerItem
					=(RowItem)invoiceContainer
					.getReferencedItem(rowItem.getId(), 
							customerContainer);
				
				customerLabel.setValue(customerItem
                               .getItemProperty("FIRSTNAME")
                               .toString()
                                +" "+ customerItem
                                .getItemProperty("LASTNAME")
                                .toString());
				
			}});
		layout.addComponent(table);
		
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

SQLContainer和参照其它SQLContainer的主要方法如下:

public boolean setReferencedItem(Object itemId,
        Object refdItemId, SQLContainer refdCont)
public Object getReferencedItemId(Object itemId,
                                  SQLContainer refdCont)
public Item getReferencedItem(Object itemId,
                              SQLContainer refdCont)
public boolean removeReference(SQLContainer refdCont)

这里不再一一说明了。

 

Vaadin Web应用开发教程(48): SQLContainer-编辑

和普通Container修改其中Item项类似,SQLContainer 可以使用类似的方法来编辑其中的Item。RowItem的ColumnProperties 会自动通知SQLContainer关于数据的变化并应用到数据库。
添加Item
向SQLContainer中添加一项是通过方法addItem()来完成的。这个方法将创建一个新的Item,新创建的Item可以在内存中缓存或直接添加到数据库中。这取决于SQLContainer的auto commit 模式。
实际也只能通过addItem() 方法向SQLContainer中添加记录,其它由Container定义的方法SQLContainer并不支持:

public boolean addContainerProperty(Object propertyId,
                                    Class<?> type,
                                    Object defaultValue)
public boolean removeContainerProperty(Object propertyId)
public Item addItem(Object itemId)
public Object addItemAt(int index)
public Item addItemAt(int index, Object newItemId)
public Object addItemAfter(Object previousItemId)
public Item addItemAfter(Object previousItemId, Object newItemId)

此外RowItem 不支持的Item方法有:

public boolean addItemProperty(Object id, Property property)
public boolean removeItemProperty(Object id)

下面的例子向Customer 表中添加一个记录 James ,Shen, Tribute Street, Perth

void addCustomer(SQLContainer sqlContainer){
		
	sqlContainer.setAutoCommit(false);
	TemporaryRowId rowId=(TemporaryRowId)sqlContainer.addItem();
	if(rowId!=null){
		RowItem rowItem=(RowItem)sqlContainer.getItem(rowId);
		ColumnProperty firstName=(ColumnProperty)rowItem.getItemProperty("FIRSTNAME");
		firstName.setValue("James");
		ColumnProperty lastName=(ColumnProperty)rowItem.getItemProperty("LASTNAME");
		lastName.setValue("Shen");
		ColumnProperty street=(ColumnProperty)rowItem.getItemProperty("STREET");
		street.setValue("Tribute Steet");
		ColumnProperty city=(ColumnProperty)rowItem.getItemProperty("CITY");
		city.setValue("Perth");
		ColumnProperty Id=(ColumnProperty)rowItem.getItemProperty("ID");
		Id.setValue(50);
		rowItem.commit();
		
	}
}

整体感觉使用SQLContainer编辑数据并不十分方便,还不如直接使用SQL语句或是使用hibernate.来的方便。

 

Vaadin Web应用开发教程(47): SQLContainer-过滤及排序

SQLContainer 的过滤及排序在设计时总是通过数据库操作来完成,也就是说在使用Filter 和Sorting 时应用与数据库之间会发生通信。实际上Filter 对应到SQL语句的WHERE语句,Sorting 则对应到ORDER BY语句。

除了Container支持的Filter之外(可以参见Vaadin Web应用开发教程(44): 使用Container接口管理一组Item),SQLContainer 也支持Like 和 Between  过滤器。 它们也对应到WHERE语句。

比如我们要查询名字叫“John” 住在”New York” 的客户。

container.addContainerFilter(
				   new And (new Equal("FIRSTNAME", "John"),
						   new Equal("CITY","New York")));

这实际上是执行:

select * from customer
where FirstName='John' and city='New York'

排序可以使用Vaadin提供的Sort 方法,其参数定义如下:

public void sort(Object[] propertyId, boolean[] ascending)

此外还可以使用 addOrderBy 方法。

比如按客户的FirstName 排序

container.addOrderBy(new OrderBy("FIRSTNAME",true));

 

Vaadin Web应用开发教程(46): 开始使用SQLContainer

在Vaadin中使用SQLContainer简单而直接,本篇及后面几篇将使用HSQLDB为例,HSQLDB为一纯JAVA实现的数据库系统,支持多种模式,如服务器模式(如其它数据库服务器比如Sql server, MySQL) 或者作为应用程序的一部分,或是直接使用内存。 本例使用HSQLDB的主要原因是因其简单,不需要另外安装数据库服务器,只要使用jar 包,例子使用随HSQLDB下载包中提供的示例数据。
其创建数据表的语句如下:

CREATE TABLE Customer(ID INTEGER PRIMARY KEY,FirstName VARCHAR(20),LastName VARCHAR(30),Street VARCHAR(50),City VARCHAR(25));
CREATE TABLE Product(ID INTEGER PRIMARY KEY,Name VARCHAR(30),Price DECIMAL);
CREATE TABLE Invoice(ID INTEGER PRIMARY KEY,CustomerID INTEGER,Total DECIMAL, FOREIGN KEY (CustomerId) REFERENCES Customer(ID) ON DELETE CASCADE);
CREATE TABLE Item(InvoiceID INTEGER,Item INTEGER,ProductID INTEGER,Quantity INTEGER,Cost DECIMAL,PRIMARY KEY(InvoiceID,Item), FOREIGN KEY (InvoiceId) REFERENCES Invoice (ID) ON DELETE CASCADE, FOREIGN KEY (ProductId) REFERENCES Product(ID) ON DELETE CASCADE);


这里我们把sample 数据库创建在C:/hsqldb/data 目录下:
显示Customer表格的基本代码如下:

void openTable(VerticalLayout layout){
		try {
			JDBCConnectionPool pool = new SimpleJDBCConnectionPool(
			        "org.hsqldb.jdbc.JDBCDriver",
			        "jdbc:hsqldb:file:/hsqldb/data/sample", "SA", "", 2, 5);
			TableQuery tq = new TableQuery("Customer", pool);
			tq.setVersionColumn("OPTLOCK");
			SQLContainer container = new SQLContainer(tq);
			// Bind a table to it
			Table table = new Table("All customers", container);
		    layout.addComponent(table);

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

可以看到使用SQLContainer的基本步骤如下:
1. 创建数据库连接 ,这里使用SimpleJDBCConnectionPool

JDBCConnectionPool pool = new SimpleJDBCConnectionPool(
			        "org.hsqldb.jdbc.JDBCDriver",
			        "jdbc:hsqldb:file:/hsqldb/data/sample", "SA", "", 2, 5);

不同的数据可以的连接字符串jdbc:hsqldb:file:/hsqldb/data/sample 不同,这里连接到一个文件数据库,如果使用内存数据库,连接字符串可以为jdbc:hsqldb:mem:sqlcontainer。

2. 有了数据库连接之后,就可以创建一个TableQuery,给出需要查询的数据库表名,本例使用表Customer.
3. 如果需要支持多用户连接数据库,可以设定数码库锁定的方式。 本例使用OptimisticLock. ( 可选)
4. 最后创建一个SQLContainer对象。

显示如下:

注意: 你需要将下载的HSQLDB 数据库的jar 包放在项目的WebContent/WEB-INF/lib 目录下: