Самый чистый способ построить строку SQL в Java - PullRequest
95 голосов
/ 16 декабря 2008

Я хочу создать строку SQL для выполнения манипуляций с базой данных (обновления, удаления, вставки, выбора и тому подобное) - вместо ужасного метода concat для строк, использующего миллионы "+" и кавычек, которые невозможно прочитать при лучше всего - должен быть лучший способ.

Я задумывался об использовании MessageFormat - но он должен использоваться для пользовательских сообщений, хотя я думаю, что он будет работать разумно - но я думаю, что должно быть что-то более согласованное с операциями типов SQL в библиотеках java sql.

Будет ли Groovy хорошим?

Ответы [ 14 ]

67 голосов
/ 16 декабря 2008

Прежде всего рассмотрите возможность использования параметров запроса в подготовленных выражениях:

PreparedStatement stm = c.prepareStatement("UPDATE user_table SET name=? WHERE id=?");
stm.setString(1, "the name");
stm.setInt(2, 345);
stm.executeUpdate();

Другое, что можно сделать, это сохранить все запросы в файле свойств. Например В файле query.properties можно разместить указанный выше запрос:

update_query=UPDATE user_table SET name=? WHERE id=?

Затем с помощью простого служебного класса:

public class Queries {

    private static final String propFileName = "queries.properties";
    private static Properties props;

    public static Properties getQueries() throws SQLException {
        InputStream is = 
            Queries.class.getResourceAsStream("/" + propFileName);
        if (is == null){
            throw new SQLException("Unable to load property file: " + propFileName);
        }
        //singleton
        if(props == null){
            props = new Properties();
            try {
                props.load(is);
            } catch (IOException e) {
                throw new SQLException("Unable to load property file: " + propFileName + "\n" + e.getMessage());
            }           
        }
        return props;
    }

    public static String getQuery(String query) throws SQLException{
        return getQueries().getProperty(query);
    }

}

Вы можете использовать свои запросы следующим образом:

PreparedStatement stm = c.prepareStatement(Queries.getQuery("update_query"));

Это довольно простое решение, но хорошо работает.

58 голосов
/ 09 августа 2011

Для произвольного SQL используйте jOOQ . В настоящее время jOOQ поддерживает SELECT, INSERT, UPDATE, DELETE, TRUNCATE и MERGE. Вы можете создать SQL следующим образом:

String sql1 = DSL.using(SQLDialect.MYSQL)  
                 .select(A, B, C)
                 .from(MY_TABLE)
                 .where(A.equal(5))
                 .and(B.greaterThan(8))
                 .getSQL();

String sql2 = DSL.using(SQLDialect.MYSQL)  
                 .insertInto(MY_TABLE)
                 .values(A, 1)
                 .values(B, 2)
                 .getSQL();

String sql3 = DSL.using(SQLDialect.MYSQL)  
                 .update(MY_TABLE)
                 .set(A, 1)
                 .set(B, 2)
                 .where(C.greaterThan(5))
                 .getSQL();

Вместо того, чтобы получить строку SQL, вы также можете просто выполнить ее, используя jOOQ. См

http://www.jooq.org

(Отказ от ответственности: я работаю в компании за jOOQ)

14 голосов
/ 16 декабря 2008

Одна технология, которую вы должны рассмотреть, это SQLJ - способ встраивания операторов SQL непосредственно в Java. В качестве простого примера в файле TestQueries.sqlj может быть указано следующее:

public class TestQueries
{
    public String getUsername(int id)
    {
        String username;
        #sql
        {
            select username into :username
            from users
            where pkey = :id
        };
        return username;
    }
}

Существует дополнительный шаг прекомпиляции, который берет ваши файлы .sqlj и переводит их в чистую Java - короче говоря, он ищет специальные блоки, разделенные

#sql
{
    ...
}

и превращает их в вызовы JDBC. Есть несколько ключевых преимуществ использования SQLJ:

  • полностью абстрагирует слой JDBC - программистам нужно думать только о Java и SQL
  • может быть сделан переводчик для проверки ваших запросов на синтаксис и т. Д. По базе данных во время компиляции
  • возможность напрямую связывать переменные Java в запросах с использованием префикса ":"

Существуют реализации переводчика для большинства основных поставщиков баз данных, поэтому вы сможете легко найти все, что вам нужно.

12 голосов
/ 16 декабря 2008

Мне интересно, если вы ищете что-то вроде Squiggle . Также очень полезно jDBI . Это не поможет вам с запросами.

9 голосов
/ 16 декабря 2008

Я бы посмотрел на Spring JDBC . Я использую его всякий раз, когда мне нужно выполнить SQL программно. Пример:

int countOfActorsNamedJoe
    = jdbcTemplate.queryForInt("select count(0) from t_actors where first_name = ?", new Object[]{"Joe"});

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

5 голосов
/ 16 декабря 2008

Я склонен использовать именованные параметры JDBC Spring, чтобы я мог написать стандартную строку, например "select * from blah, где colX = ': someValue'"; Я думаю, что это довольно читабельно.

Альтернативой может быть предоставление строки в отдельном файле .sql и чтение содержимого с использованием служебного метода.

О, также стоит взглянуть на Squill: https://squill.dev.java.net/docs/tutorial.html

4 голосов
/ 16 декабря 2008

Я рекомендую использовать ORM, например, Hibernate. Однако, безусловно, бывают ситуации, когда это не работает, поэтому я воспользуюсь этой возможностью, чтобы рассказать о некоторых вещах, которые я помог написать: SqlBuilder - это библиотека Java для динамического построения операторов SQL с использованием стиль "строитель" это довольно мощный и довольно гибкий.

4 голосов
/ 16 декабря 2008

Почему вы хотите сгенерировать все sql вручную? Рассматривали ли вы ORM как Hibernate? В зависимости от вашего проекта, он, вероятно, будет выполнять не менее 95% того, что вам нужно, делать это более чистым способом, чем необработанный SQL, и, если вам нужно получить последний бит производительности, вы можете создать SQL-запросы, которые необходимо настроить вручную.

3 голосов
/ 08 октября 2017

Google предоставляет библиотеку под названием Room Persitence Library , которая обеспечивает очень чистый способ написания sql. Ниже приведен фрагмент кода с официального сайта:

@Dao
public interface UserDao {
    @Query("SELECT * FROM user")
    List<User> getAll();

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    List<User> loadAllByIds(int[] userIds);

    @Query("SELECT * FROM user WHERE first_name LIKE :first AND "
           + "last_name LIKE :last LIMIT 1")
    User findByName(String first, String last);

    @Insert
    void insertAll(User... users);

    @Delete
    void delete(User user);
}

В официальных документах библиотеки больше примеров и лучшей документации.

Есть еще один, называемый MentaBean, который является Java ORM . Он имеет приятные функции и выглядит довольно простым способом написания SQL.

3 голосов
/ 27 марта 2012

Вы также можете посмотреть MyBatis ( www.mybatis.org ). Он помогает вам писать операторы SQL вне вашего Java-кода и отображает результаты sql в ваши Java-объекты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...