Can MyBatis create the database schema? - java

Has MyBatis any feature to allow create the SQL schema from de Class Model like Hibernate does?
I'm looking for that in Google and I only found information about MyBatis Generator (http://mybatis.github.io/generator/).
This tool seems to be useful for generate the Java model from the SQL Schema, which is just the opposite I want.

Can MyBatis create the database schema?
I'm afraid not. In order to do that you need an ORM and MyBatis is not an ORM.
With an ORM solution (like Hibernate for example) you map tables to entities. The entity is the (object) representation of the (relational) table and contains all the metadata (getters/setters, annotations etc) necessary to create the table.
MyBatis does not map entities to tables, it maps methods to SQL statements. There is no way to determine from the methods or the SQL statements what the structure of the database should be. When you use MyBatis the tables must already exist.

I tried create a new database schema and new table via the mybatis, it works well with my mysql db. So it seems mybatis totally support the execution almost all of the free sql statement.
I think you could refer another answer.
Creating a table programmatically using MyBatis and MySql

Related

Log Creation/Altering of Tables By Envers Hibernate

1) When does Hibernate Envers create or alter the audit tables in the schema when there is a new Entity or column that is annotated with #Audited?
2) Is there a way to log the mysql commands that are called when there is a new audit table or column added?
When does Hibernate Envers create or alter the audit tables in the schema when there is a new Entity or column that is annotated with #Audited?
Technically Hibernate Envers does not do this at all, this entire step is handled by Hibernate ORM proper.
During bootstrap of Hibernate ORM, the following steps occur:
ORM gathers all entity mappings, those defined in XML and annotated classes. ORM takes all these representations and builds what we call a boot-model representation of the entities.
Envers implements a special hook that ORM calls into immediately after the boot-model has been prepared but before the runtime model is built which ORM uses thereafter. This hook allows Envers to parse the boot-model in conjunction with the annotated java classes and it creates additional entity mappings for ORM that supplement what was built in (1). These mappings are currently provided to ORM has additional Hibernate HBM XML mappings.
If the hook produces any additional HBM XML mappings, Hibernate ORM integrates those directly by converting them into boot-model representations as well.
Right before Hibernate ORM converts this boot-model into the runtime-model representation, ORM builds a database representation of the mappings. It is at this point that the database model is used during the Schema Migration (if enabled) to validate/update/create the schema to match the database model representation.
Is there a way to log the mysql commands that are called when there is a new audit table or column added?
There are several ways to accomplish this, some are easier than others of course.
For example, you could enable Hibernate SQL logging, configure those entries to be written to a special named file using your logging API of choice and then ship those logs off for post-processing on defined intervals.
You could also consider using something more standalone such as Debezium that is capable of monitoring database changes at the transaction/archive/oplog/binlog level and for certain connectors exposes a Kafka topic that specifically stores DDL changes.
Hibernate-envers is using interceptors to insert changes into audition-tables. They are called right before the transaction is committed to the database.
The question is a little bit unclear, if you say mysql-commands I guess you mean update-queries like CREATE TABLE and CREATE COLUMN. By default, enver is reporting violations against the schema. I can imagine that - if you expose the audition-tables as hibernate-entitys aswell - a hbm2ddl might create those create-table and create-column update-queries.
After all I suggest to use the single-source-of-version-of-truth concept (SSOVOT) and failfast (FF) and dare the database as the single-point-of-faliure (SPOF).
The wording problem
Yes, the hibernate-plugin is called enver, but from an scientific pov a enver(entity-version) is only the version-property marked with #Version in the entity. The correct name is audition because you historically log all changes to the table in the database.
In case of "change entity tables" having rows already.
First to say is that every payload-column in entity-tables is nullable, you must add a column in the audition-table it has by default a null value. But if the genuine table does not allow to have null-values in the colmn the audition is broken! This will lead to unexpected problems. This means that the automated replication of genuine-columns to audited-columns must be an process of reconstruct schema AND DATA.

Hibernate - join tables without NamedNativeQuery

