我打算从我的项目中删除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