Oracle рекомендует добавить аннотацию @Path ко всем типам, которые будут вставляться при объединении JAX-RS с CDI: http://docs.oracle.com/javaee/7/tutorial/jaxrs-advanced004.htm Хотя это далеко не идеально (например, вы получите предупреждение от Джерси при запуске), я решил воспользоваться этим путем, что избавит меня от поддержки всех поддерживаемых типов в связующем.
Пример:
@Singleton
@Path("singleton-configuration-service")
public class ConfigurationService {
..
}
@Path("my-path")
class MyProvider {
@Inject ConfigurationService _configuration;
@GET
public Object get() {..}
}
На SQL Server MS 2005 и выше, ROW_NUMBER (), кажется, работает:
T-SQL: подкачка страниц с ROW_NUMBER ()
DECLARE @PageNum AS INT;
DECLARE @PageSize AS INT;
SET @PageNum = 2;
SET @PageSize = 10;
WITH OrdersRN AS
(
SELECT ROW_NUMBER() OVER(ORDER BY OrderDate, OrderID) AS RowNum
,OrderID
,OrderDate
,CustomerID
,EmployeeID
FROM dbo.Orders
)
SELECT *
FROM OrdersRN
WHERE RowNum BETWEEN (@PageNum - 1) * @PageSize + 1
AND @PageNum * @PageSize
ORDER BY OrderDate
,OrderID;
Я рекомендовал бы или использующий LINQ или попытался бы скопировать то, что он делает. У меня есть приложение, где я использую LINQ, Берут и методы Пропуска для получения разбитых на страницы данных. Код выглядит примерно так:
MyDataContext db = new MyDataContext();
var results = db.Products
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize);
Выполнение SQL Server Profiler показывает, что LINQ преобразовывает этот запрос в SQL, подобный:
SELECT [ProductId], [Name], [Cost], and so on...
FROM (
SELECT [ProductId], [Name], [Cost], [ROW_NUMBER]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [Name]) AS [ROW_NUMBER],
[ProductId], [Name], [Cost]
FROM [Products]
)
WHERE [ROW_NUMBER] BETWEEN 10 AND 20
)
ORDER BY [ROW_NUMBER]
Без обиняков:
1. Отфильтруйте свои строки и используйте функцию ROW_NUMBER для добавления номеров строк в порядке, который Вы хотите.
2. Фильтр (1) для возврата только номеров строк Вы хотите на своей странице.
3. Вид (2) номером строки, который совпадает с порядком, который Вы хотели (в этом случае, по имени).
Решение Oracle:
select * from (
select a.*, rownum rnum from (
YOUR_QUERY_GOES_HERE -- including the order by
) a
where rownum <= MAX_ROW
) where rnum >= MIN_ROW
LINQ, объединенный с лямбда-выражениями и анонимными классами в.Net 3.5 чрезвычайно, упрощает этот вид вещи.
Запросы базы данных:
var customers = from c in db.customers
join p in db.purchases on c.CustomerID equals p.CustomerID
where p.purchases > 5
select c;
Количество записей на страницу:
customers = customers.Skip(pageNum * pageSize).Take(pageSize);
Сортировка по любому столбцу:
customers = customers.OrderBy(c => c.LastName);
Получение только выбранных полей с сервера:
var customers = from c in db.customers
join p in db.purchases on c.CustomerID equals p.CustomerID
where p.purchases > 5
select new
{
CustomerID = c.CustomerID,
FirstName = c.FirstName,
LastName = c.LastName
};
Это создает анонимный класс со статическим контролем типов, в котором можно получить доступ к его свойствам:
var firstCustomer = customer.First();
int id = firstCustomer.CustomerID;
Результаты запросов лениво загружаются по умолчанию, таким образом, Вы не говорите с базой данных, пока Вам на самом деле не нужны данные. LINQ в .NET также значительно упрощает обновления путем хранения datacontext любых изменений, которые Вы внесли, и только обновление полей, которые Вы изменяете.
Существует дискуссия об этом Здесь
Техника получает номер страницы 100,000 от 150 000 баз данных строки в 78 мс
Используя знание оптимизатора и НАБОР ROWCOUNT, первый EmployeeID на странице, которую требуют, хранится в локальной переменной для начальной точки. Затем, ROWCOUNT НАБОРА к максимальному количеству записей, которое требуют в @maximumRows. Это позволяет подкачке страниц набор результатов намного более эффективным способом. Используя этот метод также использует в своих интересах существующие ранее индексы на таблице, поскольку это переходит непосредственно к базовой таблице а не к локально составленной таблице.
Я боюсь, что не могу судить, лучше ли это, чем текущий принятый ответ.
Существует несколько решений, которые я использую с MS SQL 2005.
Один из них является ROW_NUMBER (). Но, лично, мне не нравится ROW_NUMBER (), потому что он не работает на большие результаты (DB, который я продолжаю работать, является действительно большим - данные на более чем 1 ТБ рабочие тысячи запросов во втором - Вы знаете - большой сайт социальной сети).
Вот мое любимое решение.
Я буду использовать вид псевдо кода T-SQL.
Давайте найдем 2-ю страницу пользователей отсортированной по имени, фамилии, где каждая страница имеет 10 записей.
@page = 2 -- input parameter
@size = 10 -- can be optional input parameter
if @page < 1 then begin
@page = 1 -- check page number
end
@start = (@page-1) * @size + 1 -- @page starts at record no @start
-- find the beginning of page @page
SELECT TOP (@start)
@forename = forename,
@surname = surname
@id = id
FROM
users
ORDER BY
forename,
surname,
id -- to keep correct order in case of have two John Smith.
-- select @size records starting from @start
SELECT TOP (@size)
id,
forename,
surname
FROM
users
WHERE
(forename = @forename and surname = @surname and id >= @id) -- the same name and surname, but bigger id
OR (forename = @forename and surname > @surname) -- the same name, but bigger surname, id doesn't matter
OR (forename > @forename) -- bigger forename, the rest doesn't matter
ORDER BY
forename,
surname,
id
На самом деле LINQ имеет Пропуск, и Возьмите методы, которые могут быть объединены для выбора, какие записи выбираются.
Проверьте их.