While joining multiple tables on my project using Hibernate jpa /Spring (annotation driven), I had to use the NamedNativeQuery annotation to achieve my objective to extract a distributed resultset spanning multiple tables. This may be a question that merely serves academic merit, but given that I am starting out on Hibernate - is there another way to achieve table joins without having to fall back on queries native to the database dialect?
Yes. I believe this is exactly what you need: https://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/querycriteria.html#querycriteria-tuple
Criteria Queries is a way of building a complete query just using its API. If I were you, I'd give it a try.
By the way, according to your question, the reason for using native queries is just for retrieving a specific set of columns. If this is the case, you can also write it using HQL as well. The query doesn't necessarily needs to be native.

Hibernate... how does one do database/SQL queries?

I (think I) understand that Hibernate offers me access to a relational database essentially as if I had a class(es) that matched whatever view(s) I define of some tables.
How do I get the results of a specific query to be accessible via a class? In particular, can I issue a complex SQL query, and process multiple results?
Do I lose any of the power of SQL by using Hibernate?
I (think I) understand that Hibernate offers me access to a relational database essentially as if I had a class(es) that matched whatever view(s) I define of some tables.
Hibernate provides a framework allowing to map an object model to your database and an API to manipulate data through this object model.
How do I get the results of a specific query to be accessible via a class? In particular, can I issue a complex SQL query, and process multiple results?
I'm not sure I understood the question but let's see. The Hibernate way would be to use HQL (Hibernate Query Language) queries and/or Criteria queries to perform queries on the object model.
But you can also use Native SQL (sacrificing portability) to return entities, multiple entities or even non-managed entities (see also Hibernate 3.2: Transformers for HQL and SQL).
Do I lose any of the power of SQL by using Hibernate?
HQL and the Criteria API are quite powerful - and portable - and will generate the proper SQL for your backend. If required, you can still use native SQL queries as already mentioned. But in most cases, HQL and Criteria work well and should be preferred.
See also
14. HQL: The Hibernate Query Language
15. Criteria Queries
16. Native SQL
Hibernate3 allows you to specify handwritten SQL, including stored procedures, for all create, update, delete, and load operations.
sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").list();
More at http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querysql.html

Will hibernate java programs have no sql code?

I haven't worked with hibernate. I have little bit of experience in java. I was going through source of a beast of an java application created by Oracle(Retail Price Management). I was expecting a lot of sql code embedded in there as the application makes heavy use of database. But to my surprise, NO embedded SQL code! so far. I found that it was using what is called as "Hibernate" from the lot of .hbm.xml files. Is it a trademark for java programs using hibernate or maybe I haven't seen the complete codebase?. Could someone enlighten me how this is possible?. Thanks.
Hibernate, as all ORM tools, indeed lessens or eliminates the need to use raw SQL in Java code, due to the following:
many associations between various entities are recorded in the Hibernate mapping, so these are fetched automatically by Hibernate - i.e. if you have an aggregation relationshiop between two classes on the Java side, this may be mapped as a foreign key relationship in the DB, and Hibernate, whenever an instance of class A is loaded, can automatically load the associated instances of class B too,
many queries can be done in Hibernate's own HQL query language, or using its Criteria API.
Under the hood Hibernate does generate SQL to communicate with the DB, but this is not visible on the Java side. It can be seen in the logs though, if it is enabled.
Due to this, programs using Hibernate very rarely need to use JDBC or SQL directly. The exceptions are typically ralted to "tricky" legacy DB schemas which can't be fully handled by Hibernate.
Because that's the whole purpose of using Hibernate or any other object-relational mapping framework.
Hibernate solves object-relational impedance mismatch problems by replacing direct persistence-related database accesses with high-level object handling functions.
Hibernate generates SQL for all its standard database operations. It understands different SQL dialects, and the mapping files (.hbm.xml) tell it about the database structure so it knows how to construct its queries. There is a showSql setting you can turn on if you want to see it outputting its generated SQL as it runs.
Hibernate is an Object-Relational Mapper (ORM). ORMs are used to hide the ugly details of SQL incompatibility[sic] between databases from your program -- you define your tables and map them to an object hierarchy (the .hbm.xml files) and then Hibernate does the rest. Thus most programs that use Hibernate won't see a single phrase of SQL, unless there's a specific reason to execute a complicated query.
Hibernate is a tool, or technology that takes care of the interaction between the database and application for you. You have to tell the structure of the application and the database to it, this is what is in the .hbm.xml files.
The SQL is generated by Hibernate at runtime (kind of)
Say you have an Fruit class, and objects of this is persisted into a T_FRUIT table.
You say this to hibernate, via the .hbm.xml files. That there is a table T_FRUIT, this table is represented by the Fruit class, and which fields in the Fruit class correspond to which columns in th T_FRUIT table.
And then it knows whenever you are trying to save a fruit, it should insert/update to the T_FRUIT table.
When you want to create an Apple, you create an object of fruit corresponding to apple and save "save this fruit".
Hibernate takes care of persisting it.
You can have relationships defined between tables, and Hibernate is intelligent enough to persist in multiple tables.
When you fetch a fruit, hibernate fetches the details of the fruit and its children also(data from referencing tables). And you can say whether you want fetch all the children
at once, or as and when required.
And so on. Aim is to make your life easier, and code maintainable, easy to read, portable,...
With this info, let me redirect you.

