I am teaching my self hibernate, and am quite confused of why i can not just write simple SQL queries.
I find it rather more confusing to use than plain SQL (what I am used to)
PLUS: The NetBeans HQL editor I found pretty annoying, It is harder for me to produce a right query in HQL, then in SQL, and why does the shown SQL differ from actual SQL statements ?
So why use it ? - As it is known that hibernate is very resource extensive, and I believe that hibernate is the reason for our app to running out of memory very often, as during the process of redeploying e.g...
I am very interested in knowing why I should use Hibernate and not plain SQL (mysql) statements !?
And maybe a good link for hibernate queries would be nice ;), I am using this one atm:
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/queryhql.html
But also interested in any good link explaining the setup of the queries, the mapping, underlying construction etc..
Best Regards
Alex
HQL is object oriented and it's done with the purpose of working on the Java objects representing your DB tables.
A basic advantage is that you can put placeholders like :orderNumber (using the colon simbol) in the HQL query and replace with the value of a variable. For example:
int orderNumber = 685412;
List<Order> l=
session.createQuery("from Order where orderNumber = :orderNumber")
.setParameter("orderNumber",orderNumber).list();
In this way you can modify orderNumber in a simple way, evoiding the classical
String query = "select * from Order where orderNumber = " + orderNumber + "...";
Morover using MySQL syntax would sometimes turn your code not reusable if you migrate your DB to another DBMS.
Anyway I'm still not so convinced about the preference on HQL.
Here you can find the full grammar definition.
Related
Martin Fowler in his book Patterns of enterprise application architecture says
A good rule of thumb is to avoid string concatenation to put together
SQL queries
It is a practice that I use quite often, to abstract the syntax of my SQL queries from the real data of the query.
Can you explain me why this is considered a bad practice?
While there might be usecases where you build a prepared statement by string-concatenation before compiling it, it is always bad practice to insert query-parameters using string-concatenation for two reasons:
Performance: When using a prepared statement the query-syntax has to be parsed only once and the access-path has to be calculated only once for each distinct query-type. When building statements by string-concatenation parsing and optimizing has to be done for each execution of the query.
Security: Using string-concatenation with data provided by the user is always prone to SQL-injection-attacks. Suppose you got a statement:
query = "select secret_data from users where userid = '" + userid_param + "'";
And imagine someone sends a userid_param containing "' OR 1=1;"...
This way the only way to defend is doing 100% correct input-sanitation which might be quite hard to get right depending on the language used. When using prepared statements with a properly implemented driver the driver will isolate the statement form the query-parameters so nothing will be mixed up.
I have a very silly doubt in NHibernate. There are two or three entities of which two are related and one is not related to other two entities. I have to fetch some selected columns from these three tables by joining them. Is it a good idea to use session.CreateSql() or we have to use session.CreateCriteria(). I am really confused here as I could not write the Criteria queries here and forced to use CreateSql. Please advise.
in general you should avoid writing SQL whenever possible;
one of the advantages of using an ORM is that it's implementation-agnostic.
that means that you don't know (and don't care) what the underlying database is, and you can actually switch DB providers or tweak with the DB structure very easily.
If you write your own SQL statements you run the risk of them not working on other providers, and also you have to maintain them yourself (for example- if you change the name of the underlying column for the Id property from 'Id' to 'Employee_Id', you'd have to change your SQL query, whereas with Criteria no change would be necessary).
Having said that- there's nothing stopping you from writing a Criteria / HQL that pulls data from more than one table. for example (with HQL):
select emp.Id, dep.Name, po.Id
from Employee emp, Department dep, Posts po
where emp.Name like 'snake' //etc...
There are multiple ways to make queries with NH.
HQL, the classic way, a powerful object oriented query language. Disadvantage: appears in strings in the code (actually: there is no editor support).
Criteria, a classic way to create dynamic queries without string manipulations. Disadvantages: not as powerful as HQL and not as typesafe as its successors.
QueryOver, a successor of Criteria, which has a nicer syntax and is more type safe.
LINQ, now based on HQL, is more integrated then HQL and typesafe and generally a matter of taste.
SQL as a fallback for cases where you need something you can't get the object oriented way.
I would recommend HQL or LINQ for regular queries, QueryOver (resp. Criteria) for dynamic queries and SQL only if there isn't any other way.
To answer your specific problem, which I don't know: If all information you need for the query is available in the object oriented model, you should be able to solve it by the use of HQL.
I am building a website on top of nhibernate. Is there any efficient way to build reports? BY reports, I mean is there anyway to execute a complicated query that grabs random pieces of data? Stored procedures? Hql?
Can I get single, non mapped values from hql?
Yes you can.
For simple stuff you can use HQL and select stuff into a new non-mapped object (its class must be "registered" with NH but there is no mapped per se). HQL syntax looks like
select new NonMappedClass(column1, column2). You need an appropriate constructor to use this.
Reporting with HQL quickly breaks down. I often find myself knowning exactly what to do in SQL but having hard time figuring out the HQL way. Also the lack of real software tools for HQL slows you down (sorry NH Query Analyzer does not cut it). In these case, you can define a raw with an associated . When executing these queries, NH will return you a IList of array of Object. You need the cast the Object() into the proper type. You'll want this for advanced reporting queries.
This casting stuff is error prone and sucks big time. So you they did a nice AliasToBean query transformer that can map the result set column name to a property (names must match of course). I don't know about the latest NH release, but the older 1.2.1 AliasToBean converter seemed to have a bug in which it would converter nullable value type to the default value of the type instead of setting it to null. ie: int? would be 0 instead of null if the associated DB field was null. This prevented me from using AliasToBean in some case and I had to map by hand.
Best advice is don't fall into the trap of performing complex reporting with your business object and for loops. I've seen this in production. It will be a performance horror as your tables grows in size.
Yes, you can do this. It's called dynamic instantiation. The syntax in HQL is
select new MyClass(cust.age)
from customers cust
Or, with Criteria:
.SetProjection(Projections.ProjectionList()
.Add(Projections.Name("cust.age"), "age")
.SetResultTransformer(Transformers.AliasToBean<MyClass>())
Remember, you must have a matching constructor on MyClass!
Why did Andres Heilsberg designed LINQ syntax to be different than that of SQL (whereby made an overhead for the programmers to learn a whole new thing)?
Weren't it better if it used same syntax as of SQL?
LINQ isn't meant to be SQL. It's meant to be a query language which is as independent of the data source as reasonably possible. Now admittedly it has a strong SQL bias, but it's not meant to just be embedding SQL in source code (fortunately).
Personally, I vastly prefer LINQ's syntax to SQL's. In particular, the ordering is much more logical in LINQ. Just by looking at the order of the query clauses, you can see the logical order in which the query is processed. You start with a data source, possibly do some filtering, ordering etc, and usually end with a projection or grouping. Compare that with SQL, where you start off saying which columns you're interested in, not even knowing what table you're talking about yet.
Not only is LINQ more logical in that respect, but it allows tools to work with you better - if Visual Studio knows what data you're starting with, then when you start writing a select clause (for example) it can help you with IntelliSense. Additionally, it allows the translation from LINQ query expressions into "dot notation" to be relatively simple using extension methods, without the compiler having to be aware of any details of what the query will actually do.
So from my point of view: no, LINQ would be a lot worse if it had slavishly followed SQL's syntax.
First, choose your flavor of SQL - there are several! (T-, PL-, etc).
Ultimately, there are similarities and differences. A lot of the LINQ changes make more sense - i.e. choosing your source (FROM) before you try filtering (WHERE) / projection (SELECT), allowing better static analysis etc (including intellisense), and a more natural query comprehension syntax. This helps both the developer and the compiler, so I'm happy.
It is simpler to parse expression when initial data is provided in its beginning.
Because of this VS provides code completion even for partially written LINQ queries (great feature IMO).
The reason is the C# language designers use this approach because of when I first specify where the data is coming from, now Visual Studio and the C# compiler know what my data looks like. And I can have IntelliSense help in the rest of the query because Visual Studio will know that "city" (for example) is a string, and it has operations like startsWith and a property named length. And really, inside of a relational database like SQL Server, the select clause that you are writing in a SQL statement at the top is really one of the last pieces of the information the query engine has to figure out. Before that it has to figure out what table you are working against in the from clause even though the from clause comes later in SQL syntax
I'm overloading a vb.net search procedure which queries a SQL database.
One of the older methods i'm using as a comparison uses a Stored Procedure to perform the search and return the query.
My new method uses linq.
I'm slightly concerned about the performance when using contains queries with linq. I'm looking at equally comparable queries using both methods.
Basically having 1 where clause to
Here are some profiler results;
Where name = "ber10rrt1"
Linq query : 24reads
Stored query : 111reads
Where name = "%ber10%"
Linq query : 53174reads
Stored proc query : 23386reads
Forgetting for a moment, the indexes (not my database)... The fact of the matter is that both methods are fundamentally performing the same query (albeit the stored procedure does reference a view for [some] of the tables).
Is this consitent with other peoples experiance of linq to sql?
Also, interestingly enough;
Using like "BER10%"
resultset.Where(Function(c) c.ci.Name.StartsWith(name))
Results in the storedproc using 13125reads and linq using 8172reads
I'm not sure there is enough there for a complete analysis... I'm assuming we are talking about string.Contains/string.StartsWith here (not List<T>.Contains).
If the generated TSQL is similar, then the results should be comparable. There are a few caveats to this - for example, is the query column a calculated+persisted value? If so, the SET options must be exact matches for it to be usable "as is" (otherwise it has to re-calculate per row).
So: what is the TSQL from the SP and LINQ? Are they directly comparable?
You mention a VIEW - I'm guessing this could make a big difference if (for example) it filters out data (either via a WHERE or an INNER JOIN).
Also - LIKE clauses starting % are rarely a good idea - not least, it can't make effective use of any index. You might have better performance using "full text search"; but this isn't directly available via LINQ, so you'll have to wrap it in an SP and expose the SP via the LINQ data-context (just drag the SP into the designer).
My money is on the VIEW (and the other code in the SP) being the main difference here.