Save sql query into external file - java

i use Spring for DB operation. For now i save my sql query into a xml file, like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>This query returns something extremely useful.
</comment>
<entry key="date.sql">
"update something set time = ? where sharedkey = ?"
</entry>
</properties>
And in the JDBCTemplate i have this:
public Properties readProperties(String xmlFileName) throws Exception {
Properties properties = new Properties();
InputStream is = this.getClass().getClassLoader().getResourceAsStream(xmlFileName);
properties.loadFromXML(is);
return properties;
}
public void updateDate(){
properties = readProperties("queries.xml");
sqlQuery = properties.getProperty("date.sql");
jdbcTemplateObject.update(sqlQuery,new Object[] {time,token});
}
Work but i think is not the best solution, how i can that with Spring? or there is other library for that?

You can achieve this in multiple ways. the best way to follow is
1> By Placing the Queries in a Property File and call them using Spring PropertyPlaceHolder
2> You can Still Use XML and can Get the Query by using JAXB or SAX XML Parser.

See the ElSql library which provides this functionality.
The small ElSql project allows an external file of SQL statements to be easily loaded and managed. It was originally written to work with Spring, and still does (although it now works without Spring as a dependency).
The file may be stored in "raw" SQL, or using a DSL:
-- an example comment
#NAME(SelectBlogs)
#PAGING(:paging_offset,:paging_fetch)
SELECT #INCLUDE(CommonFields)
FROM blogs
WHERE id = :id
#AND(:date)
date > :date
#AND(:active)
active = :active
ORDER BY title, author
#NAME(CommonFields)
title, author, content
// Java code:
bundle.getSql("SelectBlogs", searchArgs);
The DSL breaks the file into #NAME blocks that can be referred to from code. Each block is defined by significant whitespace indentation.
Additional tags can be used, such as #PAGING (that inserts the necessary code for paging such as FETCH/OFFSET) and #AND (that only outputs if the specified variable exists, for dynamically building searches). The goal of the optional DSL tags is to provide the common basics that often hit when trying to build dynamic SQL in a database-neutral way.
We use it for our SQL and avoid the significant overhead of an ORM.

Related

Is it secure enough to put SQL Queries into sql.properties file for SpringBoot app

I am externalizing my SQL queries into .properties file using SpringBoot App with Java 8.
I just want to know how secure is it to put all my Queries into .properties file
Inside the resources folder, I have a file called queries.properties inside file I have below items
query1=EXEC [NHistory] #vchrId = ?
query2= EXEC [CDetails] #vchrID = ?
query3=EXEC[LDetails]
Don't do this.
This isn't best practice and might create security issues, but not necessarily for the reasons you think, e.g. accidentally serving the file.
It looks like you might be tempted to create SQL by replacing the ? marker, which will expose you to SQL injection.
It also makes your code harder to read, as it breaks object oriented encapsulation, as all your SQL is mixed together.
Instead create proper repositories using Spring Data's existing functionality for creating custom SQL, which also does not expose you to SQL injection (https://www.baeldung.com/spring-data-jpa-query).
#Query(value = "SELECT * FROM Users u WHERE u.status = ?1", nativeQuery = true)
User findUserByStatusNative(Integer status);
Spring Data also saves you from having to manually use JDBCTemplate.

How to configure JOOQ to codegen tables with the same structure?

I have some legacy tables with the same structure in MySQL like:
my_table_01
my_table_02
my_table_03
...
Is there a way I can configure JOOQ codegen to generate only one table/record class which shared by all those tables ?
There are two steps that you have to do in order to achieve what you like to do:
1. Configure the code generator
You'll probably have to exclude my_table_02 and my_table_03 from being generated. You can do this by specifying the <excludes/> tag as documented here.
Optionally, you could use generator strategies (programmatic config) or matcher strategies (XML config) to rename my_table_01 to my_table.
2. Configure your runtime
While running queries against MY_TABLE, you can specify runtime table mapping in order to map MY_TABLE back to my_table_01 or my_table_02 or my_table_03. This mapping works on a per-configuration basis, i.e. it will have the scope of a single query if you're using one configuration per query.
Another option is, of course, to abstract over these suffixes in your client code, e.g. via a table selection method:
public static Table<?> myTable() {
if (something)
return DSL.table("{0}_01", MY_TABLE);
else if (somethingElse)
return DSL.table("{0}_02", MY_TABLE);
...
}

