Как получить содержимое столбца MySQL, хранящееся как mediumblob?

В проекте, который мне передали, есть база данных MySQL, которая используется для хранения большого количества данных. В каждой базе данных есть таблица, содержащая множество текстовых фрагментов (4 символа), организованных следующим образом:

id (long, increment), text (char (4)), count (varchar) и DATA (Mediumblob)

DATA хранит массив длинных слов как двоичный, но отображает его как загадочные символы, если я выбираю в таблице. Как получить содержимое столбца MySQL, хранящееся как mediumblob?

Я уже пробовал несколько команд CONVERT и CAST, но это никогда не дает чего-то, что я мог бы каким-то образом использовать. Мне нужен контент, который закодирован здесь, поэтому есть идеи, что я мог бы попробовать сделать?

Я проверил весь код Java, но не могу понять, как этот столбец вообще заполняется данными. Кажется, это чудо пакетов Hibernate. Последний фактический звонок, который я нашел, это

found.addSeq(seq.getId());

где найден экземпляр entity=table, а addSeq делает следующее:

public void addSeq(long id)
{
    ensure(seqsCount);
    seqs[seqsCount]=id;
    seqsCount++;
}

и обеспечить() это:

private void ensure(int minSize)
{
    if (seqs.length<=minSize)
    {
        long tmp[]=new long[minSize<20 ? minSize+5 : minSize+20];
        System.arraycopy(seqs, 0, tmp, 0, seqsCount);
        
        seqs=tmp;
    }
}

Единственные намеки на столбец DATA — это две эти функции, но они никогда и нигде не вызываются в коде. Любая идея, как это может работать?

@Column(name = "DATA", unique = false, nullable = false, length=8000000)
public byte[] getData()
{
    ByteBuffer b=ByteBuffer.allocate(seqsCount*8);
    for(int i=0; i<seqsCount; i++)
    {
        b.putLong(seqs[i]);
    }

    return b.array();
}

public void setData(byte[] data)
{
    seqs=new long[data.length/8];
    seqsCount=0;
    
    ByteBuffer b=ByteBuffer.wrap(data);
    while(b.hasRemaining())
    {
        ensure(seqsCount);
        seqs[seqsCount]=b.getLong();
        seqsCount++;
    }
}

Посмотрите, как он хранится, это может объяснить, что вам нужно сделать, чтобы вернуть его и сделать его пригодным для использования.

RiggsFolly 13.05.2022 17:14

Обычно вы можете получить столбец «ДАННЫЕ» как byte[]. После получения значения вы можете преобразовать его в ожидаемое значение, которое вам действительно нужно. Итак, вам нужно знать реальную кодировку/форматирование этого двоичного столбца.

SeanH 15.05.2022 07:07

@SeanH Спасибо за ваш ответ. Я обновил сообщение с некоторыми деталями кода

MIP 16.05.2022 16:42

Метод getData() вызывается Hibernate при сохранении в базу данных, а setData(byte[]) вызывается Hibernate при извлечении объекта из базы данных. setData(byte[]) затем декодирует данные большого двоичного объекта в поле seq. Код в setData(byte[]) — это то, как вы декодируете большой двоичный объект.

Mark Rotteveel 16.05.2022 22:28

@MarkRotteveel спасибо за объяснение, очень признателен

MIP 17.05.2022 10:31
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
33
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш код показывает, как «декодировать» DATA. found.getData() вернет двоичное содержимое данных текущего объекта: найдено. Затем вы можете вызвать аналогичную логику, чтобы показать или получить данные из данных byte[].

public List<long> fetchData(byte[] data)
{
    long res=new long[data.length/8];
    int k=0;
    ByteBuffer b=ByteBuffer.wrap(data);
    while(b.hasRemaining())
    {
        res[k++] = b.getLong();
    }
}

Используйте fetchData, а затем вы можете показать список длинных значений, как вы ожидаете.

Для справки, это означает, что большой двоичный объект хранит массив длинных чисел, закодированных как big-endian (8 байтов на длинный).

Mark Rotteveel 16.05.2022 22:26

Другие вопросы по теме