Қандай артық заттар жасаудан қалай аулақ бола аламын?

Менің ағымдағы жобамда сұрауларға қосылған кестелерден кейбір өрістерді таңдап алатын бірнеше туынды сұрауды орындау керек, мысалы:

SELECT t1.col1, t2.col5
FROM t1
JOIN t2 ON t2.id = t1.t2_id

Мен оларды сыныптағыдай сақтауға тырыстым

class Result {
  String t1_col1;
  String t2_col5;
}

қолдану

Query q = entityManager.createNativeQuery( "THE SQL SELECT" , Result.class );

JPA енді «нəтиже» сыныптың «нәтижесі» объектіге бағандарды салыстыру үшін қажет болып табылмайтын субъект емес екеніне шағымданады. Сондай-ақ нәтиже класындағы @Column мәлімдемесін қайталауға тырыстым.

Менің сұрағым - бұл менің ДБ-дағы кестелер ретінде ұсынылған иелерді құрмай-ақ қалай жария ете аламын?

6

4 жауаптар

Өкінішке орай, оны JPA-да жасаудың бір жолы жоқ. Дегенмен, оны Query . оны пайдалану үшін:

org.hibernate.Query query = q.unwrap(org.hibernate.Query.class);

Сонда нәтиже трансформаторын орнатыңыз. Мында қараңыз :

query.setResultTransformer(Transformers.aliasToBean(Result.class));
6
қосылды
@downvoter - неге?
қосылды автор Bozho, көзі

