2016-07-25 19 views
0

Ich entwickle eine Webanwendung mit Federrahmen und mybatis.Kann Spring DAO in Serviceebene zusammengeführt werden?

In den meisten Fällen (bei mir am wenigsten), sind DAO Methoden sehr kurz etwas wie folgt aus:

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao { 
    public User getUser(String userId) { 
    return (User) getSqlSession().selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId); 
    } 
} 

Also im Grunde, ich brauche für jede Abfrage ein Verfahren (zB getUser(String userId)) in DAO zu schreiben, das ist an Serviceobjekte weitergeleitet werden, an denen sie verwendet werden. Es scheint mir unnötig überflüssig zu sein.

Mein Kollege versucht es einfach zu machen. Er schrieb CommonDao wie folgt aus:

@Repository 
public class CommonDao { 
    @Autowired 
    private SqlSessionTemplate sqlSession; 

    public Object insert(String queryId, Object params) { 
     return sqlSession.insert(queryId, params); 
    } 

    public Object update(String queryId, Object params) { 
     return sqlSession.update(queryId, params); 
    } 

    public Object delete(String queryId, Object params) { 
     return sqlSession.delete(queryId, params); 
    } 

    public Object selectOne(String queryId) { 
     return sqlSession.selectOne(queryId); 
    } 

    public Object selectOne(String queryId, Object params) { 
     return sqlSession.selectOne(queryId, params); 
    } 
} 

So können wir diese Methoden in Dienste wie verwenden:

@Service 
public class CrudService { 
    ... 
    @Autowired 
    private CommonDao commonDao; 
    ... 

    public UserDto selectUser(Integer userId) { 
     ... 
     UserDto userDto = (UserDto) commonDao.selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId); 
     ... 
    } 
} 

Ich bin ein bisschen wie dieser approch da es Codes einfacher macht. Aber ich bin mir nicht sicher, ob es gut ist, zu folgen.

+0

ist es nicht, verwenden Sie Generika, wird viel helfen. Denken Sie nur an die Zeit, wenn Sie die Benennung einer dieser Klassen umgestalten, Sie müssten alle Namen finden, die so geschrieben sind, und sie manuell ändern. – Sarief

+0

auch, schauen Sie sich Spring Daten, insbesondere -> Repositories. sparen Sie viele CRUD Eingabe – Sarief

+0

PS: Objekte zurückgeben ist eine schlechte Praxis. was wirst du mit ihnen machen? – Sarief

Antwort

1

Um einen Standardcode zu vermeiden und gleichzeitig Typensicherheit zu haben und Ihre Serviceebene frei von DAO-Implementierungsdetails zu lassen, verwenden Sie spring-mybatisMapperScannerConfigurer.

In diesem Fall können Sie Ihre DAOs durch typsichere Mapper ersetzen.

Das Äquivalent Ihre DAO

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao { 
    public User getUser(String userId) { 
    return (User)getSqlSession().selectOne(
     "org.mybatis.spring.sample.mapper.UserMapper.getUser", userId); 
    } 
} 

werden dieses Zuordnerklasse

package org.mybatis.spring.sample.mapper; 

interface UserMapper { 
    User getUser(String userId); 
} 

sein, wenn Sie es zu UserDao umbenennen werden Sie nicht brauchen, um Ihre Dienste zu ändern. Der Dienst hängt nur von der deklarierten Mapper-Schnittstelle ab.

Beachten Sie, dass Sie diese Schnittstelle definieren müssen, um die Typensicherheit zu haben und auch die Abhängigkeit Ihres Dienstes zu definieren.

Natürlich müssen Sie konfigurieren spring-mybatis, so dass es Mapper-Implementierung basierend auf den Mapper-Schnittstellen in Ihrem Code definiert generiert. Dies ist ziemlich einfach und es gibt many options wie man das macht.

+0

Kann die 'getUser' Methode im' UserMapper' körperlos sein? – user2652379

+0

Das war ein Tippfehler, den ich behoben habe. Es sollte Schnittstelle der Ursache sein. –

0

Hmm, was Sie kämpfen, ist in MyBatis normal.

Ihr Mitarbeiter wies Sie in eine Richtung ... Aber was ist der wahre Wert von CommonDao in dieser Form? Für mich ist es nicht sehr nützlich. Du brauchst immer noch fast die gleiche Menge an Code - und trotzdem musst du eine Menge Casting machen. Wie @Rom Konoval sagte, gibt es MapperScannerConfigurer, die Mapper-Implementierungen generieren können - auf diese Weise schreiben Sie keine redundanten Implementierungen und haben den Vorteil einer Typsicherheit - Casting passiert immer noch, ist aber vor Ihnen verborgen. Du kannst es versuchen.
Hier ist ein sample usage auf dem GitHub.

Alternativ können Sie DAO-Implementierungen selbst erstellen (wie Sie bereits) oder einfach SqlSessionTemplate direkt in Ihren Diensten verwenden. Wie du willst. Behalte deine Code-Basis so klein wie möglich und folge einem gesunden Menschenverstand.

+0

Vielen Dank. Kannst du mir einen Weg zeigen, "direkt mit deiner Datenbank in der Serviceebene zu sprechen"? Was ich denke, ist 'SqlSessionTemplate' in Diensten anstelle von DAO, aber das würde immer noch Generika verwenden. – user2652379

+0

Nur um zu erklären "Sie benötigen immer noch fast die gleiche Menge an Code" - Es könnte mehrere Select-Abfragen geben. Und wie gesagt, ich muss für jede Abfrage eine Methode schreiben. Mit 'CommonDao' muss ich nur eine Methode (z. B. 'selectOne') schreiben, um ausgewählte Abfragen zu verwenden. Also, die Menge an Code ist verringert. Es ist eine schlechte Übung, aber zu folgen. – user2652379