Có thư viện trình tạo SQL động nào tốt trong Java không? [đóng cửa]


108

Bất cứ ai cũng biết một số thư viện trình tạo SQL tốt cho Java như Squiggle (có vẻ như không được duy trì nữa). Tốt hơn là một dự án đang phát triển tích cực.

Tốt hơn với cú pháp như Zend_Db_Select , một cái gì đó sẽ cho phép thực hiện một truy vấn như

String query = db.select().from('products').order('product_id');

Tôi có thể hỏi lợi ích của cú pháp trên so với "SELECT f1..fn FROM products ORDER BY product_id"?
Itay Moav -Malimovka

4
@ ItayMoav-Malimovka, Chà, ít nhất thì cú pháp của truy vấn SQL trong trường hợp của tôi (nếu chúng tôi lấy JOOQ làm ví dụ) được kiểm tra tại thời điểm bạn viết mã. Bạn có tính năng tự động hoàn thành cú pháp đầy đủ giúp tăng tốc độ viết truy vấn của bạn và làm cho nó dễ bị lỗi hơn.
Vladislav Rastrusny

Tôi đồng ý đây là điều mà IDE nên cải thiện.
Itay Moav -Malimovka

1
@ ItayMoav-Malimovka, tốt ... trong trường hợp của JOOQ, nếu tôi thay đổi điều gì đó trong cấu trúc DB của mình, mã của tôi sẽ chỉ dừng biên dịch cho đến khi tôi sửa nó theo cấu trúc DB mới. Nếu bạn có các truy vấn dưới dạng văn bản, chúng sẽ bị hỏng.
Vladislav Rastrusny

Ví dụ: Tôi hiện đang làm việc trên một ứng dụng cần tạo các câu lệnh để hoạt động trên một cơ sở dữ liệu kế thừa khổng lồ. Nhiều câu lệnh chia sẻ các ràng buộc tùy chỉnh mà chúng tôi xây dựng bởi SQL DSL. Nhờ đó chúng ta có thể dễ dàng tạo ra các câu lệnh chưa biết tại thời điểm biên dịch.
Rafael Winterhalter

Câu trả lời:


53

Querydsl jOOQ là hai lựa chọn phổ biến.


6
JOOQ có thể là một lựa chọn tốt hơn để phát triển SQL nặng, nhưng Querydsl có một API đơn giản hơn và cũng hỗ trợ các phụ trợ khác (JPA, JDO, Lucene, Mongodb, v.v.); Tôi cũng đang trong công ty đằng sau Querydsl
Timo Westkämper

Chúng tôi sử dụng Querydsl SQL trong một số dự án nội bộ của chúng tôi. Tôi không có kinh nghiệm cá nhân về jooq nhưng tôi nghe nói rằng nó khá ok.
ponzao

11
Vấn đề với QueryDsl là bạn không thể sử dụng nó như một trình tạo truy vấn thuần túy vì nó không cung cấp cho bạn chính truy vấn đã tạo. Nó sẽ tạo ra truy vấn và thực thi nó cho bạn. Bạn không thể có một cái mà không có cái khác.
Abhinav Sarkar

5
Querydsl và jOOQ có vẻ là những lựa chọn phổ biến và trưởng thành nhất, tuy nhiên có một điều cần lưu ý: Cả hai đều dựa trên khái niệm tạo mã, nơi các lớp meta được tạo cho các bảng và trường cơ sở dữ liệu. Điều này tạo điều kiện cho một DSL sạch đẹp nhưng nó gặp phải vấn đề khi cố gắng tạo các truy vấn cho cơ sở dữ liệu chỉ được biết đến trong thời gian chạy, như trong ví dụ của OP ở trên. Mặc dù jOOQ hỗ trợ phương pháp tiếp cận dựa trên Chuỗi nhưng có một số điều kỳ quặc. Tài liệu của Querydsl không đề cập đến việc có thể không sử dụng tạo mã hay không. Vui long sửa cho tôi nêu tôi sai.
Sven Jacobs

3
@SvenJacobs nhận xét rất cũ, nhưng để cập nhật, QueryDSL cho phép xây dựng sql mà không cần tạo mã: stackoverflow.com/questions/21615956/…
Nagaraj Tantri

7

ddlutils là lựa chọn tốt nhất của tôi: http://db.apache.org/ddlutils/api/org/apache/ddlutils/platform/SqlBuilder.html

đây là ví dụ tạo (groovy):

Platform platform  = PlatformFactory.createNewPlatformInstance("oracle");//db2,...
//create schema    
def db =        new Database();
def t = new Table(name:"t1",description:"XXX");
def col1 = new Column(primaryKey:true,name:"id",type:"bigint",required:true);
t.addColumn(col1);
t.addColumn(new Column(name:"c2",type:"DECIMAL",size:"8,2"));
t.addColumn( new Column(name:"c3",type:"varchar"));
t.addColumn(new Column(name:"c4",type:"TIMESTAMP",description:"date"));        
db.addTable(t);
println platform.getCreateModelSql(db, false, false)

