Перш за все, з вашого опису не зрозуміло, що ви зробили, але вам потрібна PlaylistSongs
таблиця, яка містить a PlaylistId
і a SongId
, що описує, які пісні належать до яких списків відтворення.
Саме в цю таблицю потрібно додати інформацію про замовлення.
Мій улюблений механізм - з реальними числами. Я реалізував це нещодавно, і це спрацювало як шарм. Коли ви хочете перенести пісню на певну позицію, ви обчислюєте її нове Ordering
значення як середнє Ordering
значення попередньої пісні та наступної пісні. Якщо ви використовуєте 64-бітове реальне число, у вас вичерпається точність приблизно в той же час, коли пекло замерзне, але якщо ви справді пишете своє програмне забезпечення для нащадків, то подумайте про перепризначення приємних закруглених цілих Ordering
значень для всіх пісень у кожній пісні плейлист раз у раз
Як додатковий бонус, ось написаний я код, який реалізує це. Звичайно, ви не можете використовувати його таким, яким він є, і зараз було б надто багато для мене роботи, щоб його оздоровити, тому я лише розміщую його, щоб отримати ідеї.
Клас є ParameterTemplate
(як би там не було, не питайте!) Метод отримує список шаблонів параметрів, до яких цей шаблон належить від його батьківського ActivityTemplate
. (Що б там не було, не питай!) Код містить захист від неточності. Для тестування використовується дільник: тест блоку використовує великий дільник, щоб швидко втратити точність і, таким чином, запустити код захисту точності. Другий метод є загальнодоступним і "лише для внутрішнього використання; не викликати", щоб код тестування міг викликати його. (Це не могло бути приватним пакетом, тому що мій код тестування не в тому ж пакеті, що і код, який він тестує.) Поле, яке контролює замовлення, викликається Ordering
, отримується доступ через getOrdering()
і setOrdering()
. Ви не бачите жодного SQL, оскільки я використовую об'єктно-реляційне картографування через сплячий режим.
/**
* 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;
}