DAO and DTO

In the following piece of code:-
package com.informit.myejb.dao;
public interface SampleDAO
public SampleModel create( long id, String name, String data ) throws
SampleDAOException;
public void delete( long id ) throws SampleDAOException;
public void update( long id, SampleModel model ) throws
SampleDAOException;
public SampleModel[] findByName( String name ) throws
SampleDAOException;
public SampleModel findById( long id ) throws SampleDAOException;
}we are creating a DTO named sampleModel. Now considering that I just need one value out of the whole table. Wouldn't creating the whole DTO object be a waste of time effort and memory, specially if each time we hae to access the DTO we have to create a new one. specially if the keys being passed to the method are used only once.
I understand the concept of separation of concerns but I am concerned over here about the amount of effort required to create these DAOs and DTOs specially in cases where only one or two fields are required.
To me it seems like an over kill.
Any comments.

well Martin Fowlwer does propose IdentityMap pattern in such a case where he says that thes objects should be stored in a Map with the primary key being the key for the map. So next time you need an object you check with the map if it exists or not and if it doesnot you try to grab it again.
But IMHO if the hit ratio(no. of times the same data is used again) is less these Maps might pose a nightmare in terms of memory and garbage collection.
So should one use IdentityMap or avoid it?
What do you think.

Similar Messages

  • Using DAO and DTO, or changing Patterns

    I have been working on a web project that revolves around scheduling events and enrolling people is said events. The schema is fairly straight forward, but does not lend itself well to OO, or at least what I have been used to. Before I get to the questions, I'll layout the basic idea of the trouble part of the schema.
    An Event has a 1:m relationship to Time Slots.
    A Time Slot has a 1:m relationship to Participants.
    A Time Slot also has a 1:M relationship to Tables.
    So, a given Event can run in multiple Time Slots, have multiple Participants in a Time Slot, and occupy multiple Tables in a Time Slot.
    Now, here's where I'd love some input because I know I'm lacking the experience. I've been reading in the forums here and in my books, many of which are included in the "must have" category as I've been reading here. I've adopted the DAO Pattern with DTOs the encompass the Event as a primary object/class. It has Lists which will get populated with the children. However, technically the way the schema is modelled, you cannot have participants or tables without a time slot. So, would I create separate bean or DTO to model the time slot that would also contains Lists for participants and tables? I imagine trying to represent nested relationships like the to a business layer might get hairy to maintain.
    So, in one scenario, an administrator would like to update event details, I'd use a findById() method to retrieve the full depth of the relationship in the schema.
    In a second scenario, a report is needed to list events, their times slots and tables in each time slot. Now, I have a List in my DTO that really has no need to be populated and would be wasteful to bring back from the database.
    A third scenario is a user comes to the site and wishes to search for events that they could enroll in. This time, for the search, I just want a few pieces from the primary table to displayed, I don't want to get the whole of the nested relationships and I want to get the search results by time slot. So, the way I've modelled the first DTO is now pretty much useless.
    So, is it better to construct to separate DTOs? I know I'd need different find() methods to support scenario 1 and 3. And in the case of retrieving non-needed data in scenario 2, should I provide a way to tell the DAO not to retrieve participants or just create yet another find() method that just doesn't populate participants?
    While I do have a say in the schema, I cannot just up and change it. I am more than willing to hear any and all critiques on code, schema, and how any part of this is implemented. As far as questions to why I'm not using Spring, Hibernate, or X framework, I just haven't had time to review them, but as this is still in design, it's fair game.
    Thanks in advance.

    >
    So, in one scenario, an administrator would like to
    update event details, I'd use a findById() method to
    retrieve the full depth of the relationship in the
    schema.
    In a second scenario, a report is needed to list
    events, their times slots and tables in each time
    slot. Now, I have a List in my DTO that really has
    no need to be populated and would be wasteful to
    bring back from the database.
    Ok - so don't do it.
    A third scenario is a user comes to the site and
    wishes to search for events that they could enroll
    in. This time, for the search, I just want a few
    pieces from the primary table to displayed, I don't
    want to get the whole of the nested relationships and
    I want to get the search results by time slot. So,
    the way I've modelled the first DTO is now pretty
    much useless.
    You can have more than one DTO. Or just don't populate everything in some cases.

  • Newbie's DAO and database design

    I have NodeDAO (which creates Node objects from a 'node' table). Node objects have a NodeType object which is handeled by the NodeTypeDAO (acessing 'node_type'
    table). For the NodeDAO to return a fully populated Node object, it must first give it a NodeType.
    Now should I:
    a) Let NodeDAO use NodeTypeDAO to handle NodeTypeObjects?
    b) Let NodeDAO use 'node_type' table, which should normally only be handeled by the NodeTypeDAO?
    c) Let NodeDAO return an incomplete Node object, and let the complete assembly/disassembly be handeled elsewhere (eg. TransferObjectAssembler)?
    I think option c) is most obvious as it gives the clearer design. I'm going to need a TransferObjectAssembler eventually because I need to access different type of NodeDAOs for each kind of NodeType (Category, Image, Document, etc.). It's that part of returned a not fully populated object that seems not quite right.
    Have I overlooked another solution to this problem?
    Any advice is appreciated, thanks.
    --Zta.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

    Hi Zta,
    There are a number of new techniques to Java EE 5 that can be used. DAO's and DTO's may longer be required in your application is you are using the Java Persistance APIs.
    Please take a look at the Java EE 5 tutorial located at http://java.sun.com/javaee/5/docs/tutorial/doc, specifically in the Persistence section located at http://java.sun.com/javaee/5/docs/tutorial/doc/PersistenceIntro.html to help inform you of the latest methods and technologies.
    Hope this helps - Thanks - Mark

  • Tight Coupling DAO with DTO

    Hello All,
    I need to ask a question about the DAO design pattern, does its CRUD methods have to be passed/return DTOs that encapsulates the domain data OR this data can exist as instance veraiable in the DAO class, and the client (session bean for example) can call the fine-grained set/get methods on the DAO.
    I'm worried about tight coupling my DAOs with DTO as the DTOs will be custom/use case specific DTOs that don't necssary map to the domain DTOs.
    Thanks

    Stop cross posting! http://forum.java.sun.com/thread.jsp?forum=425&thread=497475&start=0&range=15#2349469

  • DAO and Struts

    I m new to Struts and i wsh to do a stuff in it....
    I m not clear with the DAOs and Business Delegate model in it and i need a sample code for continuing with wher can i get if anybody culd suggest me a well start point??

    hi
    thanks for ur response,
    Actually i tried the tryme.war from http://javaboutique.internet.com/tutorials/ApacheDAOs/tryme.war
    i hav configured my conf/server.xml as
    <?xml version='1.0' encoding='utf-8'?>
    <Server>
    <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener"/>
    <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
    <GlobalNamingResources>
    <Environment name="simpleValue" type="java.lang.Integer" value="30"/>
    <Resource auth="Container" description="User database that can be updated and saved" name="UserDatabase" type="org.apache.catalina.UserDatabase" pathname="conf/tomcat-users.xml" factory="org.apache.catalina.users.MemoryUserDatabaseFactory"/>
    <Resource name="PointBaseJNDI" type="javax.sql.DataSource" password="mysql" driverClassName="com.mysql.jdbc.Driver" maxIdle="2" maxWait="5000" username="root" url="jdbc:mysql://localhost:3306/test" maxActive="40"/>
    <Resource name="jdbc/hrweb" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" password="mysql" maxIdle="2" maxWait="5000" username="root" url="jdbc:mysql://localhost:3306/hrweb" maxActive="4"/>
    <Resource name="jdbc/hrsite" type="javax.sql.DataSource" password="mysql" driverClassName="com.mysql.jdbc.Driver" maxIdle="2" maxWait="5000" username="root" url="jdbc:mysql://localhost:3306/hrsite" maxActive="40"/>
    <Resource name="testmysql" type="javax.sql.DataSource" password="admin" driverClassName="sun.jdbc.odbc.JdbcOdbcDriver" maxIdle="2" maxWait="5000" username="root" url="jdbc:odbc:tomtest" maxActive="4"/>
    <Resource name="jdbc/dao" type="javax.sql.DataSource" password="mysql" driverClassName="com.mysql.jdbc.Driver" maxIdle="2" maxWait="5000" username="root" url="jdbc:mysql://localhost:3306/test" maxActive="4"/>
    </GlobalNamingResources>
    <Service name="Catalina">
    <Connector port="8088" redirectPort="8443" maxSpareThreads="75" maxThreads="150" minSpareThreads="25">
    </Connector>
    <Connector port="8009" protocol="AJP/1.3" protocolHandlerClassName="org.apache.jk.server.JkCoyoteHandler" redirectPort="8443">
    </Connector>
    <Engine defaultHost="localhost" name="Catalina">
    <Host appBase="webapps" name="localhost">
    </Host>
    <Realm className="org.apache.catalina.realm.UserDatabaseRealm"/>
    </Engine>
    </Service>
    </Server>
    also my catalina/localhost/root.xml to be
    <?xml version='1.0' encoding='utf-8'?>
    <Context displayName="Welcome to Tomcat" docBase="ROOT" path="" workDir="work\Catalina\localhost\_">
    <ResourceLink global="jdbc/dao" name="jdbc/daoref" type="javax.sql.sourceParams"/>
    <ResourceLink global="testmysql" name="testmysqlref" type="javax.sql.DataSource"/>
    <ResourceLink global="PointBaseJNDI" name="PointBaseJNDIRef" type="javax.sql.DataSource"/>
    <ResourceLink global="AccessJNDI" name="AccessJNDIRef" type="javax.sql.DataSource"/>
    </Context>
    but when i tried to get run the tryme.war , list.jsp file
    i m getting the follown error...
    HTTP Status 500 -
    type Exception report
    message
    description The server encountered an internal error () that prevented it from fulfilling this request.
    exception
    javax.servlet.ServletException: Cannot find bean dvds in any scope
         org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:845)
         org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:778)
         org.apache.jsp.list_jsp._jspService(org.apache.jsp.list_jsp:106)
         org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:99)
         javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
         org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:325)
         org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
         org.apache.jasper.servlet.JspServlet.service(JspServlet.java:245)
         javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    root cause
    javax.servlet.jsp.JspException: Cannot find bean dvds in any scope
         org.apache.struts.util.RequestUtils.lookup(RequestUtils.java:938)
         org.apache.struts.taglib.logic.IterateTag.doStartTag(IterateTag.java:277)
         org.apache.jsp.list_jsp._jspService(org.apache.jsp.list_jsp:68)
         org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:99)
         javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
         org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:325)
         org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
         org.apache.jasper.servlet.JspServlet.service(JspServlet.java:245)
         javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    note The full stack trace of the root cause is available in the Apache Tomcat/5.5.4 logs.
    could u please figure out the problem?

  • DAO and Domain Object

    hi,
    Normally when i want to persist a domain object like Customer object to a database, my statements will be below,
    // code from my facade
    Customer cust = new Customer();
    cust.setFirstName("myname");
    cust.setLastName("mylastname");
    // set another attributes
    cust.create();
    with this code i have a CustomerPersistence object to handler for create this customer record to a database. Now j2ee have a DAO pattern. So my question is,
    1.where is a domain object within DAO pattern? --> because of we can reused domain object.
    2.DTO is Domain Object, isn't it?
    3.when i look at some articles about DAO, many of it will present in this way
    facade -->create DTO --> call DAO (plus something about factory pattern)
    i never see something like this
    facade --> domain object --> dao
    any suggestion?
    anurakth
    sorry for my english!!

    Hi,
    I am a bit confused about implementation of the domain model and I wondered if you could help. My main concern is that I am introducing too many layers and data holders into the mix. Here is what I am thinking.
    DTO - used to carry data between the presentation and the services layer
    Service Class - coordinates the calling of domain objects
    Domain Object - models a domain entity, service layer logic specific to this object is to be implemented here.
    Data Object - an exact representation of a database table. many to many relationship between domain object and data object.
    Hibernate DAO Class - has no properties, just methods used for read and writing the object to the database. It is passed in the Data Object for persistence. Is it wrong that the DAO contains no properties?
    Perhaps the domain object will contain each data object it is comprised of. I was originally going to keep calls to DAOs in the Services class (as recommended in http://jroller.com/page/egervari/20050109#how_to_change_services_logic ) but I am thinking that each domain object could expose a save method, and that method would co-ordinate persisting itself to the various tables it is derived from.
    Does this sound resonable? I have trouble finding a pattern on the net that clealy defines the Domain Model. I was tempted to map Domain Objects directly to database tables, and simply persist the Domain Object, but this 1-1 relationship may not always hold true.
    Thanks.

  • JSF and DTO classes

    Hello,
    I am interested in the following situation. I have 2 database tables and corresponding DTO and DAO classes. Here are the DTO classes:
    public class DTO1 {
        private int column1;
        private String column2;
        private String column3;
        private int fk1;
        /* getters, setters*/
    public class DTO2 {
        private int id;
        private String name1;
        private String columnX;
        private String columnY;
        /* getters, setters*/
    }Suppose that we want to execute the following query:
    SELECTt1.column1, t1.column2, t1.column3, t2.name FROMDTO1 t1, DTO2 t2 WHERE t1.fk1 = t2.id;What's right to do?
    Should I extend DTO1 class and add another field, e.g.
    public class DTO1Extended extends DTO1{
        private String name;
        /* getters, setters*/
    }and then use this extended model together with base model in my DAO class?
    Or, should I add this name field in my base model class, e.g.:
    public class DTO1 {
        private int column1;
        private String column2;
        private String column3;
        private int fk1;
        private String name;
        /* getters, setters*/
    }I think that the first approach is more OO.
    Or, maybe, there is some other (better) solution?
    What would some persistence framework, like Hibernate, done to resolve this situation?

    Already answered in the other thread which you hijacked: [http://forums.sun.com/thread.jspa?threadID=5360009].

  • Domains and DTOs

    Hi,
    In the past I have always used different objects (Domain objects) in the DAO layer, and different objects in the service layer (DTOs).
    I'm working on a new project where they requested that we just use one type of object. This means the front-end is using the same objects as the back-end.
    But now I'm starting to notice issues with this and I'm wondering if anyone else has had similar problems and how they overcame them.
    The main issue is basically:
    The front-end has a reference to a DTO.
    That DTO is sent to a transactional service method.
    The service method makes some changes to values in the DTO.
    The service method calls a DAO which updates the database.
    The service method gets some values from the database and updates the DTO with them.
    Something goes wrong and the transaction rollsback.
    The database changes rollback.
    The DTO changes do not.
    And now my front-end has references to a DTO that is in an invalid state.
    What's the best way to get around this?
    Clone the DTO in the service layer so the front-end is not using the same object reference?
    Thanks.

    quin wrote:
    Hi,
    In the past I have always used different objects (Domain objects) in the DAO layer, and different objects in the service layer (DTOs).
    I'm working on a new project where they requested that we just use one type of object. This means the front-end is using the same objects as the back-end.
    But now I'm starting to notice issues with this and I'm wondering if anyone else has had similar problems and how they overcame them.
    The main issue is basically:
    The front-end has a reference to a DTO.
    That DTO is sent to a transactional service method.
    The service method makes some changes to values in the DTO.
    The service method calls a DAO which updates the database.
    The service method gets some values from the database and updates the DTO with them.
    Something goes wrong and the transaction rollsback.
    The database changes rollback.
    The DTO changes do not.
    And now my front-end has references to a DTO that is in an invalid state.
    What's the best way to get around this?
    Myself I would look at why "something goes wrong" in such a way and so often that anyone cares what happens in the GUI versus that the operation itself failed. And why does the GUI care what the DTO at that point is doing anyways.
    But besides that....
    The front-end has a reference to a DTO.
    Wrap the following in a method
    DTO doit(DTO orig)
    ... DTO newDto = new DTO(orig); // Previous response
    ...That newDto is sent to a transactional service method.
    ...The service method makes some changes to values in the newDto .
    ...The service method calls a DAO which updates the database.
    ...The service method gets some values from the database and updates the newDto with them.
    ...Something goes wrong and the transaction rollsback.
    ...if The database changes rollback throw exception.
    ... No rollback so return newDto.
    GUI code
    origDTO = doit(origDTO);

  • DAO and session Facade

    Hi
    I came across an design pattern where they call the DAO from Session facade. The purpose of session facade is to minimise the number of network calls. Even though there are no network calls involved why do they go for session facade to call the DAO. Wont a DAOFActory will help them doin this.
    Even if the requirement is to block the presentation layer of all the backend operations, we could have had any other , why session facade was used i could nt understand

    You might even discover that entity beans can get created even before you use them.
    Your application server creates "pools" of bean instances that it can use when it needs to. It is part of this role, and is done in order to optimize performances.
    You cannot force them to be garbage collected. Even if you stop referencing them, the app server will.
    When your create references to a bean, it (usually) won't create an instance. It will take an existing one, and load data into it, using ejbCreate or ejbActivate.
    Hope this helps.
    /Stephane

  • DAO and MVC

    Hello!
    I am using the MVC pattern in my project.
    Should i put my DAOs in the model package or should i create
    a separate package for the DAOs? And in that case, what should i call it?
    What is the most common solution?

    valooCK wrote:
    a local class was your invention due to poor reading skills.Here we go again.
    [JLS �14.3 Local Class Declarations|http://java.sun.com/docs/books/jls/third_edition/html/statements.html#247773]
    A local class is a nested class (�8) that is not a member of any class and that has a name. All local classes are inner classes (�8.1.3). Every local class declaration statement is immediately contained by a block. Local class declaration statements may be intermixed freely with other kinds of statements in the block.
    The character known as "valooCK" consistently (and boy, do I mean consistently) demonstrates why posts made under that account are not to be taken seriously.
    ~

  • Dao and sql

    Dear All,
    In SQL we can find out the SUM of some datas, or we can get the datas by using select query and do the sum in DAO classes using StingBuffer.
    i need to know here,
    If i write SUM in query, is it processing speed will be low? or if i make sum in dao classes is it processing speed is faster? which one is good for better performance compared, writing in DAO classes is better or Sum in sql query is better?
    Thanks a lot in Adv

    It is entirely dependent on your design. If you fetch the records from two different tables via JDBC with no cache, the performance would be slower than doing the sum in the DB engine over large intervals based on the complexity of the query etc. This does not merit doing it with SUM though, it is entirely a design decision.

  • Loading DAO and SQL on demand for the request

    Hi,
    I have a requirement, where I need to load the SQL queries for the specific DAO on demand when the request has been made. This will ensure that I am not loading all the objects as I will be loading only the objects which I am going to work with. That is the main idea behind this operation. I am using JPA for back-end which connects to Oracle DB. Whether it will be better to load all the module specific DAO's on-demand using lazy-init="true" in Spring and load the specific SQL queries for those DAO's? In hibernate we are using named queries. Hence, please do suggest me how we can go about this?
    Whether it is better to load the DAOImpl and specific SQL for those DAO on demand (lazy-init="true")?If that is the case how we can do it? Please give me some examples on this? Whether we need to configure the named SQL queries in text file or XML? Which one will be better.Also suggest me which will be the best way of handling this? Any ideas are really appreciated.
    Thanks.

    I am unclear on if this question is a JPA question or a Spring/Hibernate question. If it is the later, you might try asking elsewhere, as this is a TopLink/JPA forum - TopLink is a JPA provider that includes EclipseLink. If it is JPA, you might make your question more clear, as JPA does not allow defining named queries in a text file and defining a query will not return entities from the database. JPA does allow defining queries in orm.xml or though annations on the entities themselves, and in JPA 2.1, you can add named queries in code. And entities are only returned when the query is executed, so you might want to explain a bit more what you are trying to avoid loading.
    Best Regards,
    Chris

  • DAO and CMT config...

    Hi.
              I am using WLS 8.1 sp2 . I have a stateless session bean that uses a DAO for database access. It appears that the DAO is not participating in the transaction. Here is a very simple example, here is my slsb method:
              public String doTransaction(int id, String name, String description)
              throws RemoteException
              //Call two methods, do the first to write a record, then
              //call setRollbackOnly to see if it is rolled back.
              try
              StoreDAO storeDAO = StoreDAOFactory.getDAO();
              storeDAO.saveT1(id, name);
              //I FORCE THIS CALL TO THROW AN EXCEPTION
              storeDAO.saveT2(id, description);
              catch( Exception e)
              ctx.setRollbackOnly(); //<-- saveT1 is NOT rolled back
              System.out.println("Ok, the rollbackonly was called");
              return e.getMessage();
              return "ok";
              Here is ejb-jar.xml as it pertains to this method:
              <container-transaction>
              <method>
              <ejb-name>ShoppingCartBean</ejb-name>
              <method-name>doTransaction</method-name>
              </method>
              <trans-attribute>RequiresNew</trans-attribute>
              </container-transaction>
              I force saveT2 to throw an exception right away, so the transaction will be rolled back, but the data that was written to the database during the saveT1 call is not rolled back.
              I obtain the database connection in the DAO by doing a JNDI lookup for the datasource that I configured with weblogic.
              Any Ideas?

    How is the DataSource configured? Is is a JDBCDataSource or a
              JDBCTxDataSource? If it isn't the latter, it isn't transactional and it will
              not be enlisted in the transaction started by the container.
              Bill
              "david kessler" <[email protected]> wrote in message
              news:15207409.1107277453717.JavaMail.root@jserv5...
              > Hi.
              >
              > I am using WLS 8.1 sp2 . I have a stateless session bean that uses a DAO
              > for database access. It appears that the DAO is not participating in the
              > transaction. Here is a very simple example, here is my slsb method:
              >
              > public String doTransaction(int id, String name, String description)
              > throws RemoteException
              > {
              > //Call two methods, do the first to write a record, then
              > //call setRollbackOnly to see if it is rolled back.
              > try
              > {
              > StoreDAO storeDAO = StoreDAOFactory.getDAO();
              > storeDAO.saveT1(id, name);
              > //I FORCE THIS CALL TO THROW AN EXCEPTION
              > storeDAO.saveT2(id, description);
              > }
              > catch( Exception e)
              > {
              > ctx.setRollbackOnly(); //<-- saveT1 is NOT rolled back
              > System.out.println("Ok, the rollbackonly was called");
              > return e.getMessage();
              > }
              > return "ok";
              > }
              >
              > Here is ejb-jar.xml as it pertains to this method:
              >
              > <container-transaction>
              > <method>
              > <ejb-name>ShoppingCartBean</ejb-name>
              > <method-name>doTransaction</method-name>
              > </method>
              > <trans-attribute>RequiresNew</trans-attribute>
              > </container-transaction>
              >
              > I force saveT2 to throw an exception right away, so the transaction will
              > be rolled back, but the data that was written to the database during the
              > saveT1 call is not rolled back.
              >
              > I obtain the database connection in the DAO by doing a JNDI lookup for the
              > datasource that I configured with weblogic.
              >
              > Any Ideas?
              

  • DAO and entity bean

    I have an entity bean which has a lot of gets and set methods. i am calling all the methods in a DAO. The DAO Recognizes all the old methods but not the last one, i dont understand why a single get Set is not being recognized.

    Your question is not very clear. Could you tell the problem in details?

  • Ejb 3 and DTO

    Dear all,
    as far as i know, ejb3 entity bean is just pojo and can detech from entity manager.
    So, Should i use entity object as DTO? or Should i use separate DTO ?
    What will be the best practive?
    With Regards,
    WP

    Hi,
    I saw this question was answered... But I couldn't see the other replies?
    Can share your answer here?
    Thanks.
    Ed

Maybe you are looking for