Data Access Objects (DAOs) are a common design pattern, and recommended by Sun. But the earliest examples of Java DAOs interacted directly with relational databases -- they were
DAO has lost its meaning over time.
During the J2EE days when it became a popular pattern, a DAO was a class where you could simultaneously cater for multiple sources of data - a database by one vendor, a database by another, a file - and provide a single place to wrap queries to communicate for data.
There was plenty of scope for reuse, so an DAO object for a particular entity may well extend an abstract DAO which housed the re-usable stuff, which in itself implemented a DAO interface.
Post-J2EE/EJB, the DataMapper and DataSource patterns (or for simple systems, ActiveRecord) became popular to perform the same role. However, DAO became a buzzword for any object involved with persistence.
Nowdays, the term 'DAO' has sadly become a synonym for "a class which enables me to communicate with my database".
With ORM / JPA, much of the rationale for a true, J2EE era DAO is provided out of the box.
In the case of a latter DataSource pattern, JPA's EntityManager is akin to the DataSource, but is usually provided via a PersistenceUnit XML definition and instantiated via IoC.
The CRUD methods which once lived in a DAO or Mapper can now be provided exactly once using the Repository pattern. There's no need for AbstractDAO's - the ORM products are clever enough to accept an Object() and know where it is persisting it.