Здравствуйте, anton_t, Вы писали:
_>Здравствуйте, swimmers, Вы писали:
S>>Здравствуйте, anton_t, Вы писали:
C>>>>А как же LINQ? C>>>>В JAVA есть аналог linq2db?
_>>>Есть https://www.jooq.org
S>>Вот так аналог, ты серьезно?
_>А что на linq можно сделать, чего нельзя на jooq?
1) композиция запросов
// в одном местеvar q1 =
from book in books
where book.Author.StartsWith("A")
select book;
// в другомvar q2 = date.HasValue ? q1.Where(b => b.Published > date.value) : q2.Where(b => b.Publishrd == null);
// в третьемvar q3 =
from b in q2 select new {
Title = b.Title,
Author = b.Author.Name
};
2) Мэппинг сразу в DTO
var q3 =
from b in q2 selectnew DtoClass {
Title = b.Title,
Author = b.Author.Name
};
3) derived table и вообще любые преобразования полей
from a in Authors
where a.Books.Count > 3
from b in a.Books
where b.Published.Year == DateTime.Now.Year
select b.Title;
from book in books
where book.Published.Year * book.Author.BirthDate.Year == x
select book;
4) self join
from b1 in books
join b2 in books on b1.Title equals b2.Title
select { Title1 = b1.Title, Title2 = b2.Title };
Аналог на LINQ. Скорость маппинга в обьект сравнима с ручной вычиткой из DataReader (или как там в жаве)
var query =
from b in db.Book
join a in db.Author on b.AuthorId equals a.Id
where b.PublishedIn == 1948
select new
{
b.Title,
a.FirstName,
a.LastName
}
Одинаковые по сути два запроса, только копмилятор вам не подскажет что вы в слекте используете левые поля.
Сколько не искал так и не нашел нормального примера декомпозиции запросов в JOOQ. Вот хочется еще иметь страну изданной книги
var booksWithAuthors =
from b in db.Book
join a in db.Author on b.AuthorId equals a.Id
select new
{
Book = b,
Author = a
}
// тот же самый запрос что и в первом примере но с использованием композицииvar query =
from ba in booksWithAuthors
select new
{
ba.Book.Title,
ba.Author.FirstName,
ba.Author.LastName
}
// переиспользовали запрос, меньше багов сделалиvar withCountries =
from ba in booksWithAuthors
join c in db.Counries on ba.Author.CountryId on c.CountryId
select new
{
ba.Book.Title,
ba.Book.PulishDate,
ba.Author.FirstName,
ba.Author.LastName,
CountryName = c.Name
}
Нагромождение запросов совсем не влияет на его качество, по крайней мере в linq2db. Но первый запрос мы можем переиспользовать в других запросах, джоинится на него, еще добавить фильтров.
Тоесть вместо того чтобы в базе данных создавать вьюшки, мы просто делаем строго типизированные LINQ запросы и переиспользуем их как хотим.
Теперь если нам надо количество записей этого дела. Да пожалуйста
withCountries.Count()
Отгрупировать, да проще некуда
var byCountry =
from bc in withCountries
group bc by bc.CountryName into g
select new
{
CountryName = g.Key
Count = g.Count(),
Maxdate = g.Max(p => p.PulishDate)
}
Предоставляет ли JOOQ такое? Я очень сильно сомневаюсь, и даже если сделали, компилятор вам валидацию точно не проведет.
Re[8]: Через год-два .NET Core потеснит Java на рынке enterprise решений
Все это есть, пусть менее элегантное и с меньшим контролем компилятора.
Все это можно найти здесь https://www.jooq.org/doc/3.14/manual/
Про 5й пункт не совсем понял, что ты хочешь сделать, но у меня сложилось впечатление, что ты как раз пытаешься обойти слишком строгий контроль компилятора.
SQL не статически типизированный, поэтому при генерации SQL-я в достаточно сложных случаях и возникает дилемма — либо контроль компилятора, либо гибкость.
Re[8]: Через год-два .NET Core потеснит Java на рынке enterprise решений
Здравствуйте, Danchik, Вы писали:
D>Сколько не искал так и не нашел нормального примера декомпозиции запросов в JOOQ. Вот хочется еще иметь страну изданной книги
Подсказка: это не хитровы хитромудрая нашлепка на синтаксис языка, как linq, это обычная цепочка функций. Вынеси часть этой цепочки в отдельную функцию и комбинируй как хочещь.
Re[9]: Через год-два .NET Core потеснит Java на рынке enterprise решений
Здравствуйте, anton_t, Вы писали:
_>Здравствуйте, gandjustas, Вы писали:
_>Все это есть, пусть менее элегантное и с меньшим контролем компилятора.
Нет.
_>Все это можно найти здесь https://www.jooq.org/doc/3.14/manual/
Бегло глянул, не нашел ничего похожего. Давай примеры.
_>Про 5й пункт не совсем понял, что ты хочешь сделать, но у меня сложилось впечатление, что ты как раз пытаешься обойти слишком строгий контроль компилятора.
Я пытаюсь сделать декомпозицию запросов в функции.
_>SQL не статически типизированный
Это неправда, SQL статически типизирован. Переменная в нем имеет тип во время компиляции и не меняет его в рантайм.
То что ты хочешь сказать называется "Java программирования не знает ничего о типах в SQL и почти все потуги на Java это просто обертка для склейки строк".
_>поэтому при генерации SQL-я в достаточно сложных случаях и возникает дилемма — либо контроль компилятора, либо гибкость.
В C# как раз этой дилеммы нет. C# генерирует и, самое главное, проверяет типы при "компиляции" запросов. Поэтому существует достаточно большое подмножество корректных (компилируемых) linq-запросов на C#, которые отображаются в корректный SQL. Нарушить эту корректность случайно довольно сложно.
Re[10]: Через год-два .NET Core потеснит Java на рынке enterprise решений
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, anton_t, Вы писали:
_>>Здравствуйте, gandjustas, Вы писали:
_>>Все это есть, пусть менее элегантное и с меньшим контролем компилятора. G>Нет.
_>>Все это можно найти здесь https://www.jooq.org/doc/3.14/manual/ G>Бегло глянул, не нашел ничего похожего. Давай примеры.
_>>Про 5й пункт не совсем понял, что ты хочешь сделать, но у меня сложилось впечатление, что ты как раз пытаешься обойти слишком строгий контроль компилятора. G>Я пытаюсь сделать декомпозицию запросов в функции.
Мне лень самому писать примеры. Вот есть небольшое описение https://www.jooq.org/doc/3.14/manual/sql-building/sql-statements/dsl-and-non-dsl/
В jooq автоматически встроено разбиение на функции. Потому что jooq — это не ad hoc нашлепка на язык, а набор функций, комбинируй их как хочешь.
И jooq это только один пример.
Не нравится jooq или hibernate — возьми другой широко используемый язык под JVM, например Scala, там есть Slick https://scala-slick.org/ , по сравнению с которым linq2db — детский лепет.
С такой альтернативой под .NET проблемы: есть другие языки кроме C# (и не к ночи будет упомянут VB.NET), но они — маргинальны.
Поэтому приходится есть что дают и нахваливать.
_>>SQL не статически типизированный G>Это неправда, SQL статически типизирован. Переменная в нем имеет тип во время компиляции и не меняет его в рантайм. G>То что ты хочешь сказать называется "Java программирования не знает ничего о типах в SQL и почти все потуги на Java это просто обертка для склейки строк".
Я бы не сказал, что jooq и JPA — это склейка строк. Не говоря уж про другие альтернативы под JVM.
_>>поэтому при генерации SQL-я в достаточно сложных случаях и возникает дилемма — либо контроль компилятора, либо гибкость. G>В C# как раз этой дилеммы нет. C# генерирует и, самое главное, проверяет типы при "компиляции" запросов. Поэтому существует достаточно большое подмножество корректных (компилируемых) linq-запросов на C#, которые отображаются в корректный SQL. Нарушить эту корректность случайно довольно сложно.
Та ки C# при работе с linq2db ничего не знает про типы в SQL, он значет про типы в модели данных, по которой собирает запрос. Так и hibernate умеет, это не rocket science.
Re[11]: Через год-два .NET Core потеснит Java на рынке enterprise решений
Здравствуйте, anton_t, Вы писали:
_>Не нравится jooq или hibernate — возьми другой широко используемый язык под JVM, например Scala, там есть Slick https://scala-slick.org/ , по сравнению с которым linq2db — детский лепет.
Откуда тебе знать-то, что из них детский лепет, если ты в глаза не видел l2db, а о том, что SQL статически типизирован узнал лишь вчера?
Re[11]: Через год-два .NET Core потеснит Java на рынке enterprise решений
Здравствуйте, anton_t, Вы писали:
_>Та ки C# при работе с linq2db ничего не знает про типы в SQL, он значет про типы в модели данных, по которой собирает запрос. Так и hibernate умеет, это не rocket science.
Вообще то знает. Например для EF есть куча атрибутов для полей БД. И в конце концов модель
Есть модель с типом Object но поля БД строго типизированы. При это объект опирается на 2 поля одно отвечающее за тип (int или byte[4]) второе за ссылку
ComplexType]
public class ЛюбаяСсылка_Fld52 : НеопределенныйТип, НеопределенныйТипСсылочный
{
[Column("_Fld52_TYPE")]
[Required]
[MaxLength(1)]
override public byte[] Тип { get; set; }
[Column("_Fld52_RTREF")]
[Required]
[MaxLength(4)]
public byte[] НомерТаблицы { get; set; }
[Column("_Fld52_RRREF")]
[Required]
[MaxLength(16)]
public byte[] Ссылка { get; set; }
}
[Column("_Fld52_TYPEF")] это название полей в БД.
То есть для неопределенных значений приходится извращаться. Что касается byte[] а не int или Guid то это 1С так захотели.
Если это тип ссылочный на другую таблицу, то строится отдельный запрс к таблице по значению в НомерТаблицы
и солнце б утром не вставало, когда бы не было меня
Re[12]: Через год-два .NET Core потеснит Java на рынке enterprise решений
Здравствуйте, Klikujiskaaan, Вы писали:
K>Здравствуйте, anton_t, Вы писали:
_>>Не нравится jooq или hibernate — возьми другой широко используемый язык под JVM, например Scala, там есть Slick https://scala-slick.org/ , по сравнению с которым linq2db — детский лепет.
K>Откуда тебе знать-то, что из них детский лепет, если ты в глаза не видел l2db, а о том, что SQL статически типизирован узнал лишь вчера?
А с чего ты взял, что я в глаза не видел linq2db? Я с BLToolkit еще в 2010 году работал. Так что телепат из тебя хреновый.
Про мои знания о SQL ты тоже в лужу пузыри пустил.
Соединение с БД появляется только после старта приложения, соответственно и данные с их типами — тоже. Так что типизация данных в хранилище данных для middle tier — динамическая.
Вот такой запрос:
select *
from SUPPLIERS
where SOME_ID='123'
Будет рабтать если SOME_ID — VARCHAR2(100) иди RAW(16), только план запроса будет разный.
Re[12]: Через год-два .NET Core потеснит Java на рынке enterprise решений
S>Здравствуйте, anton_t, Вы писали:
_>>Та ки C# при работе с linq2db ничего не знает про типы в SQL, он значет про типы в модели данных, по которой собирает запрос. Так и hibernate умеет, это не rocket science.
S>Вообще то знает. Например для EF есть куча атрибутов для полей БД. И в конце концов модель
S>На примере 1С S>https://infostart.ru/public/402038/
S>Есть модель с типом Object но поля БД строго типизированы. При это объект опирается на 2 поля одно отвечающее за тип (int или byte[4]) второе за ссылку
S>
S> ComplexType]
S> public class ЛюбаяСсылка_Fld52 : НеопределенныйТип, НеопределенныйТипСсылочный
S> {
S> [Column("_Fld52_TYPE")]
S> [Required]
S> [MaxLength(1)]
S> override public byte[] Тип { get; set; }
S> [Column("_Fld52_RTREF")]
S> [Required]
S> [MaxLength(4)]
S> public byte[] НомерТаблицы { get; set; }
S> [Column("_Fld52_RRREF")]
S> [Required]
S> [MaxLength(16)]
S> public byte[] Ссылка { get; set; }
S> }
S>
S>[Column("_Fld52_TYPEF")] это название полей в БД.
S>То есть для неопределенных значений приходится извращаться. Что касается byte[] а не int или Guid то это 1С так захотели.
S> Если это тип ссылочный на другую таблицу, то строится отдельный запрс к таблице по значению в НомерТаблицы
Я тут в мапинге не вижу информации о типах данных на стороне СУБД. Только типы данных в приложении, мапинг на столбцы и валидацию.
Re[13]: Через год-два .NET Core потеснит Java на рынке enterprise решений
Здравствуйте, Klikujiskaaan, Вы писали:
K>Здравствуйте, anton_t, Вы писали:
_>>А с чего ты взял, что я в глаза не видел linq2db? Я с BLToolkit еще в 2010 году работал.
K>Оно и видно
Как мы уже видели, телепат из тебя никудышный, так что опять, похоже, какая-то чушь видится.
Re[11]: Через год-два .NET Core потеснит Java на рынке enterprise решений
Здравствуйте, anton_t, Вы писали:
_>Мне лень самому писать примеры. Вот есть небольшое описение https://www.jooq.org/doc/3.14/manual/sql-building/sql-statements/dsl-and-non-dsl/ _>В jooq автоматически встроено разбиение на функции. Потому что jooq — это не ad hoc нашлепка на язык, а набор функций, комбинируй их как хочешь.
Заходим по ссылке и смотрим первый прмиер:
Result<Record> result =
create.select()
.from(AUTHOR.as("a"))
.join(BOOK.as("b")).on(a.ID.eq(b.AUTHOR_ID))
.where(a.YEAR_OF_BIRTH.gt(1920)
.and(a.FIRST_NAME.eq("Paulo")))
.orderBy(b.TITLE)
.fetch();
Вроде все красиво. Но что такое a и b (выделено жирным выше)?
Оказывается чтобы использовать a и b надо перед запросом еще написать:
// Declare your aliases before using them in SQL:
Author a = AUTHOR.as("a");
Book b = BOOK.as("b");
Я тут вижу сразу две проблемы:
1) Компилятор не контролирует что параметры функций .as("a") и .as("b") совпадают с именами переменных (выделено курсивом выше). Очень легко нависать компилируемый код, дающий некорректный SQL или поломать существующий
2) Я так понимаю что сделать алиасы для подзапросов и derived table не получится.
И эти проблемы концептуальные. Все (без исключения) подобные фреймворки обладают такими недостатками. Легко сделать компилируемый код, дающий некорректный SQL. Мощность такого языка запросов значительно ниже мощности SQL и самого ЯП.
_>И jooq это только один пример.
Такой же как и все остальные. За 13 лет с момента изобретения linq сколько пытались его превзойти — ни у кого не получилось.
_>Не нравится jooq или hibernate — возьми другой широко используемый язык под JVM, например Scala, там есть Slick https://scala-slick.org/ , по сравнению с которым linq2db — детский лепет.
Я в scala не силен, но судя по примерам кода, в scala есть цитирование. Это именно та языковая фича, которая позволяет сделать linq-подобные фреймворки. Именно этой фичи не хватает в Java чтобы родить нормальный DSL для запросов к базе.
_>>>SQL не статически типизированный G>>Это неправда, SQL статически типизирован. Переменная в нем имеет тип во время компиляции и не меняет его в рантайм. G>>То что ты хочешь сказать называется "Java программирования не знает ничего о типах в SQL и почти все потуги на Java это просто обертка для склейки строк".
_>Я бы не сказал, что jooq и JPA — это склейка строк. Не говоря уж про другие альтернативы под JVM.
jooq это именно склейка строк. Красиво завернутая, обмазанная типми, но все равно довольно тупая склейка строк. Я такое на делфи в 2001 делал. Да и современная Java недалеко от делфи образца 2001 года ушла.
_>>>поэтому при генерации SQL-я в достаточно сложных случаях и возникает дилемма — либо контроль компилятора, либо гибкость. G>>В C# как раз этой дилеммы нет. C# генерирует и, самое главное, проверяет типы при "компиляции" запросов. Поэтому существует достаточно большое подмножество корректных (компилируемых) linq-запросов на C#, которые отображаются в корректный SQL. Нарушить эту корректность случайно довольно сложно. _>Та ки C# при работе с linq2db ничего не знает про типы в SQL, он значет про типы в модели данных, по которой собирает запрос.
Именно. Проверка типов при компиляции программы на C# обеспечивает корректность генерируемого SQL. Читба такая проверка могла работать нужны дополнительные средства языка, которых нет в Java.
_>Так и hibernate умеет, это не rocket science.
Нет, не умеет. Крайне легко привести пример где C# не скомпилируется, а hibernate, jooq и все подобное скомпилируется, но выдаст некорректный запрос.
Re[13]: Через год-два .NET Core потеснит Java на рынке enter
Здравствуйте, anton_t, Вы писали:
_> Я тут в мапинге не вижу информации о типах данных на стороне СУБД. Только типы данных в приложении, мапинг на столбцы и валидацию.
Ну ты по ссылке ходил? Там же кроме мапинга имени столбцов еще и типы столбцов
S>Здравствуйте, anton_t, Вы писали:
_>> Я тут в мапинге не вижу информации о типах данных на стороне СУБД. Только типы данных в приложении, мапинг на столбцы и валидацию. S>Ну ты по ссылке ходил? Там же кроме мапинга имени столбцов еще и типы столбцов
S>[Column("_CODE",TypeName = "nvarchar")] S>По этой схеме при Code First генерятся базы S>https://infostart.ru/public/402038/
S>Там куча примеров
S>
S>public partial class ТабличнаяЧастьПредок
S> {
S> virtual public byte[] СсылкаID { get; set; }
S> [Key]
S> [Column("_KeyField", Order = 1)]
S> [MaxLength(4)]
S> publicbyte[] KeyField { get; set; }
S> virtual public int НомерСтроки { get; set; }
S> }
S>
S>
S>На основании этих предков можно уже создавать потомков
S>Я сделал несколько тестовых справочников со всевозможными типами.
S>Например
G>Здравствуйте, anton_t, Вы писали:
_>>Мне лень самому писать примеры. Вот есть небольшое описение https://www.jooq.org/doc/3.14/manual/sql-building/sql-statements/dsl-and-non-dsl/ _>>В jooq автоматически встроено разбиение на функции. Потому что jooq — это не ad hoc нашлепка на язык, а набор функций, комбинируй их как хочешь. G>Заходим по ссылке и смотрим первый прмиер: G>
G>Вроде все красиво. Но что такое a и b (выделено жирным выше)? G>Оказывается чтобы использовать a и b надо перед запросом еще написать: G>
G>// Declare your aliases before using them in SQL:
G>Author a = AUTHOR.as("a");
G>Book b = BOOK.as("b");
G>
G>Я тут вижу сразу две проблемы: G>1) Компилятор не контролирует что параметры функций .as("a") и .as("b") совпадают с именами переменных (выделено курсивом выше). Очень легко нависать компилируемый код, дающий некорректный SQL или поломать существующий G>2) Я так понимаю что сделать алиасы для подзапросов и derived table не получится.
G>И эти проблемы концептуальные. Все (без исключения) подобные фреймворки обладают такими недостатками. Легко сделать компилируемый код, дающий некорректный SQL. Мощность такого языка запросов значительно ниже мощности SQL и самого ЯП.
_>>И jooq это только один пример. G>Такой же как и все остальные. За 13 лет с момента изобретения linq сколько пытались его превзойти — ни у кого не получилось.
_>>Не нравится jooq или hibernate — возьми другой широко используемый язык под JVM, например Scala, там есть Slick https://scala-slick.org/ , по сравнению с которым linq2db — детский лепет. G>Я в scala не силен, но судя по примерам кода, в scala есть цитирование. Это именно та языковая фича, которая позволяет сделать linq-подобные фреймворки. Именно этой фичи не хватает в Java чтобы родить нормальный DSL для запросов к базе.
_>>>>SQL не статически типизированный G>>>Это неправда, SQL статически типизирован. Переменная в нем имеет тип во время компиляции и не меняет его в рантайм. G>>>То что ты хочешь сказать называется "Java программирования не знает ничего о типах в SQL и почти все потуги на Java это просто обертка для склейки строк".
_>>Я бы не сказал, что jooq и JPA — это склейка строк. Не говоря уж про другие альтернативы под JVM. G>jooq это именно склейка строк. Красиво завернутая, обмазанная типми, но все равно довольно тупая склейка строк. Я такое на делфи в 2001 делал. Да и современная Java недалеко от делфи образца 2001 года ушла.
_>>>>поэтому при генерации SQL-я в достаточно сложных случаях и возникает дилемма — либо контроль компилятора, либо гибкость. G>>>В C# как раз этой дилеммы нет. C# генерирует и, самое главное, проверяет типы при "компиляции" запросов. Поэтому существует достаточно большое подмножество корректных (компилируемых) linq-запросов на C#, которые отображаются в корректный SQL. Нарушить эту корректность случайно довольно сложно. _>>Та ки C# при работе с linq2db ничего не знает про типы в SQL, он значет про типы в модели данных, по которой собирает запрос. G>Именно. Проверка типов при компиляции программы на C# обеспечивает корректность генерируемого SQL. Читба такая проверка могла работать нужны дополнительные средства языка, которых нет в Java.
_>>Так и hibernate умеет, это не rocket science. G>Нет, не умеет. Крайне легко привести пример где C# не скомпилируется, а hibernate, jooq и все подобное скомпилируется, но выдаст некорректный запрос.
Jooq обеспечивает меньший контроль компилятора, чем Linq, ок, с этим никто не спорит.
Вот только если вернуться к началу дискусии: при наличии Jooq, Scala со Slick, Kotlin с Exposed — Linq вообще не является какой-то киллер фичей из-за которой все вдруг начнут переходить с JVM на .NET Core.
Re[15]: Через год-два .NET Core потеснит Java на рынке enter
S>>Типы БД nvarchar,nchar,ntext,numeric,DateTime,image
S>> Для описания Decimal для CodeFirst нужны еще приседания, но для BaseFirst и этого предостаточно. S>>https://stackoverflow.com/questions/3504660/decimal-precision-and-scale-in-ef-code-first _>[/cut] _>И каким образом эта информация используется компилятором, если не считать генерации DDL? _>Предположу, что никак.
Это информация нужна для
1. Генерации БД
2. Генерации запраса
смотри https://infostart.ru/public/402433/
единица.ШтрихКод.CompareTo("4") > 0
превращается
AND([Join1].[SP80] > N'4')
3. Для отображения результата запроса на классы
и солнце б утром не вставало, когда бы не было меня
Re[13]: Через год-два .NET Core потеснит Java на рынке enterprise решений
Здравствуйте, anton_t, Вы писали:
_>Jooq обеспечивает меньший контроль компилятора, чем Linq, ок, с этим никто не спорит.
Именно это и важно, иначе это тупой склейщик строк, порождающий еще больше проблем и усложнающий использование.
_>Вот только если вернуться к началу дискусии: при наличии Jooq, Scala со Slick, Kotlin с Exposed — Linq вообще не является какой-то киллер фичей из-за которой все вдруг начнут переходить с JVM на .NET Core.
Так мы начали обсуждать рантайм, а не язык. Интересный ход, я где-то пропустил ветвление.