我正在使用spring
和CrudRepository
来进行数据库连接。
现在我需要一个很长(几行)的SQL查询,我更喜欢在类路径中的文件中维护,而不是直接在代码中。
但我怎么能做到这一点? 我的回购如下:
@Query(value = "<my very long sql query>", nativeQuery = true) //how to inject file content?
@Modifying
@Transactional
public void executeSpecificSql();
答案 0 :(得分:4)
使用以下步骤。
答案 1 :(得分:2)
如果您的项目设置了资源文件夹,请在// based on stock MidasLib unit
unit MidasDLL;
interface
implementation
uses Winapi.Windows, Winapi.ActiveX, Datasnap.DSIntf, SysUtils, Registry;
// function DllGetDataSnapClassObject(const CLSID, IID: TGUID; var Obj): HResult; stdcall; external 'Midas.DLL';
//var DllGetDataSnapClassObject: function(const CLSID, IID: TGUID; var Obj): HResult; stdcall; //external 'Midas.DLL';
var DllGetDataSnapClassObject: pointer; //external 'Midas.DLL';
const dllFN = 'Midas.DLL'; dllSubN = 'DllGetDataSnapClassObject';
var DllHandle: HMODULE = 0;
function RegisteredMidasPath: TFileName;
const rpath = '\SOFTWARE\Classes\CLSID\{9E8D2FA1-591C-11D0-BF52-0020AF32BD64}\InProcServer32';
var rry: TRegistry;
begin
Result := '';
rry := TRegistry.Create( KEY_READ );
try
rry.RootKey := HKEY_LOCAL_MACHINE;
if rry.OpenKeyReadOnly( rpath ) then begin
Result := rry.ReadString('');
if not FileExists( Result ) then
Result := '';
end;
finally
rry.Destroy;
end;
end;
procedure TryFindMidas;
var fPath, msg: string;
function TryOne(const fName: TFileName): boolean;
const ver_16_0 = 1048576; // $00060001
var ver: Cardinal; ver2w: LongRec absolute ver;
begin
Result := false;
ver := GetFileVersion( fName );
if LongInt(ver)+1 = 0 then exit; // -1 --> not found
if ver < ver_16_0 then begin
msg := msg + #13#10 +
'Obsolete version found: '+IntToStr(ver2w.Hi) + '.' + IntToStr(ver2w.Lo) + ' in library file ' + fName;
exit;
end;
DllHandle := SafeLoadLibrary(fName);
if DllHandle = 0 then begin
msg := msg + #13#10 +
'Failure loading library ' + fName + '. Maybe this was Win64 DLL or some other reason.';
exit;
end;
DllGetDataSnapClassObject := GetProcAddress( DllHandle, dllSubN);
if nil = DllGetDataSnapClassObject then begin // не найдена
msg := msg + #13#10 +
'Incompatible library loaded ' + fName + '. Missed function ' + dllSubN;
FreeLibrary( DllHandle );
DllHandle := 0;
end;
Result := true;
end;
function TryTwo(const fName: TFileName): boolean; // seek in the given folder and its immediate parent
begin
Result := TryOne(fName + dllFN);
if not Result then
Result := TryOne(fName + '..\' + dllFN); //
end;
begin
fPath := ExtractFilePath( ParamStr(0) );
if TryTwo( fPath ) then exit;
fPath := IncludeTrailingBackslash( GetCurrentDir() );
if TryTwo( fPath ) then exit;
fPath := RegisteredMidasPath;
if fPath > '' then
if TryOne( fPath ) then exit;
msg := 'This program needs the library ' + dllFN + ' version 16.0 or above.'#13#10 +
'It was not found, thus the program can not work.'#13#10 + #13#10 + msg;
Winapi.Windows.MessageBox(0, PChar(msg), 'Launch failure!',
MB_ICONSTOP or MB_TASKMODAL or MB_DEFAULT_DESKTOP_ONLY or MB_TOPMOST );
Halt(1);
end;
initialization
// RegisterMidasLib(@DllGetDataSnapClassObject); -- static linking does not work for utilities in sub-folders
TryFindMidas; // immediately terminates the application if not found
RegisterMidasLib(DllGetDataSnapClassObject);
finalization
if DllHandle <> 0 then
if FreeLibrary( DllHandle ) then
DllHandle := 0;
end.
文件下创建,并将键值对添加为/META-INF/jpa-named-queries.properties
。 Spring数据将会上升。
对于较长时间的查询,最好使用带有repoClass.methodName=yoursql
标记的xml
属性文件:https://stackoverflow.com/a/19128259/1194415
答案 2 :(得分:1)
不确定它是否适合您的设置,但是,这可以通过以下方式完成:
1)使用<sql-query>
标记
<sql-query name="MyQuery">.......
2)使用<mapping>
标记
<mapping resource="MyQuery.sql.xml"/>
3)使用指向上述配置文件的属性"hibernate.ejb.cfgfile"
定义持久性文件
<property name="hibernate.ejb.cfgfile" value="hibernate.cfg.xml"/>
4)使用上面的属性文件来构建EntityManagerFactory
现在,上面的Query可以在Repository方法中使用:
@Query(name = "MyQuery", nativeQuery = true)
[return type] executeMyQuery();