The h:button is a recent addition and is part of a set of improvements that make
JSF more GET-friendly.
The original way to use an "edit" button in a table can be seen illustrated in a very old, but still essentially useful article "JSF For NonBelievers" at IBM DeveloperWorks.
In a nutshell, you use a DataModel object as the Model object for the dataTable. JSF1 required a DataModel. JSF2 will automatically construct one from an ordered collection (List or array), but it will be anonymous, so you won't be able to access useful functions if you do that.
In the commandButton's action method, you can use the dataModel's getRowData to obtain the object that backs the selected row, or the getRowIndex if you just want its row number.
Armed with this information, you can use JSF navigation to handle the detail edit. Here's a sample:
In this example, the thingEditor detail edit backing bean was injected as a managed property into the thingTableList class that contains the above method. That, however, requires thingEditor to be session scoped, which can be annoying. There are alternatives, however.
Any object containing a DataModel must have at least View Scope. If it's put in Request scope, the DataModel gets destroyed and re-created from scratch on each request, and loses essential context information. This is one of the reasons why Request scope is almost totally useless in JSF.