Java DAO模式+JNDI数据源+CDI和MyBatis
我计划从我的项目中删除JPA Eclipselink,并使用MyBatis代替它。我在寻找一些不错的指南,在EE容器状态类会话ejb和JNDI数据源+DAO模式+CDI中使用MyBatis的最佳实践是什么?我不使用Spring!。不幸的是,我没有找到任何关于它的好文档 有没有任何方法可以在没有xml配置文件的情况下初始化MyBatis并使用JNDI数据源 MyBatis实现DAO模式并使用CDI将DAO类注入无状态EJB的最佳方式是什么 我使用Java8+Glassfish Payara EE服务器+MyBatis 3.4.2 更新-1 我按照这一页上的说明做了,但它对我不起作用 这是Glassfish的运行时异常,实际上它是Payara应用程序服务器:Java DAO模式+JNDI数据源+CDI和MyBatis,java,hibernate,jpa,mybatis,ibatis,Java,Hibernate,Jpa,Mybatis,Ibatis,我计划从我的项目中删除JPA Eclipselink,并使用MyBatis代替它。我在寻找一些不错的指南,在EE容器状态类会话ejb和JNDI数据源+DAO模式+CDI中使用MyBatis的最佳实践是什么?我不使用Spring!。不幸的是,我没有找到任何关于它的好文档 有没有任何方法可以在没有xml配置文件的情况下初始化MyBatis并使用JNDI数据源 MyBatis实现DAO模式并使用CDI将DAO类注入无状态EJB的最佳方式是什么 我使用Java8+Glassfish Payara EE服
[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类:
@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
也许我犯了个错误,我忘了什么
更新-2
如果至少有一个适当的CDIBean未使用,则Weld不会检测映射器。Servlet不是合适的CDIBean。
解决方法是使用@Dependent注释servlet。
您可以找到更多详细信息。是的,有一种在JavaEE环境中使用myBatis的好方法,尤其是CDI 有一个mybatis cdi扩展,可以为您解决许多问题,并确保完美的集成。网站及其链接 你应该仔细阅读这本书。特别是在介绍之后,左边菜单中的入门部分。他们解释如何设置一切
此外,还有一个很好的示例项目。这里甚至有一个。我的答案,为了清晰起见,还报告了我的评论 不是第一个问题,但可能是下一个问题:至少在类路径中需要mybatis-configuration.xml来定义transactionManager和引用jndi数据源 以防万一,为MyBatisSQLSessionFactory添加一个带有日志的默认构造函数。应该只实例化一次 对于WAR,beans.xml必须在WEB-INF中。否则,在单独的依赖项ejb.jar中提取业务代码,所有这些都打包在EAR中 我建议激活:填充beans.xml I@Inject@SessionFactory保护的SqlSession会话;在EJB中,然后在其方法中:新的DAOsession;因为事务是在EJB级别上管理的,而使用会话注入DAO并没有按预期工作
当调用多个语句时,还要注释EJB方法@TransactionalExecutionType=ExecutionType.REUSE。这将使用相同的接头;对所有交易报表执行一次操作,并只准备一次唯一的报表。先试试,不要弄清楚。首先,你使用的是什么版本的Java EE?我在原始文章中添加了此信息。不是第一期,但可能是下一期:至少在类路径中需要mybatis-configuration.xml来定义transactionManager和引用jndi数据源。这是我的第一个计划,但mybatis cdi尚未发布。我已经阅读了一些关于如何创建SQLSessionFactory的文档,据我所知,我有两种方法:我可以在生产中使用mybatis cdi beta6,还是您建议我使用第一种解决方案?你能给我举一个如何在实践中使用mybatis cdi的例子吗?我不知道在我的第二个场景中需要注入什么。尚不清楚如何在应用服务器环境中使用容器管理的事务。我不想手动执行sqlSessionFactory.openSession.commit。如果我想使用容器管理的事务,那么我需要向dao实现注入什么?在这种情况下,我似乎需要注入与SqlSessionFactory对象不同的东西。如果需要myBatis,我会使用它。我用得很好。事务部分只需要启用一个CDI拦截器:我可能不理解您所说的第二个场景是什么意思。我的mybatis CDI beta3在生产中运行良好。I@Inject@SessionFactory保护的SqlSession会话;在EJB中,然后在其方法中:新的DAOsession;因为事务是在EJB级别上管理的,并且使用会话注入DAO没有按预期工作;凉的但我并没有预见到任何集成,我已经使用了很长时间的beta版似乎足够稳定,可以满足我的需求。无论如何,我很快就会给它做个测试。