Is there any lightweight JDBC wrapper with these features? - java

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));

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.

Is there a HQL version of Hibernate's Restrictions.sqlRestriction()?

I have a Java application using Hibernate 4.3.6. We use two different databases (one for regular deploy, other for unit/integration tests). There's a common db-function we'd like to use, but it's called different in each db dialect and Hibernate has no support for it. We've fixed this by simply creating subclasses for each Dialect and using:
this.registerFunction("normalizedFunctionName",
new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "arbitraryFunctionName(?1, ?2)"));
I can now use normalizedFunctionName(?, ?) in HQL. However I'd like to use it when using the Criteria API, something like:
sessionFactory.getCurrentSession()
.createCriteria(SomeClass.class)
.add(
Restrictions.lt("normalizedFunctionName(value, 'bla')", 3)
);
But this doesn't work. Now I've discovered there's:
Restrictions.sqlRestriction("arbitraryFunctionName(value, 'bla') < 3");
But since that's native SQL and not HQL, I can't use it.
So, my questions are:
Is there an HQL version of the Restrictions.sqlRestriction() feature?
Or is there another alternative to accomplish what I'm trying to do?

Spring & JDBCTemplate : are resources automatically closed when using the underlying datasource?

I'm using Spring and JDBC template to manage database access, but build the actual SQL queries using JOOQ. For instance, one DAO may look like the following:
public List<DrupalTaxonomyLocationTerm> getLocations(String value, String language) throws DataAccessException {
DSLContext ctx = DSL.using(getJdbcTemplate().getDataSource(), SQLDialect.MYSQL);
SelectQuery q = ctx.selectQuery();
q.addSelect(field("entity_id").as("id"),);
q.addFrom(table("entity").as("e"));
[...]
}
As you can see from the above, I'm building and executing queries using JOOQ. Does Spring still take care of closing the ResultSet I get back from JOOQ, or do I somehow "bypass" Spring when I access the data source directly and pass the data source on to JOOQ?
Spring doesn't do anything with the objects generated from your DataSource, i.e. Connection, PreparedStatement, ResultSet. From a Spring (or generally from a DataSource perspective), you have to do that yourself.
However, jOOQ will always:
close Connection objects obtained from a DataSource. This is documented in jOOQ's DataSourceConnectionProvider
close PreparedStatement objects right after executing them - unless you explicitly tell jOOQ to keep an open reference through Query.keepStatement()
close ResultSet objects right after consuming them through any ResultQuery.fetchXXX() method - unless you explicitly want to keep an open Cursor with ResultQuery.fetchLazy()
By design, jOOQ inverses JDBC's default behaviour of keeping all resources open and having users tediously close them explicitly. jOOQ closes all resources eagerly (which is what people do 95% of the time) and allows you to explicitly keep resources open where this is useful for performance reasons.
See this page of the jOOQ manual for differences between jOOQ and JDBC.

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)

How to test HQL queries?

I'm searching for a fast (really fast) way to test changes to hibernate queries. I have a huge application with thousands of different HQL queries (in XML files) and 100+ mapped classes and i dont want to redeploy the whole application to just test one tiny change to a query.
How would a good setup look like to free me from redeployment and enable a fast query check?
With Intellij IDEA 8.1.3 the mechnism of choice is called 'Facet'. To instantly test HQL queries:
create a data source Tools -> Data Source, Add Data Source, define driver, username and password of yor development db
in case you dont have already a hibernate.cfg or you configure your session factory in a different way than via xml: create a hibernate.cfg file referencing all XML mapping's (define a name for the session factory, just for easier handling)
in 'Project Structure' add Facet to your module of choice and assign the recently defined data source to the new facet
switch to Java EE View
Open Hibernate Facets - Node
Right click Session factory and choose "Open HQL Console"
enter HQL query in console
...and your're done.
sorry for this RTFM question.
You can use hibernate tools in eclipse to run queries. This will allow you to run HQL whenever you want to try something.
If you're using IntelliJ, there is Hibero.
There is a standalone editor from sun, but I haven't tried it.
I wrote a simple tool to test & preview HQL, this is just one java class with main method.
you can find the code here: https://github.com/maheskrishnan/HQLRunner
here's the screen shot...
I test my HQL queries in unit-tests with the HSQLDB database. Just create an entity manager, cast it to a hibernate session and query away.
final EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("tacs-test", props);
final EntityManager entityManager = entityManagerFactory.createEntityManager();
return (Session)entityManager.getDelegate();
Best
Anders
You said the quickest way, I'm not sure if you meant the quickest way to get going, or the quickest way to perform ongoing tests, with some initial investment to get the tests implemented. This answer is more the latter.
The way I've done this before was to implement some simple integration testing with JUnit and DBUnit.
In essence, you'll be using DBUnit to set up your test database with a known and representative set of data, and then plain JUnit to exercise the methods containing your HQL queries, and verify the results.
For instance,
Set up your database first to contain only a fixed set of data e.g.,
Product Name, Price
Acme 100 Series Dynamite, $100
Acme 200 Series Dynamite, $120
Acme Rocket, $500
This is something you'd do in your JUnit test case's setup() method.
Now let's assume you have a DAO for this entity, and there's a "findProductWithPriceGreaterThan(int)" method. In your test, you'd do something like:
public void testFindProductWithPriceGreaterThanInt() {
ProductDAO dao = new HibernateProductDAO();
//... initialize Hibernate, or perhaps do this in setup()
List products = dao.findProductWithPriceGreaterThan(110);
assertEquals(2, products.size());
//... additional assertions to verify the content of the list.
}
In the eclipse Market, you can search for JBoss Tools and choose only Hibernate tools from the given list.
In eclipse
Install Hibernate tools(Jboss)
Switch to hibernate perpective
Open/click Hibernate Configuration window
Rt Click on the window and Add Configuration
Rt Click on the window click/open HQL editor
Type and execute your HQL queries and get your result in the Hibernate Query result window
Follow this link for more info http://docs.jboss.org/tools/OLD/2.0.0.GA/hibernatetools/en/html/plugins.html

Categories