Po pierwsze, z opisu tego, co zrobiłeś, nie wynika jasno, ale potrzebujesz PlaylistSongs
tabeli zawierającej PlaylistId
ai SongId
opisującej, które utwory należą do poszczególnych list odtwarzania.
To w tej tabeli musisz dodać informacje o zamówieniu.
Moim ulubionym mechanizmem są liczby rzeczywiste. Ostatnio go wdrożyłem i działało to jak urok. Gdy chcesz przenieść utwór do określonej pozycji, obliczasz jego nową Ordering
wartość jako średnią Ordering
wartości z poprzedniego utworu i następnego utworu. Jeśli użyjesz 64-bitowej liczby rzeczywistej, zabraknie ci precyzji w tym samym czasie, w którym piekło zamarznie, ale jeśli naprawdę piszesz swoje oprogramowanie dla potomnych, rozważ ponowne przypisanie ładnych zaokrąglonych liczb całkowitych Ordering
do wszystkich utworów w każdym lista odtwarzania co jakiś czas.
Jako dodatkowy bonus, oto kod, który napisałem, który to implementuje. Oczywiście nie możesz go używać w obecnym stanie, a teraz byłoby dla mnie zbyt dużo pracy, aby go odkażać dla ciebie, więc zamieszczam go tylko po to, aby czerpać z niego pomysły.
Klasą jest ParameterTemplate
(cokolwiek, nie pytaj!) Metoda pobiera listę szablonów parametrów, do których ten szablon należy od swojego rodzica ActivityTemplate
. (Cokolwiek, nie pytaj!) Kod zawiera pewną ochronę przed brakiem precyzji. Dzielnik służy do testowania: test jednostkowy wykorzystuje duży dzielnik, aby szybko zabrakło precyzji, a tym samym wywołać precyzyjny kod zabezpieczający. Druga metoda jest publiczna i „wyłącznie do użytku wewnętrznego; nie wywołuje”, aby kod testowy mógł ją wywołać. (Nie może to być pakiet prywatny), ponieważ mój kod testowy nie znajduje się w tym samym pakiecie co kod, który testuje.) Pole kontrolujące kolejność jest wywoływane Ordering
, dostępne za pośrednictwem getOrdering()
i setOrdering()
. Nie widzisz żadnego SQL, ponieważ używam mapowania obiektowo-relacyjnego przez Hibernację.
/**
* Moves this {@link ParameterTemplate} to the given index in the list of {@link ParameterTemplate}s of the parent {@link ActivityTemplate}.
*
* The index must be greater than or equal to zero, and less than or equal to the number of entries in the list. Specifying an index of zero will move this item to the top of
* the list. Specifying an index which is equal to the number of entries will move this item to the end of the list. Any other index will move this item to the position
* specified, also moving other items in the list as necessary. The given index cannot be equal to the current index of the item, nor can it be equal to the current index plus
* one. If the given index is below the current index of the item, then the item will be moved so that its new index will be equal to the given index. If the given index is
* above the current index, then the new index of the item will be the given index minus one.
*
* NOTE: this method flushes the persistor and refreshes the parent node so as to guarantee that the changes will be immediately visible in the list of {@link
* ParameterTemplate}s of the parent {@link ActivityTemplate}.
*
* @param toIndex the desired new index of this {@link ParameterTemplate} in the list of {@link ParameterTemplate}s of the parent {@link ActivityTemplate}.
*/
public void moveAt( int toIndex )
{
moveAt( toIndex, 2.0 );
}
/**
* For internal use only; do not invoke.
*/
public boolean moveAt( int toIndex, double divisor )
{
MutableList<ParameterTemplate<?>> parameterTemplates = getLogicDomain().getMutableCollections().newArrayList();
parameterTemplates.addAll( getParentActivityTemplate().getParameterTemplates() );
assert parameterTemplates.getLength() >= 1; //guaranteed since at the very least, this parameter template must be in the list.
int fromIndex = parameterTemplates.indexOf( this );
assert 0 <= toIndex;
assert toIndex <= parameterTemplates.getLength();
assert 0 <= fromIndex;
assert fromIndex < parameterTemplates.getLength();
assert fromIndex != toIndex;
assert fromIndex != toIndex - 1;
double order;
if( toIndex == 0 )
{
order = parameterTemplates.fetchFirstElement().getOrdering() - 1.0;
}
else if( toIndex == parameterTemplates.getLength() )
{
order = parameterTemplates.fetchLastElement().getOrdering() + 1.0;
}
else
{
double prevOrder = parameterTemplates.get( toIndex - 1 ).getOrdering();
parameterTemplates.moveAt( fromIndex, toIndex );
double nextOrder = parameterTemplates.get( toIndex + (toIndex > fromIndex ? 0 : 1) ).getOrdering();
assert prevOrder <= nextOrder;
order = (prevOrder + nextOrder) / divisor;
if( order <= prevOrder || order >= nextOrder ) //if the accuracy of the double has been exceeded
{
parameterTemplates.clear();
parameterTemplates.addAll( getParentActivityTemplate().getParameterTemplates() );
for( int i = 0; i < parameterTemplates.getLength(); i++ )
parameterTemplates.get( i ).setOrdering( i * 1.0 );
rocs3dDomain.getPersistor().flush();
rocs3dDomain.getPersistor().refresh( getParentActivityTemplate() );
moveAt( toIndex );
return true;
}
}
setOrdering( order );
rocs3dDomain.getPersistor().flush();
rocs3dDomain.getPersistor().refresh( getParentActivityTemplate() );
assert getParentActivityTemplate().getParameterTemplates().indexOf( this ) == (toIndex > fromIndex ? toIndex - 1 : toIndex);
return false;
}