I am trying to create a multi-layer menu with no restriction on how far it can branch out - e.g. Food->Fruits->Round Shape->color etc...
I am not sure how to represent the relationship in SQL and also am not sure how to query the data.
I thought about doing:
MainMenu:
ID:ChildID:Name:URL:PermissionID:etc.
SubMenu:
PID:ChildID:Name:URL:PermissionID:etc.
I think if the submenu has additional submenus, its children would be another item in the SubMenu table, and that should work? The PermissionID is used to determine if the Menu item can be accessed by a UserGroup.
I am not sure about the SQL query since i am a little green on it. I know in the end I am feeding UserGroup's PermissionIDs to the SQL to get all the Menu and Submenu from the tables.
Storing hierachical data in RDBMS is not a good idea. Either you can use document based frameworks like Elastic https://www.elastic.co/ which stores data in JSON document format or you can use hierachical JSON in varchar column in RDBMS.
Related
So, I have myself all confused with how to pull info from three tables. Let me set this up fairly clearly (I hope)...
I have three tables FoodTruck, MenuItems, and Ingredients. Each food truck can have multiple menuItems (has a truckID column tied to the FoodTruck truckID) and each menuItem can have multiple ingredients (menuID column tied to the MenuItem menuID).
So, I am thoroughly confused on the mysql command to get the information I truly want (joins are still fairly confusing to me) because in the end I would LIKE to be able to show a user the Food Truck's menu. It would look like one big menu consisting of menuItems which include ingredients.
If there is a select query that would get all of that information, what would the output be comprised of? I mean, how would it be presented? An array of the menuItems and then an array of the ingredients? If I got the info I could figure out how to deal with it as I am using JDBC...
Forgot to add: in the Menu table there are the columns (primary key: menuID, foodName, price, foodType, specialComments)... I need all of those. In the Ingredients table, I have name and menuID but I really only need to display name.
I have most of the queries done that I need. It is just that I am trying to display the full menu now. I am using the DAO design and prepared statements to sanitize the input. In doing that, I was hoping to be able to use a join or somehow get all of that pertinent info without resorting to several queries to my database
Yes you can do it with one query, using LEFT JOIN.
SELECT
* // I used *, you should modify it if you want to better control the output
FROM FoodTruck ft
LEFT JOIN MenuItems mi
ON mi.truckID = ft.truckID
LEFT JOIN Indgredient ind
ON ind.menuID = mi.menuID
Left join will keep records from the table on the left even no rows can be found in the table on the right.
Take note that rows from FoodTruck are likely to duplicate because you have more than one menu items for each truck. The same will also happend to MenuItem.
Im having domain object Item with fields id, name, parentItem and category(Boolean).
So im inserting values in database like:
id name parentItem category
1 Tools NULL 1
2 Electric tools 1 1
3 Small tools 2 1
4 Actual tool end child item 3 0
so actual item is in category/path "Tools/Electric tools/Small tools"
So i need to implements lazy filter search by categoryName/categoryPath.
For example: if user inputs in dataTable filter "Electric" i need to return all items in "Electric tools" category and all items from subcategorys ( in this example Small tools and all other if they exist).
So currently i have in java domain object #Transient field which uses recursion to get items path.
But i cant search by Transient fields. I mean i cant implement search in database because this field is:
1. Transient
2. Uses recursion and if i need to deploy app on other db version, i will have to rewrite recursion sql on db or something. I dont like this
Can anyone point me to some clever, unique solution ?
Any idea, advice is appreciated. Thanks!
This question looks very similar: HQL recursion, how do I do this?
In short: You cannot do recursion in HQL. Your best bets are:
Write a native query to do this (and yes, you would have to rewrite it with every database move, since recursive queries are not standard SQL)
Use a join column to have parents/children in the object and traverse&filter the product tree in memory (uses more memory since you preload everything, but only hits DB once)
Make multiple queries if you know your tree is not too deep. (Saves memory, but a lot of database work)
I am currently working with a Java based web application (JSF) backed by Hibernate that has a variety of different search pages for different areas.
A search page contains a search fields section, which a user can customize the search fields that they are interested in. There are a range of different search field types that can be added (exact text, starts with, contains, multi-select list boxes, comma separated values, and many more). Search fields are not required to be filled in and are ignored, where as some other search fields require a different search field to have a value for this search field to work.
We currently use a custom search object per area that is specific to that area and has hard coded getter and setter search fields.
public interface Search {
SearchFieldType getSearchPropertyOne();
void setSearchPropertyOne(SearchFieldType searchPropertyOne);
AnotherSearchFieldType getSearchPropertyTwo();
void setSearchPropertyTwo(AnotherSearchFieldType searchPropertyTwo);
...
}
In this example, SearchFieldType and AnotherSearchFieldType represent different search types like a TextSearchField or a NumericSearchField which has a search type (Starts with, Contains, etc.) or (Greater Than, Equals, Less Than, etc.) respectively and a search value that they can enter or leave empty (to ignore the search field).
We use this search object to prepare a Criteria object
The search results section is a table that can also be customized by the user to contain only columns of the result object that they are interested in. Most columns can be ordered ascending or descending.
We back our results in a Result object per result which also hard codes the columns that can be displayed. This table is backed by hibernate annotations, but we are trying to use flat data instead of allowing other hibernate backed objects to minimize lazy joining data.
#Entity(table = "result_view")
public interface Result {
#Column(name = "result_field_one")
Long getResultFieldOne();
void setResultFieldOne(Long resultFieldOne);
#Column(name = "result_field_two")
String getResultFieldTwo();
void setResultFieldTwo(String resultFieldTwo);
...
}
The search page is backed by a view in our database which handles the joining to all the tables needed for every possible outcome. This view has gotten pretty massive and we take a huge performance hit for every search, even when a user only really wants to search on one field and display a few columns because we have upwards of thirty search field options and thirty different columns they can display and this is all backed by the one view.
On top of this, users request new search fields and columns all the time that they would like added to the page. We end up having to alter the search and result objects as well as the backing view to make these changes.
We are trying to look into this matter and find alternatives to this. One approach mentioned was to create different views that we dynamically choose based on the fields searched on or displayed in the results table. The different views might join different columns and we pick and choose which view we need for any given search.
I'm trying to think about the problem a different way. I think it might be better to not use a view and instead dynamically join tables we need based on what search fields and result columns are requested. I also feel that the search and result objects should not contain hard coded getters/setters and should instead be a collection of search fields and a collection (or map) of result columns. I have yet to completely flesh out my idea.
Would hibernate still be a valid solution to this issue? I wouldn't want to have to create a Result object used in a hibernate criteria since they result columns can be different. Both search fields and/or result columns might require joining tables.
Is there a framework I could use that might help solve the problem? I've been trying to look for something, and the closest thing I have found is SqlBuilder.
Has anyone else solved a similar problem dynamically?
I would prefer not to reinvent the wheel if a solution already exists.
I apologize that this ended up as a wall of text. This is my first stackoverflow post, and I wanted to make sure I thoroughly defined my problem.
Thanks in advance for your answers!
I don't fully understand the problem. But JPA Criteria API seems very flexible, which can be used to build query based on user-submitted filtering conditions.
I have a customer with a very small set of data and records that I'd normally just serialize to a data file and be done but they want to run extra reports and have expandability down the road to do things their own way. The MySQL database came up and so I'm adapting their Java POS (point of sale) system to work with it.
I've done this before and here was my approach in a nutshell for one of the tables, say Customers:
I setup a loop to store the primary key into an arraylist then setup a form to go from one record to the next running SQL queries based on the PK. The query would pull down the fname, lname, address, etc. and fill in the fields on the screen.
I thought it might be a little clunky running a SQL query each time they click Next. So I'm looking for another approach to this problem. Any help is appreciated! I don't need exact code or anything, just some concepts will do fine
Thanks!
I would say the solution you suggest yourself is not very good not only because you run SQL query every time a button is pressed, but also because you are iterating over primary keys, which probably are not sorted in any meaningful order...
What you want is to retrieve a certain number of records which are sorted sensibly (by first/last name or something) and keep them as a kind of cache in your ArrayList or something similar... This can be done quite easily with SQL. When the user starts iterating over the results by pressing "Next", you can in the background start loading more records.
The key to keep usability is to load some records before the user actually request them to keep latency small, but keeping in mind that you also don't want to load the whole database at once....
Take a look at indexing your database. http://www.informit.com/articles/article.aspx?p=377652
Use JPA with the built in Hibernate provider. If you are not familiar with one or both, then download NetBeans - it includes a very easy to follow tutorial you can use to get up to speed. Managing lists of objects is trivial with the new JPA and you won't find yourself reinventing the wheel.
the key concept here is pagination.
Let's say you set your page size to 10. This means you select 10 records from the database, in a certain order, so your query should have an order by clause and a limit clause at the end. You use this resultset to display the form while the users navigates with Previous/Next buttons.
When the user navigates out of the page then you fetch an other page.
https://www.google.com/search?q=java+sql+pagination
I am authoring a javabean and would like to know if it should include properties to set values obtained from a sql join?
Say I have database tables for Products and Orders. These are also my java bean names.
Now I want to display a list of all products but in addition to all the product properties, I want to have columns to display last purchase date and last purchased by
My db query to get the product list would need to do joins to gather the additional info. It does not seem correct to have setters and getters for `last purchase date and last purchased by' in Product.java model. I may want to have a 3rd column so constantly adding new columns to my bean doesn't make sense.
How do you go about this? I seem to encounter this when needing to display lists of models in my view.
Have a Map in Product. Upon firing the sql, store hte results of the join as key value pair in the Map. K=lastpurchasedby(columnName) and V= the value
So no need to add individual attributes. They all come in key-value pairs.