Hibernate and stored procedures

As my understanding on setting hibernate, I need to create
table meta data file (person.hbm.xml), include all the fields mapping
java object (person.java)
If we use stored procedures for all transaction, do we still need the above configuration?
It seems hibernate and stored procedures will overlap,
We set up the stored procedure because we don't want the to developer know all the field in db. If tables change, then we need update above files.
Does it mean if we purely use stored procedure, we should just go for JDBC?
If hibernate, we should stay in HQL?
You can use native SQL and map the result to object:
sess.createSQLQuery("SELECT * FROM CATS").addEntity(Cat.class);
The JDBC syntax to invoke store procedure is like following:
CallableStatement proc =
connection.prepareCall("{ call set_death_age(?, ?) }");
proc.setString(1, poetName);
proc.setInt(2, age);
So maybe, you can invoke stored procedure and map them to object:
sess.createSQLQuery("{ call my_stored_proc }").addEntity(Cat.class);
Note also that updates made through stored procedures will escape hibernate, which means that you will need to evict objects from the 1st level and 2nd level cache yourself.
So as you see, hibernate and stored procedure don't really fit naturally together.
we set up the stored procedure because
we don't want the to developer know
all the field in db. if table change,
then we need update above files.
If you're concerned about security, either use:
database views
Oracle column priviledges
provide mapping files and forbid their modification by developpers
Using Hibenate with Stored Procedures is a certain overlap. As you for example need to write astored procedure for INSERT, UPDATE, DELETE and SELECT, Hibernate provides an easiest way to interract with with relational database objects by mappings them into metadata files like you mentioned person.hbm.xml.
Yes, the use of stored procedure wil require you to write these metadata files anyway. A stored procedure will not replace the Hibernate mappings. Those mapping only tell Hibernate how to persist your object-oriented model to the database. A great thing about Hibernate is that you may even, if needed, generate you database model from your JAVA code through the schema generation tool.
As for the stored procedures, one recommended way is to configure your stored procedures as named queries from within the configuration file. This, however, makes you miss the better potential, in my opinion, of Hibernate.
Does this answer your question? Do you need further explanations?
It is possible to use native-sql and to use stored procedure for querying (with limiations/rules). But, as written in the documentation:
Stored procedures currently only return scalars and entities. <return-join> and <load-collection> are not supported.
So if you want to work with non-managed entities (i.e. not scalars in an Object[]), you'll have to apply a ResultTransformer in the code.
But at the end, if you want to hide the database to developers, if you don't want to map objects to tables, if you don't want to work with associations, if you don't want to use HQL, if you don't want to use an OO approach, then I really wonder why you want to use Hibernate. You'd better use raw JDBC (with Spring for example) or maybe a data-mapper like iBATIS.
You can map the database fields in a result set to an object in hibernate: the documentation explains how.
The idea of Hibernate is to fill the object-relational gap. With the stored procedures (which I can't guess since you haven't told anything about them) you can't get objects from database. You still get rows.
Hiding the database columns from developers sounds like a bad practice to me. Hiding them from the application is perhaps what you want, and you achieve that with the metadata file.

Categories