//you can read Table Object from  platform.readModelFromDatabase(....)
def sqlbuilder = platform.getSqlBuilder();
println "insert:"+sqlbuilder.getInsertSql(t,["id":1,c2:3],false);
println "update:"+sqlbuilder.getUpdateSql(t,["id":1,c2:3],false);
println "delete:"+sqlbuilder.getDeleteSql(t,["id":1,c2:3],false);
//http://db.apache.org/ddlutils/database-support.html

1
Tôi phải xác định lại cột mặc dù tôi đã xác định chúng trong @Entity, rất đau.
huuthang

6

Tôi có thể giới thiệu jOOQ . Nó cung cấp rất nhiều tính năng tuyệt vời, cũng có một DSL trực quan cho SQL và một cách tiếp cận thiết kế ngược cực kỳ có thể tùy chỉnh.

jOOQ kết hợp hiệu quả SQL phức tạp, an toàn kiểu chữ, tạo mã nguồn, bản ghi hoạt động, thủ tục được lưu trữ, kiểu dữ liệu nâng cao và Java trong một DSL thông thạo, trực quan.


Bạn có dùng nó không? Làm thế nào để bạn tìm thấy nó?
Vladislav Rastrusny

3
Tôi sử dụng nó để tạo mã nguồn tùy chỉnh từ DDL. Nó hoạt động tuyệt vời!
Christopher Klewes

"Mặc dù thư viện jOOQ có một API tuyệt vời để xây dựng các câu lệnh SQL, nhưng nó đi kèm với toàn bộ bộ công cụ để xây dựng câu lệnh, kết nối với cơ sở dữ liệu, ghi / đọc mô hình vào / từ cơ sở dữ liệu, v.v. Do bản chất hiện tại của ứng dụng VM , giới hạn tham chiếu phương thức là 64k. jOOQ có thể chứa hơn 10.000 phương thức được tham chiếu khi được sử dụng. Điều này có vẻ không nhiều so với giới hạn, nhưng nếu bạn xem xét các thư viện lớn khác thường được sử dụng (chẳng hạn như Dịch vụ Guava và Google Play) , việc đạt đến giới hạn 64k đó trở nên dễ dàng hơn nhiều. " - android-arsenal.com/details/1/3202 :(
Tomáš Fejfar

3

Hibernate Criteria API (mặc dù không phải là SQL thuần túy, nhưng rất mạnh mẽ và đang được phát triển tích cực):

List sales = session.createCriteria(Sale.class)
         .add(Expression.ge("date",startDate);
         .add(Expression.le("date",endDate);
         .addOrder( Order.asc("date") )
         .setFirstResult(0)
         .setMaxResults(10)
         .list();

1
Vấn đề là nó không ánh xạ tới SQL như tôi hiểu, phải không?
Vladislav Rastrusny

7
điều này không tạo ra SQL và là một cơn ác mộng để gỡ lỗi khi nó không tuân theo các quy tắc của ít nhất sự ngạc nhiên (không làm việc như mong đợi)

Nó tạo ra SQL (ở cuối) và nó không làm ai ngạc nhiên. Lợi ích - nó có thể di động trên các cơ sở dữ liệu.
Vladimir Dyuzhev

3
Mức độ phức tạp của truy vấn mà bạn đạt được với API tiêu chí JPA mà không làm cho truy vấn hoàn toàn khó đọc là bao nhiêu? Bạn có ví dụ về một lựa chọn lồng nhau trong một mệnh đề IN/ EXISTShoặc một tự tham gia bằng cách sử dụng bí danh cho Salethực thể, v.v. không? Tôi tò mò
Lukas Eder

1
Nhận xét không có nhiều không gian để cung cấp các ví dụ, nhưng bạn có thể xem xét chúng tại docs.jboss.org/hibernate/core/3.5/reference/en/html/…
Vladimir

0

Bạn có thể sử dụng thư viện sau:

https://github.com/pnowy/NativeCriteria

Thư viện được xây dựng trên đầu Hibernate "create sql query" nên nó hỗ trợ tất cả các cơ sở dữ liệu được hỗ trợ bởi Hibernate (phiên Hibernate và các nhà cung cấp JPA được hỗ trợ). Mẫu trình tạo có sẵn, v.v. (trình ánh xạ đối tượng, trình lập bản đồ kết quả).

Bạn có thể tìm thấy các ví dụ trên trang github, tất nhiên là thư viện có sẵn ở trung tâm Maven.

NativeCriteria c = new NativeCriteria(new HibernateQueryProvider(hibernateSession), "table_name", "alias");
c.addJoin(NativeExps.innerJoin("table_name_to_join", "alias2", "alias.left_column", "alias2.right_column"));
c.setProjection(NativeExps.projection().addProjection(Lists.newArrayList("alias.table_column","alias2.table_column")));

điều này phức tạp hơn là chỉ viết SQL bằng tay
EpicPandaForce

@EpicPandaForce Tôi đồng ý vì các trường hợp rất đơn giản nhưng việc nối phức tạp hơn nhiều khi bạn cần nối chuỗi đó dựa trên các điều kiện rất phức tạp trong đó có một tập hợp các điều kiện này khác nhau. Sau đó, chuỗi được nối chính xác (như tất cả các chuỗi thêm, nối, có, đặt tham số, v.v.) là một vấn đề. Với giải pháp bạn có một người xây dựng sẽ giải quyết sự phức tạp này cho bạn.
Przemek Nowak
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.