Хорошо, это начало длинной истории - сделано короткое «bort parsing командной строки в C ...
/**
* Helper function to parse the command line
* @param argc Argument Counter
* @param argv Argument Vector
* @param prog Program Instance Reference to fill with options
*/
bool parseCommandLine(int argc, char* argv[], DuplicateFileHardLinker* prog) {
bool pathAdded = false;
// iterate over all arguments...
for ( int i = 1; i<argc; i++ ) {
// is argv a command line option ?
if ( argv[i][0] == '-' || argv[i][0] == '/' ) {
// ~~~~~~ Optionally Cut that part vvvvvvvvvvvvv for sake of simplicity ~~~~~~~
// check for longer options
if ( stricmp( &argv[i][1], "NoFileName" ) == 0
|| strcmp( &argv[i][1], "q1" ) == 0 ) {
boNoFileNameLog = true;
} else if ( strcmp( &argv[i][1], "FuckNow?" ) == 0 ) {
logInfo( "SECRET FOUND: Well - wow I'm glad ya ask me.");
} else {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Now here comes the main thing:
//
// check for one char options
while ( char option = *++argv[i] ) {
switch ( option ) {
case '?':
// Show program usage
logInfo(L"Options:");
logInfo(L" /q\t>Quite mode");
logInfo(L" /v\t>Verbose mode");
logInfo(L" /d\t>Debug mode");
return false;
// Log options
case 'q':
setLogLevel(LOG_ERROR);
break;
case 'v':
setLogLevel(LOG_VERBOSE);
break;
case 'd':
setLogLevel(LOG_DEBUG);
break;
default:
logError(L"'%s' is an illegal command line option!"
" Use /? to see valid options!", option);
return false;
} // switch one-char-option
} //while one-char-options
} //else one vs longer options
} // if isArgAnOption
//
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ So that's it! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// What follows now is are some usefull extras...
//
else {
// the command line options seems to be a path...
WCHAR tmpPath[MAX_PATH_LENGTH];
mbstowcs(tmpPath, argv[i], sizeof(tmpPath));
// check if the path is existing!
//...
prog->addPath(tmpPath); //Comment or remove to get a working example
pathAdded = true;
}
}
// check for parameters
if ( !pathAdded ) {
logError("You need to specify at least one folder to process!\n"
"Use /? to see valid options!");
return false;
}
return true;
}
int main(int argc, char* argv[]) {
try {
// parse the command line
if ( !parseCommandLine(argc, argv, prog) ) {
return 1;
}
// I know that sample is just to show how the nicely parse commandline Arguments
// So Please excuse more nice useful C-glatter that follows now...
}
catch ( LPCWSTR err ) {
DWORD dwError = GetLastError();
if ( wcslen(err) > 0 ) {
if ( dwError != 0 ) {
logError(dwError, err);
}
else {
logError(err);
}
}
return 2;
}
}
#define LOG_ERROR 1
#define LOG_INFO 0
#define LOG_VERBOSE -1
#define LOG_DEBUG -2
/** Logging Level for the console output */
int logLevel = LOG_INFO;
void logError(LPCWSTR message, ...) {
va_list argp;
fwprintf(stderr, L"ERROR: ");
va_start(argp, message);
vfwprintf(stderr, message, argp);
va_end(argp);
fwprintf(stderr, L"\n");
}
void logInfo(LPCWSTR message, ...) {
if ( logLevel <= LOG_INFO ) {
va_list argp;
va_start(argp, message);
vwprintf(message, argp);
va_end(argp);
wprintf(L"\n");
}
}
Обратите внимание, что эта версия также поддерживает комбинирующие аргументы:« Вместо записи / h / s -> / hs также будет работать.
Извините за то, что вы публиковали n-й человек здесь, однако я не был доволен всеми автономными версиями, которые я видел здесь. Хорошо, что либцы прекрасны. Поэтому, я бы предпочел использовать parseer option libUCW, Arg или Getopt над самодельными.
Обратите внимание, что вы можете изменить:
*++argv[i]
-> (++argv*)[0]
более длинный, но загадочный, но все же cryptic.
Хорошо, давайте сломаем его: 1. argv [i] -> получить доступ к i-му элементу в поле указателя argv-char
Так приятно, что в C ## указатели «умерли» - долго живут указатели !!!
]Это поддерживается для JPQL-запросов JPA и объяснено как часть спецификации JPA .
Шаг 1: Объявите простой класс bean
blockquote>package com.path.to.class; public class SurveyAnswerStatistics { private String answer; private Long cnt; public SurveyAnswerStatistics(String answer, Long cnt) { this.answer = answer; this.count = cnt; } }
Шаг 2: Верните экземпляры bean-компонента из метода репозитория
blockquote>@Query("SELECT " + " new com.path.to.class.SurveyAnswerStatistics(v.answer, COUNT(v)) " + "FROM " + " Survey v " + "GROUP BY " + " v.answer") List<SurveyAnswerStatistics> findSurveyCount();
Важные замечания
- Обязательно укажите полный путь к классу bean с именем пакета. Например, если класс bean называется
MyBean
и он находится в пакетеcom.path.to
, то полный путь к компоненту будетcom.path.to.MyBean
. Просто предоставлениеMyBean
не будет работать (если только класс bean не находится в пакете по умолчанию).- Обязательно вызовите конструктор класса bean, используя ключевое слово
new
.SELECT new com.path.to.MyBean(...)
будет работать, тогда какSELECT com.path.to.MyBean
не будет.- Обязательно передавайте атрибуты точно в том же порядке, что и в конструкторе bean. Попытка передать атрибуты в другом порядке вызовет исключения.
- Убедитесь, что запрос является допустимым запросом JPA, то есть он не является родным запросом.
@Query("SELECT ...")
или@Query(value = "SELECT ...")
или@Query(value = "SELECT ...", nativeQuery = false)
, тогда как@Query(value = "SELECT ...", nativeQuery = true)
не будет работать. Это связано с тем, что исходные запросы передаются без изменений поставщику JPA и выполняются в соответствии с базовыми СУБД как таковыми. Посколькуnew
иcom.path.to.MyBean
не являются действительными ключевыми словами SQL, RDBMS затем генерирует исключение.
Решение для собственных запросов
Как отмечено выше, синтаксис
new ...
является JPA-поддерживаемым механизмом и работает со всеми поставщиками JPA. Однако, если сам запрос не является запросом JPA, то есть является нативным запросом, синтаксисnew ...
не будет работать, поскольку запрос передается непосредственно в базовую RDBMS, которая не понимает ключевое словоnew
поскольку он не является частью стандарта SQL.В подобных ситуациях классы bean-классов должны быть заменены интерфейсами Spring Data Projection .
Шаг 1: Объявить интерфейс проекции
blockquote>package com.path.to.interface; public interface SurveyAnswerStatistics { String getAnswer(); int getCnt(); }
Шаг 2: Возвратить проецируемые свойства из запроса
blockquote>@Query(nativeQuery = true, value = "SELECT " + " v.answer AS answer, COUNT(v) AS cnt " + "FROM " + " Survey v " + "GROUP BY " + " v.answer") List<SurveyAnswerStatistics> findSurveyCount();
Использовать SQL
AS
, чтобы отображать поля результатов в свойства проецирования для однозначного отображения.
Мне не нравятся имена типов java в строках запроса и обрабатывают его с помощью конкретного конструктора. Spring JPA неявно вызывает конструктор с результатом запроса в параметре HashMap:
@Getter
public class SurveyAnswerStatistics {
public static final String PROP_ANSWER = "answer";
public static final String PROP_CNT = "cnt";
private String answer;
private Long cnt;
public SurveyAnswerStatistics(HashMap<String, Object> values) {
this.answer = (String) values.get(PROP_ANSWER);
this.count = (Long) values.get(PROP_CNT);
}
}
@Query("SELECT v.answer as "+PROP_ANSWER+", count(v) as "+PROP_CNT+" FROM Survey v GROUP BY v.answer")
List<SurveyAnswerStatistics> findSurveyCount();
Этот список возврата SQL-запроса & lt; Object []> would.
Вы можете сделать это следующим образом:
@RestController
@RequestMapping("/survey")
public class SurveyController {
@Autowired
private SurveyRepository surveyRepository;
@RequestMapping(value = "/find", method = RequestMethod.GET)
public Map<Long,String> findSurvey(){
List<Object[]> result = surveyRepository.findSurveyCount();
Map<Long,String> map = null;
if(result != null && !result.isEmpty()){
map = new HashMap<Long,String>();
for (Object[] object : result) {
map.put(((Long)object[0]),object[1]);
}
}
return map;
}
}
Я знаю, что это старый вопрос, на который уже был дан ответ, но вот еще один подход:
@Query("select new map(count(v) as cnt, v.answer) from Survey v group by v.answer")
public List<?> findSurveyCount();
определяют пользовательский класс pojo, скажем sureveyQueryAnalytics, и сохраняют возвращаемое значение запроса в вашем пользовательском классе pojo
@Query(value = "select new com.xxx.xxx.class.SureveyQueryAnalytics(s.answer, count(sv)) from Survey s group by s.answer")
List<SureveyQueryAnalytics> calculateSurveyCount();
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate class [SurveyAnswerReport] [select new SurveyAnswerReport(v.answer,count(v.id)) from com.furniturepool.domain.Survey v group by v.answer] at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1750) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677) at org.hibernate.jpa.spi.AbstractEnti..........
– Pranav C Balan 31 March 2016 в 09:45SurveyAnswerReport
в вашем выходе. Я предполагаю, что вы заменилиSurveyAnswerStatistics
на свой собственный классSurveyAnswerReport
. Необходимо указать полное имя класса. – Bunti 31 March 2016 в 09:49com.domain.dto.SurveyAnswerReport
. – manish 31 March 2016 в 09:50JpaRepository
? Есть ли какая-то конфигурация, которую я пропустил? – marioosh 16 October 2017 в 09:12