How do I configure JPA table name at runtime?

I have an issue where I have only one database to use but I have multiple servers where I want them to use a different table name for each server.
Right now my class is configured as:
#Entity
#Table(name="loader_queue")
class LoaderQueue
I want to be able to have dev1 server point to loader_queue_dev1 table, and dev2 server point to loader_queue_dev2 table for instance.
Is there a way i can do this with or without using annotations?
I want to be able to have one single build and then at runtime use something like a system property to change that table name.
For Hibernate 4.x, you can use a custom naming strategy that generates the table name dynamically at runtime. The server name could be provided by a system property and so your strategy could look like this:
public class ServerAwareNamingStrategy extends ImprovedNamingStrategy {
#Override
public String classToTableName(String className) {
String tableName = super.classToTableName(className);
return resolveServer(tableName);
}
private String resolveServer(String tableName) {
StringBuilder tableNameBuilder = new StringBuilder();
tableNameBuilder.append(tableName);
tableNameBuilder.append("_");
tableNameBuilder.append(System.getProperty("SERVER_NAME"));
return tableNameBuilder.toString();
}
}
And supply the naming strategy as a Hibernate configuration property:
<property
name="hibernate.ejb.naming_strategy"
value="my.package.ServerAwareNamingStrategy"
/>
I would not do this. It is very much against the grain of JPA and very likely to cause problems down the road. I'd rather add a layer of views to the tables providing unified names to be used by your application.
But you asked, so have some ideas how it might work:
You might be able to create the mapping for your classes, completely by code. This is likely to be tedious, but gives you full flexibility.
You can implement a NamingStrategy which translates your class name to table names, and depends on the instance it is running on.
You can change your code during the build process to build two (or more) artefacts from one source.

Is there any lightweight JDBC wrapper with these features?

Named parameters, just like JdbcTemplate from Spring
XML configuration for JDBC connection settings
XML configuration for queries. Something like Hibernate <sql-query>. See Named SQL queries for an example
I'm thinking of trying to build my own, but I thought I'd ask here, maybe it's already been done.
Obviously I don't want to use neither an ORM nor JdbcTemplate.
What about MyBatis?
(source: mybatis.org)
I'am looking for the same thing, meanwhile try out DBUtils Utility:
http://commons.apache.org/dbutils/
Lightweight, open source and no dependencies.
Try JdbcSession from jcabi-jdbc. It's simple (as you want) and requires you to create a java.sql.DataSource before, for example (using BoneCP and H2 database):
BoneCPDataSource source = new BoneCPDataSource();
source.setDriverClass("org.h2.Driver");
source.setJdbcUrl("jdbc:h2:mem:x");
String name = new JdbcSession(source)
.sql("SELECT name FROM user WHERE id = ?")
.set(555)
.select(new SingleHandler<String>(String.class));

Getting SQL script from Hibernate update

I'm looking for way to get the SQL update script when Hibernate automatically updates tables.
I'm using hibernate.hbm2ddl.auto=update in development environment only, and I need SQL script that updates tables for production.
I want these SQL scripts in txt format for revision and potential edit.
How can this be done?
Thanks for any advice.
There are some suggestions and general discussion here.
In a nutshell, you can turn on logging (to standard output):
hibernate.show_sql=true
Alternatively, if you use log4j, you can add this to your log4j.properties file:
log4j.logger.org.hibernate.SQL=DEBUG
Both of these approaches are going to output Hibernate's prepared statements with parameters (so the parameter values themselves are not inline). To get around this, you could use an interceptor like P6Spy. Details on that can be found here.
org.hibernate.cfg.Configuration class has method:
public java.lang.String[] generateSchemaUpdateScript( Dialect, DatabaseMetadata)
what generates the reqiured update script.
I've just implemented this in grails:
configuration = new DefaultGrailsDomainConfiguration(
grailsApplication: grailsApplication,
properties: props)
//this extends hibernate config
Connection c = SessionFactoryUtils.getDataSource(sessionFactory).getConnection(props.'hibernate.connection.username', props.'hibernate.connection.password')
<br/>md = new DatabaseMetadata(c, DialectFactory.buildDialect(props.'hibernate.dialect'))
configuration.generateSchemaUpdateScript(DialectFactory.buildDialect(props.'hibernate.dialect'), md)
)
check SchemaExport script in grails, for further information, it uses hibernate to generate schema.
(I had to implent is as a service because we have external domain model)

Categories