我打算從我的項目中刪除JPA(Eclipselink),並使用MyBatis代替它。我正在尋找一些很好的指南在EE容器(statelass session ejb)和JNDI數據源+ DAO模式+ CDI(我沒有使用Spring!)中使用MyBatis的最佳實踐是什麼。不幸的是,我還沒有找到任何有關它的好文檔。DAO模式+ JNDI datasouce + CDI與MyBatis
是否有任何方式來初始化MyBatis並使用JNDI數據源而不使用xml配置文件?
什麼是最好的MyBatis的方式來實現DAO模式,並與CDI注入我的DAO類無狀態EJB?
我使用Java 8 + Glassfish(Payara EE服務器)+ MyBatis 3.4.2。
UPDATE-1
我跟着http://www.mybatis.org/cdi/getting-started.html此頁面上的指令,但它並沒有爲我工作。
這是運行時異常我用Glassfish的有(實際上它是一個似鯖水狼牙魚)應用服務器:
[2017-02-14T22:02:23.715+0100] [Payara 4.1] [INFO] [AS-WEB-GLUE-00172] [javax.enterprise.web] [tid: _ThreadID=101 _ThreadName=admin-listener(6)] [timeMillis: 1487106143715] [levelValue: 800] [[
Loading application [mybatis-demo-1.0#mybatis-demo-war-1.0.war] at [/demo]]]
[2017-02-14T22:02:23.770+0100] [Payara 4.1] [INFO] [] [javax.enterprise.system.core] [tid: _ThreadID=101 _ThreadName=admin-listener(6)] [timeMillis: 1487106143770] [levelValue: 800] [[
mybatis-demo-1.0 was successfully deployed in 1,526 milliseconds.]]
[2017-02-14T22:03:00.333+0100] [Payara 4.1] [INFO] [] [javax.enterprise.web] [tid: _ThreadID=25 _ThreadName=http-listener-1(2)] [timeMillis: 1487106180333] [levelValue: 800] [[
WebModule[null] ServletContext.log():Marking servlet a.b.war.HelloServlet as unavailable]]
[2017-02-14T22:03:00.334+0100] [Payara 4.1] [WARNING] [] [javax.enterprise.web] [tid: _ThreadID=25 _ThreadName=http-listener-1(2)] [timeMillis: 1487106180334] [levelValue: 900] [[
StandardWrapperValve[a.b.war.HelloServlet]: Allocate exception for servlet a.b.war.HelloServlet
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type PersonMapper with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private a.b.war.HelloServlet.personMapper
at a.b.war.HelloServlet.personMapper(HelloServlet.java:0)
這是我的測試Servlet:
@WebServlet("/servlet")
public class HelloServlet extends HttpServlet {
@Inject
private PersonMapper personMapper;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println(personMapper.getPerson(1L).toString());
}
我的映射類:
@Mapper
public interface PersonMapper {
@Select("SELECT * FROM person WHERE id = #{id}")
Person getPerson(@Param("id") long id);
}
似乎MyBatisSQLSessionFactory.getSqlSessionFactory()方法不會被調用因爲我在日誌文件中看不到任何東西。
我的SessionFactory類:
public class MyBatisSQLSessionFactory {
private static final Logger LOGGER = LoggerFactory.getLogger(MyBatisSQLSessionFactory.class);
@Produces
@ApplicationScoped
@SessionFactoryProvider
public SqlSessionFactory getSqlSessionFactory() throws IOException {
LOGGER.info("MyBatis is initializing...");
String resource = "mybatis-configuration.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
LOGGER.info("MyBatis has been initialized, SQL Session Factory: {}", sqlSessionFactory.toString());
return sqlSessionFactory;
}
}
最後我戰爭的結構:
*.war
│ index.html
│
├───META-INF
│ │ bean.xml
│ │ MANIFEST.MF
│ │
│ └───maven
│ ...
│
└───WEB-INF
├───classes
│ └───a
│ └───b
│ └───war
│ │ HelloServlet.class
│ │
│ └───mybatis
│ │ MyBatisSQLSessionFactory.class
│ │
│ └───dao
│ PersonMapper.class
│
└───lib
也許我犯了一個錯誤,我忘了什麼事......
UPDATE-2
「如果沒有至少一個適當的CDI bean使用,Weld不會檢測映射器。而Servlet不是正確的CDI bean。 解決方法是@Dependent來註釋的servlet。」 你可以找到更多的細節here。
首先您使用的是哪個版本的Java EE? –
我將此信息添加到原始帖子。 – zappee
不是第一個問題,但可能是下一個問題:在classpath中至少需要mybatis-configuration.xml來定義transactionManager和引用jndi dataSource。 – blackwizard