Хочу звернути вашу увагу на EclipseLink, який пішов від ораклівського TopLink і сьогодні являє більш ніж підтримку персістенсу через JPA, але також JAXB, JCA та SDO (простими словами - можна працювати з XML, веб-сервісами чи но-скл базами). Але я сфокусуюся саме на ORM стороні цього рішення, і без дискутування чому ORM це погано і треба обережно совати його до свого проекту:)
Пропоную розглянути, як EclipseLink може допомогти, якщо на проекті Оракл СКБД
Отже, більшість знайомі з Хібернейтом, або з JPA in general. Хочу поділитися своїм досвідом використання EclipseLink, після інтенсивної роботи з Hibernate.
Перший плюс EclipseLink - це етелонна реалізація JPA (хоча це привносить і свої мінуси). Другий, і найбільш вагомий плюс - велика кількість Оракл-орієнтед плюшек, про які піде нижче - отже, якщо на вашому проекті Оракл і ви не плануєте підтримути якісь інші СКБД, то вам прямий шлях до використання EclipseLink, а не Хібернейт. І по-третє, статус з багами в кожному з проектів (as for July 26, 2011):
Name - Number of bugs - Number of blockers - The oldest blocker
Hibernate - 156 - 49 - 29/Sep/2006
EclipseLink - 15 - 3 - 04/Jun/2010
(!) Перед використанням слід обов"язково ознайомитися з інструкцією по використання, бо на вас чекатимуть різноманітні підводні камені. Один з найбільш підступних - це кеш другого рівня, який по замовчуваню увімкнений (це WeakHashMap)
Ну а тепер про обіцяні плюшки для Ораклу:
1) EclipseLink вміє вписувати хінти до кверів,
коли під"єднаний до Оракла, а також має АПІ який дозволяє вам самостійно додавати хінти: наприклад, з банально
Query query = em.createQuery("SELECT e FROM Employee e ORDER BY e.lastName ASC, e.firstName ASC"); query.setFirstResult(5); query.setMaxResults(5); List<Employee> emps = query.getResultList();
SELECT * FROM (SELECT /*+ FIRST_ROWS */ a.*, ROWNUM rnum FROM ( SELECT t0.EMP_ID AS EMP_ID1, t1.EMP_ID AS EMP_ID2, t0.F_NAME AS F_NAME3, t0.L_NAME AS L_NAME4, t0.START_TIME AS START_TIME5, t0.END_TIME AS END_TIME6, t0.GENDER AS GENDER7, t1.SALARY AS SALARY8, t0.VERSION AS VERSION9, t0.START_DATE AS START_DATE10, t0.END_DATE AS END_DATE11, t0.MANAGER_ID AS MANAGER_ID12, t0.ADDR_ID AS ADDR_ID13 FROM EMPLOYEE t0, SALARY t1 WHERE (t1.EMP_ID = t0.EMP_ID) ORDER BY t0.L_NAME ASC, t0.F_NAME ASC) a WHERE ROWNUM <= ?) WHERE rnum > ? bind => [10, 5]
2) Підтримка ієрархічних запитів оракла
Не певен щодо перекладу, мова йде про Hierarchical Queries http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm
ReadAllQuery raq = new ReadAllQuery(Employee.class); // Specifies a START WITH expression Expression startExpr = expressionBuilder.get("id").equal(new Integer(1)); // Specifies a CONNECT BY expression Expression connectBy = expressionBuilder.get("managedEmployees"); // Specifies an ORDER SIBLINGS BY vector Vector order = new Vector(); order.addElement(expressionBuilder.get("lastName")); order.addElement(expressionBuilder.get("firstName")); raq.setHierarchicalQueryClause(startExpr, connectBy, order); Vector employees = uow.executeQuery(raq);
SELECT * FROM EMPLOYEE START WITH ID=1 CONNECT BY PRIOR ID=MANAGER_ID ORDER SIBLINGS BY LAST_NAME, FIRST_NAME
3) Підтримка Oracle Flashback Transaction Query
Ніколи не використовував цей функціонал, і чесно кажу навіть не уявляю, кому він може стати в нагоді (хто знає - поділіться досвідом)
4) Альтернативний спосіб викликати stored procedures, відміний від Хібернейтівського
Тобто, в хібернейті сторед процедуру можна описати, наприклад в hbm.xml чи jpa @NamedStoredProcedureQuery тоді як на додачу до JPA-way, EclipseLink підтримує ще й StoredFunctionCall клас для динамічного формування виклику до деякої сторед процедури, а-ля:
StoredFunctionCall functionCall = new StoredFunctionCall(); functionCall.setProcedureName("CHECK_VALID_EMPLOYEE"); functionCall.addNamedArgument("EMP_ID"); functionCall.setResult("FUNCTION_RESULT", String.class); ValueReadQuery query = new ValueReadQuery(); query.setCall(functionCall); query.addArgument("EMP_ID"); List args = new ArrayList(); args.addElement(new Integer(44)); String valid = (String) session.executeQuery(query, args);
Ще одна корисна штукенція, наче підтримується для всіх СКБД, це АПІ для "репортинг запитів". Тобто, якщо вам треба заюзати в коді AVG, SUM і тд, то не треба писати SQL (чи інші його варіації) - можно просто використати ReportQuery, який дозволяє побудувати таку кверю через маніпулювання методами
ReportQuery query = new ReportQuery(Employee.class, emp); query.addMaximum("max-salary", emp.get("salary")); query.addAverage("average-salary", emp.get("salary")); query.addAttribute("city", emp.get("address").get("city"));
Роблячи вибір, слід пам"ятатти що Хібернейт має власні специфічні плюшки, і слід зважити який функціонал вам буде більш потрібний
Немає коментарів:
Дописати коментар