Прежде всего, из вашего описания того, что вы сделали, неясно, но вам нужна PlaylistSongs
таблица, которая содержит a PlaylistId
и a SongId
, описывающие, какие песни принадлежат каким плейлистам.
Именно в этой таблице вы должны добавить информацию для заказа.
Мой любимый механизм с реальными числами. Я реализовал это недавно, и это сработало как шарм. Когда вы хотите переместить песню в определенную позицию, вы вычисляете ее новое Ordering
значение как среднее значение Ordering
значений предыдущей и следующей песни. Если вы используете 64-битное действительное число, вы достигнете точности примерно в то же самое время, когда ад замерзнет, но если вы действительно пишете свое программное обеспечение для потомков, тогда подумайте о переназначении хороших округленных целочисленных Ordering
значений для всех песен в каждой плейлист время от времени.
В качестве дополнительного бонуса, вот код, который я написал, который реализует это. Конечно, вы не можете использовать его как есть, и для меня сейчас было бы слишком много работы по его дезинфекции для вас, поэтому я только публикую его, чтобы вы могли извлечь из него идеи.
Класс ParameterTemplate
(что угодно, не спрашивайте!) Метод получает список шаблонов параметров, к которым принадлежит этот шаблон, от его родителя ActivityTemplate
. (Как бы то ни было, не спрашивайте!) Код содержит некоторую защиту от нехватки точности. Делитель используется для тестирования: в модульном тесте используется большой делитель, чтобы быстро выйти за пределы точности и, таким образом, активировать защитный код точности. Второй метод является общедоступным и «только для внутреннего использования; не вызывать», чтобы тестовый код мог его вызывать. (Он не может быть закрытым для пакета, потому что мой тестовый код не находится в том же пакете, что и код, который он тестирует.) Поле, которое управляет порядком, вызывается Ordering
, вызывается через getOrdering()
и setOrdering()
. Вы не видите SQL, потому что я использую объектно-реляционное отображение через Hibernate.
/**
* 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;
}