Егер сіз SQL сұрауларын орындау үшін JPA/Hibernate қолданбасын пайдалансаңыз, сіз дұрыс емес құралды пайдаланасыз. Hibernate - ORM, және сіз кестелерді объектілерге салыстыруыңыз керек. Бұл JPA-ның барлық нүктесі. Мен тек SQL сұрауларын орындағыңыз келеді, мысалы, JDBC (және Spring's JdbcTemplate, мысалы)

Кестелер1 және 2-кесте бірліктерге бөлінгенде (осы T1 және T2 нысандарын шақырайық), бұл SQL сұрауларын қажет етпейді, өйткені JPQL тек кейбір нысандарды таңдауға қабілетті. Сұрауыңыз бұл сияқты болуы мүмкін (t1 және t2 арасындағы байланысқа байланысты):

select t1.col1, t2.col5 from T1 t1 join t1.t2 t2

Нәтижелеріңізді жасау үшін (бұл ДТҰ және карталанған нысан емес) нәтиже нәтижесін (Object ()) тізімінен қайталайтын боласыз.

List rows = (List) query.list(); List listOfResults = new ArrayList(rows.size); for (Object[] row : rows) { listOfResults.add(new Result((String) row[0], (String) row[1])); } 
5
қосылды
Бұл сұрақ қойған жоқ. Бұл өз кезегінде, табиғи сұрауды шешуді талап етті.
қосылды автор BillR, көзі
Сіз типтік ORM педантикалық жауап бердіңіз. Мен бұл ең жақсы жауап екенін білмеймін. Мен ОММ-ді көрмеймін және бәрін тоқтатады. Ол бұл мәселеге жауап бергісі келмейтін кез-келген адамды таба алмағандықтан, екінші рет жақсы жауап беруі керек еді. Менде бір сұрақ бар және ол жерде жауап берілмеді. Бұл жерде жауапты көргенді жақсы көрер еді. Айтпақшы, айналада миллиондаған ORM педантикалық бекеттер бар, олар бірдей нәрсені айтады. Мен мұздатқышты ішуден бас тартамын және менің ойымша, топтық ойлауды ғана емес, ең жақсы шешім деп ойлаймын. 5 жылдан кейін ORM = XML.
қосылды автор BillR, көзі
Өйткені, ол «ұйықтау» деп айтады және JPA сіз ORM-ні пайдаланатын барлық объектілерді салыстыруға тиіс дегенді білдірмейді. Адамдар тіптен сұранымдарды жасау үшін кибернетені қолданады. Егер 'ORM тек' жақсы болса, Hibernate Dev-лері «createSQLQuery» (ішкі сұраулардың JPA емес нұсқаларын) іске асыруға кедергі келтірер еді деп ойлайсыз ба? Тіпті ОРМ-ді қолданған кезде ғана олар антипаттерн болып табылады. Бірақ бәрі дөңгелек тесігі бар болса да, бір квадрат ORM плитасын қолданғысы келеді. Бұл туралы ойланыңыз, Кибернетика отандық сұрауларды қолдайды. Неліктен? ... Мәселен біреу мәселені өз отандық сұраумен қалай шешуді сұрағанда ... Міне, бәрін айтайын.
қосылды автор BillR, көзі
Ия, мен білемін, бірақ оны қорқынышты деп білемін. Ол рефакторинг жасауға мүмкіндік бермейді және тек екі немесе үш тривиальды кодты сақтайды. Плюс бұл отладки қиын етеді.
қосылды автор JB Nizet, көзі
Егер менің конструкторыма дәлел келтірсем, жоғарыдағы код компиляцияны тоқтатады және сұрауды түзетуге тура келетінін білемін. JPQL сұрауында жаңадан болған кезде, мен тек қана орындау уақытында алып кетемін. Егер конструктордағы аргументтердің тәртібін қоссам, IDE барлық шақыруларды ауыстырады. Бірақ жаңа JPQL-де болмаса. Егер менің сұрағым қате түрді қайтарса, кейбір «жасанды конструкторды» алып тастаудың орнына таза ClassCastException боламын. Ненің дұрыс емес екенін көру үшін сұраудың нәтижесін тексере аламын.
қосылды автор JB Nizet, көзі
@BillR: бірақ ОР жауапты қабылдады. Біреу бұрағышпен тырнақты қалай басқаруға болатындығын сұрағанда, ең жақсы жауап: бұлай істемеңіз, балға қолданыңыз.
қосылды автор JB Nizet, көзі
@BillR: Сұрақ JPA және Hibernate деп белгіленеді. JPA және Hibernate пайдалану үшін OP таңдады . Егер сіз ORM-лер жақсы деп ойласаңыз, онда JPA және Hibernate қолданбаңыз. ORM пайдалануды ештеңе мәжбүрлейді. Бірақ сіз ORM пайдалануды таңдасаңыз, оның ережелерін ойнауға тура келеді. Сізге ұнамайтын ОРМ-лер менің жауап дұрыс емес дегенді білдірмейді.
қосылды автор JB Nizet, көзі
Келісілді. Бір кішкентай (бірақ өте жақсы) функцияны қосу үшін: JPQL сұранысы бойынша жаңа операторды келесідей пайдалануға болады: SELECT NEW com.Result (t1.col1, t2.col5) FROM T1 t1 қосылуға t1t2 t2 Егер сізде Нәтиже (String, String) конструкторы, ол Интенттің өзі болудың қажеті жоқ жаңа Нәтиже нысаныңызды жасау үшін шақырылады.
қосылды автор Piotr Nowicki, көзі
Сіз «рефакторинг жасауға рұқсат бермейсіз» дегеніміз не? Егер параметрлерді немесе олардың түрлерін өзгертпесе, жаңа құрылғыны қолданбасаңыз немесе пайдаланбасаңыз, сізді сақтайды. Мен критерийлер API сияқты сауда-саттық мәселесі деп ойлаймын - бұл әлдеқайда рефакторингке ыңғайлы, бірақ жеке өзім үшін оқу қиын.
қосылды автор Piotr Nowicki, көзі
Жақсы ұпай, түсініктемелерге рахмет :-)
қосылды автор Piotr Nowicki, көзі

DataNucleus JPA-де осы сұранысты (аздап өзгерте отырып) іске қосуға болады және ол JPA спецификациясына сәйкес болуы керек.

SELECT t1.col1 AS t1_col1, t2.col5 AS t2_col5 FROM t1 JOIN t2 ON t2.id = t1.t2_id

яғни қайтару бағандарын нәтиже класындағы өріс атауларымен қатарластырыңыз. JPA спецификациясы нәтиже класы элементінің сыныбы болуы керек деп айтпайды; ол жай ғана «алынған даналардың (сынақтардың) сыныбы» дейді.

1
қосылды

Сұраулардан қажетті қосылатын бағандарды қайтаратын және dataholder сыныбының көрініс атауын пайдаланатын VIEW анықтауға алып кетуіңіз мүмкін.

0
қосылды