我打算从我的项目中删除JPA(Eclipselink)并使用MyBatis而不是它。我正在寻找一些很好的指南,在EE容器(statelass session ejb)和JNDI数据源+ DAO模式+ CDI(我不使用Spring!)中使用MyBatis的最佳实践是什么。不幸的是,我没有找到任何关于它的好文档。
有没有办法初始化MyBatis并使用没有xml配置文件的JNDI数据源?
使用CDI实现DAO模式并将我的dao类注入无状态EJB的最佳MyBatis方法是什么?
我使用Java 8 + Glassfish(Payara EE服务器)+ MyBatis 3.4.2。
UPDATE-1
我按照此页http://www.mybatis.org/cdi/getting-started.html上的说明操作,但它对我不起作用。
这是我使用Glassfish(实际上是Payara)应用服务器时的运行时异常:
[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。
答案 0 :(得分:1)
我在这里的答案,也是为了清楚起见我的评论。
不是第一个问题,但可能是下一个问题:至少在类路径中需要mybatis-configuration.xml来定义transactionManager和引用jndi dataSource。
以防万一为MyBatisSQLSessionFactory添加一个带默认构造函数的默认构造函数。应该只实例化一次。
对于WAR,beans.xml必须位于WEB-INF中。否则,在单独的依赖项ejb.jar中提取业务代码,所有这些都打包在EAR中。
我建议激活JTA Transactions:填充beans.xml。
我在EJB中使用@Inject @SessionFactory protected SqlSession session;
,然后在其方法中使用new DAO(session);
,因为事务是在EJB级别上管理的,并且注入会话的DAO注入不能按预期工作。
当有多个语句被调用时,还要注释EJB方法@Transactional(executorType=ExecutorType.REUSE)
。这将使用相同的连接;所有交易报表的ction,只准备一次唯一的报表。首先尝试不弄清楚。
答案 1 :(得分:0)
是的,有一种很好的方法可以在Java EE环境中使用myBatis,尤其是CDI。
有一个mybatis-cdi扩展,可以为您解决许多问题并确保完美集成。 GitHub repository is here并链接到official documentation.
您应该彻底阅读official documentation。特别是“入门”部分(在介绍之后的左侧菜单中)。他们解释了如何设置一切。
此外,还有一个很好的示例项目to be found on GitHub。甚至有example with JSF used。