2017-02-14 29 views
0

Я планирую удалить JPA (Eclipselink) из моего проекта и использовать MyBatis вместо него. Я искал какой-нибудь хороший путеводитель, что лучше всего использовать MyBatis в контейнере EE (статическая сессия ejb) и JNDI datasource + DAO pattern + CDI (я не использую Spring!). К сожалению, я не нашел хорошей документации об этом.DAO pattern + JNDI datasouce + CDI с MyBatis

Есть ли способ инициализировать MyBatis и использовать источник данных JNDI без файла конфигурации xml?

Каков наилучший способ MyBatis для реализации шаблона DAO и впрыскивать мои классы dao в Ecl с отсутствием состояния с CDI?

Я использую 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) 

Это мой тестовый сервлет:

@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 

Может быть, я сделал ошибку, и я что-то забыл ...


ОБНОВЛЕНИЕ-2

«Сварщик не обнаруживает карту, если не используется по крайней мере одним соответствующим CDI-компонентом. И Servlet не является надлежащим CDI bean. Обход является аннотировать сервлет с @Dependent.» Вы можете найти более подробную информацию here.

+0

Прежде всего, какую версию Java EE вы используете? –

+0

Я добавил эту информацию в исходное сообщение. – zappee

+0

не первая проблема, но, возможно, следующая: mybatis-configuration.xml требуется в пути к классам, по крайней мере, для определения transactionManager и reference jndi dataSource. – blackwizard

ответ

0

Да, есть хороший способ работы с myBatis в Java EE вредоносного, особенно CDI.

Там есть mybatis-КДИ расширение, которое решает многие проблемы для вас и обеспечивает безупречную интеграцию. GitHub repository is here и ссылки на official documentation.

Вы должны прочитать official documentation тщательно особенно в разделе «начало работы» (. в меню слева, только после того, как введение). Они объясняют, как настроить все.

Кроме того, есть хороший пример проекта to be found on GitHub. Существует даже example with JSF used.

+0

Это был мой первый план, но mybatis-cdi еще не выпущен. Я прочитал некоторую документацию о том, как создать SQLSessionFactory, и, насколько я понимаю, у меня есть два способа: https://gist.githubusercontent.com/zappee/b837c389d81a8e658dd362b970e16fc9/raw/eeb4230a5b8b63d602a3118202708136b9b328d6/gistfile1.txt – zappee

+0

Могу ли я использовать mybatis-cdi beta6 в производстве или вы рекомендуете мне использовать 1-е решение? Не могли бы вы дать мне пример того, как использовать на практике mybatis-cdi? Я не знаю, что мне нужно вводить во втором сценарии. Непонятно, как использовать транзакцию, управляемую контейнером, в среде сервера приложений. Я не хочу делать sqlSessionFactory.openSession(). Commit() вручную. Если я хочу использовать транзакции, управляемые контейнером, то что мне нужно сделать для выполнения моей dao? В этом случае мне кажется, что мне нужно ввести что-то другое, чем объект SqlSessionFactory. – zappee

+0

Я бы использовал его, если myBatis требуется. Я использую его просто отлично. Для части транзакции требуется только один перехватчик CDI: http://www.mybatis.org/cdi/transactions.html Возможно, я не понимаю, что вы подразумеваете под вторым сценарием. –

1

Мой ответ здесь, также сообщая мои комментарии для наглядности.

Не первый выпуск, но, возможно, следующий: mybatis-configuration.xml требуется в пути к классам, по крайней мере, для определения transactionManager и reference jndi dataSource.

На всякий случай добавьте конструктор по умолчанию с журналом MyBatisSQLSessionFactory. Должен быть экземпляр только один раз.

Для WAR, beans.xml должен находиться в WEB-INF. В противном случае извлеките бизнес-код в отдельную зависимость ejb.jar, все упакованные в EAR.

Я рекомендую активировать JTA Transactions: заполните beans.xml.

I @Inject @SessionFactory protected SqlSession session; в EJB, то в его методах: new DAO(session);, поскольку транзакция управляется на уровне EJB, а инъекция DAO, в которую вводится сессия, не работает должным образом.

Также аннотировать методы EJB @Transactional(executorType=ExecutorType.REUSE), когда имеется несколько выражений. Это будет использовать ту же связь; для всех операторов транзакции и готовить уникальные заявления только один раз. Сначала попробуйте, не разобравшись.

+0

выпущен mybatis-cdi-1.0.0;) – zappee

+0

классный! но никакая интеграция, предусмотренная для меня, бета, которую я использую долго, кажется достаточно стабильной для моих нужд. В любом случае, я дам ему тест. – blackwizard