DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

The Latest Integration Topics

article thumbnail
IBatis (MyBatis): Working with Stored Procedures
this tutorial will walk you through how to setup ibatis ( mybatis ) in a simple java project and will present how to work with stored procedures using mysql.the goal os this tutorial is to demonstrate how to execute/call stored procedures using ibatis/ mybatis . pre-requisites for this tutorial i am using: ide: eclipse (you can use your favorite one) database: mysql libs/jars: mybatis , mysql conector and junit (for testing) this is how your project should look like: sample database please run the script into your database before getting started with the project implementation. you will find the script (with dummy data) inside the sql folder. as we are going to work with stored procedures, you will also have to execute a script with procedures. here are the procedures: use `blog_ibatis`;drop procedure if exists `gettotalcity`;delimiter $$use `blog_ibatis`$$create procedure `blog_ibatis`.`gettotalcity` (out total integer)begin select count(*) into total from city;end$$delimiter ; -- -------------------------------------------------------------------------------- use `blog_ibatis`;drop procedure if exists `gettotalcitystateid`;delimiter $$use `blog_ibatis`$$create procedure `blog_ibatis`.`gettotalcitystateid` (in stateid smallint, out total integer)begin select count(*) into total from city where state_id = stateid;end$$delimiter ; -- -------------------------------------------------------------------------------- use `blog_ibatis`;drop procedure if exists `getstates`;delimiter $$use `blog_ibatis`$$create procedure `blog_ibatis`.`getstates` ()begin select state_id, state_code, state_name from state;end$$delimiter ; 1 – spmapper – xml i did not find anything on the user manual about how to call stored procedures, so i decided to search on the mailing list. and i found some tips of how to call stores procedures. on the previous version, ibatis has a special xml tag for stored procedures. but there is no xml tag for it on current mybatis version (version 3). to call a stored procedure usgin mybatis/ibatis 3 you will have to follow some tips: must set the statement type to callable must use the jdbc standard escape sequence for stored procedures: { call xxx (parm1, parm2) } must set the mode of all parameters ( in, out, inout ) all in, out, and inout parameters must be a part of the parametertype or parametermap (discouraged). the only exception is if you are using a map as a parameter object. in that case you do not need to add out parameters to the map before calling , mybatis will add them for you automatically. resulttype or resultmap (more typically) is only used if the procedure returns a result set. important : oracle ref cursors are usually returned as parameters, not directly from the stored proc. so with ref cursors, resultmap and/or resulttype is usually not used. first example: we want to call the procedure gettotalcity and this procedure only have one out parameter, and no in/inout parameter. how to do it? we are going to ser inline parameters in this first example. to use inline parameters, create a pojo class to represent your parameters, set the parametertype to the class you created and you are going to use this notation to represent each parameter: #{parametername, mode=out, jdbctype=integer} mode can be in, out, inout and specify the jdbctype of your parameter to create the mybatis xml configuration, you can use the select ou update tag. do not forget to set the statementtype to callable . here is how our mybatis statement is going to look like: { call gettotalcity(#{total, mode=out, jdbctype=integer})} and this is the pojo class which represents the parameter for gettotalcity procedure: package com.loiane.model; public class param { private int total; public int gettotal() { return total; } public void settotal(int total) { this.total = total; } second example: now we are going to try to call the same stored procedure we demonstrated on the first example, but we are going to use a parametermap, like you used to do in version 2.x. a very important note: this is discouraged, please use inline parameters. let’s declare the param pojo class as a parametermap: and the stored procedure statment: { call gettotalcity(?) } note that now we use “ ? ” (question mark) to represent each parameter. third example: now we are going to call a stored procedure with in and out parameters. let’s follow the same rules as the fisrt example. we are going to use inline parameters and we are going to create a pojo class to represent our parameter. mybatis code: { call gettotalcitystateid( #{stateid, mode=in, jdbctype=integer}, #{total, mode=out, jdbctype=integer})} param2 pojo: package com.loiane.model; public class param2 { private int total; private int stateid; public int gettotal() { return total; } public void settotal(int total) { this.total = total; } public int getstateid() { return stateid; } public void setstateid(int stateid) { this.stateid = stateid; } fourth example: now let’s try to retrieve a resultset from the stored procedure. for this we are going to use a resultmap. { call getstates()} state pojo class: package com.loiane.model; public class state { private int id; private string code; private string name; public int getid() { return id; } public void setid(int id) { this.id = id; } public string getcode() { return code; } public void setcode(string code) { this.code = code; } public string getname() { return name; } public void setname(string name) { this.name = name; } 2- spmapper – annotations now let’s try to do the same thing we did using xml config. annotation for first example (xml): @select(value= "{ call gettotalcity( #{total, mode=out, jdbctype=integer} )}")@options(statementtype = statementtype.callable)object callgettotalcityannotations(param param); it is very similiar to a simple select statement, but we have to set the statement type to callable. to do it, we can use the annotation @options . with annotations, we can only use inline parameters, so we will not be able to represent the second exemple using annotations. annotation for third example (xml): the explanation is the same as first example, i am just going to list the code: @select(value= "{ call gettotalcitystateid( #{stateid, mode=in, jdbctype=integer}, #{total, mode=out, jdbctype=integer})}")@options(statementtype = statementtype.callable)object callgettotalcitystateidannotations(param2 param2); annotation for fourth example (xml): i tried to set the fourth example with annotation, but the only thing i’ve got is this: //todo: set resultmap with annotations/*@select(value= "{ call gettotalcitystateid()}")@options(statementtype = statementtype.callable)/*@results(value = { @result(property="id", column="state_id"), @result(property="name", column="state_name"), @result(property="code", column="state_code"),})*/list callgetstatesannotations(); and it does not work. i tried to search on the mailing list, no luck. i could not find a way to represent a resultmap with annotation and stored procedures. i don’t know if it is a limitation. if you have any clue how to do it, please leave a comment, i will appreciate it! download if you want to download the complete sample project, you can get it from my github account: https://github.com/loiane/ibatis-stored-procedures if you want to download the zip file of the project, just click on download: there are more articles about ibatis to come. stay tooned! from http://loianegroner.com/2011/03/ibatis-mybatis-working-with-stored-procedures/
March 30, 2011
by Loiane Groner
· 105,471 Views · 1 Like
article thumbnail
IBatis (MyBatis): Working with Dynamic Queries (SQL)
this tutorial will walk you through how to setup ibatis ( mybatis ) in a simple java project and will present how to work with dynamic queries (sql). pre-requisites for this tutorial i am using: ide: eclipse (you can use your favorite one) database: mysql libs/jars: mybatis , mysql conector and junit (for testing) this is how your project should look like: sample database please run the script into your database before getting started with the project implementation. you will find the script (with dummy data) inside the sql folder. 1 – article pojo i represented the pojo we are going to use in this tutorial with a uml diagram, but you can download the complete source code in the end of this article. the goal of this tutorial is to demonstrate how to retrieve the article information from database using dynamic sql to filter the data. 2 – article mapper – xml one of the most powerful features of mybatis has always been its dynamic sql capabilities. if you have any experience with jdbc or any similar framework, you understand how painful it is to conditionally concatenate strings of sql together, making sure not to forget spaces or to omit a comma at the end of a list of columns. dynamic sql can be downright painful to deal with. while working with dynamic sql will never be a party, mybatis certainly improves the situation with a powerful dynamic sql language that can be used within any mapped sql statement. the dynamic sql elements should be familiar to anyone who has used jstl or any similar xml based text processors. in previous versions of mybatis, there were a lot of elements to know and understand. mybatis 3 greatly improves upon this, and now there are less than half of those elements to work with. mybatis employs powerful ognl based expressions to eliminate most of the other elements. if choose (when, otherwise) trim (where, set) foreach let’s explain each one with examples. 1 – first scenario : we want to retrieve all the articles from database with an optional filter: title. in other words, if user specify an article title, we are going to retrieve the articles that match with the title, otherwise we are going to retrieve all the articles from database. so we are going to implement a condition (if) : select id, title, author from article where id_status = 1 and title like #{title} 2 – second scenario : now we have two optional filters: article title and author. the user can specify both, none or only one filter. so we are going to implement two conditions: select id, title, author from article where id_status = 1 and title like #{title} and author like #{author} 3 – third scenario : now we want to give the user only one option: the user will have to specify only one of the following filters: title, author or retrieve all the articles from ibatis category. so we are going to use a choose element: select id, title, author from article where id_status = 1 and title like #{title} and author like #{author} and id_category = 3 4 – fourth scenario : take a look at all three statements above. they all have a condition in common: where id_status = 1. it means we are already filtering the active articles let’s remove this condition to make it more interesting. select id, title, author from article where title like #{title} and author like #{author} what if both title and author are null? we are going to have the following statement: select id, title, authorfrom articlewhere and what if only the author is not null? we are going to have the fololwing statement: select id, title, authorfrom articlewhereand author like #{author} and both fails! how to fix it? 5 – fifth scenario : we want to retrieve all the articles with two optional filters: title and author. to avoid the 4th scenatio, we are going to use a where element: select id, title, author from article title like #{title} and author like #{author} mybatis has a simple answer that will likely work in 90% of the cases. and in cases where it doesn’t, you can customize it so that it does. the where element knows to only insert “where” if there is any content returned by the containing tags. furthermore, if that content begins with “and” or “or”, it knows to strip it off. if the where element does not behave exactly as you like, you can customize it by defining your own trim element. for example,the trim equivalent to the where element is: select id, title, author from article title like #{title} and author like #{author} the overrides attribute takes a pipe delimited list of text to override, where whitespace is relevant. the result is the removal of anything specified in the overrides attribute, and the insertion of anything in the with attribute. you can also use the trim element with set. 6 – sixth scenario : the user will choose all the categories an article can belong to. so in this case, we have a list (a collection), and we have to interate this collection and we are going to use a foreach element: select id, title, author from article title like #{title} and author like #{author} the foreach element is very powerful, and allows you to specify a collection, declare item and index variables that can be used inside the body of the element. it also allows you to specify opening and closing strings, and add a separator to place in between iterations. the element is smart in that it won’t accidentally append extra separators. note : you can pass a list instance or an array to mybatis as a parameter object. when you do, mybatis will automatically wrap it in a map, and key it by name. list instances will be keyed to the name “list” and array instances will be keyed to the name “array”. the complete article.xml file looks like this: select id, title, author from article where id_status = 1 and title like #{title} select id, title, author from article where id_status = 1 and title like #{title} and author like #{author} select id, title, author from article where id_status = 1 and title like #{title} and author like #{author} and id_category = 3 select id, title, author from article title like #{title} and author like #{author} select id, title, author from article title like #{title} and author like #{author} select id, title, author from article where id_category in #{category} download if you want to download the complete sample project, you can get it from my github account: https://github.com/loiane/ibatis-dynamic-sql if you want to download the zip file of the project, just click on download: there are more articles about ibatis to come. stay tooned! happy coding! from http://loianegroner.com/2011/03/ibatis-mybatis-working-with-dynamic-queries-sql/
March 23, 2011
by Loiane Groner
· 72,581 Views
article thumbnail
IBatis (MyBatis): Discriminator Column Example – Inheritance Mapping Tutorial
This tutorial will walk you through how to setup iBatis (MyBatis) in a simple Java project and will present an example using a discriminator column, in another words it is a inheritance mapping tutorial. Pre-Requisites For this tutorial I am using: IDE: Eclipse (you can use your favorite one) DataBase: MySQL Libs/jars: Mybatis, MySQL conector and JUnit (for testing) This is how your project should look like: Sample Database Please run the script into your database before getting started with the project implementation. You will find the script (with dummy data) inside the sql folder. 1 – POJOs – Beans I represented the beans here with a UML model, but you can download the complete source code in the end of this article. As you can see on the Data Modeling Diagram and the UML diagram above, we have a class Employee and two subclasses: Developer and Manager. The goal of this tutorial is to retrieve all the Employees from the database, but these employees can be an instance of Developer or Manager, and we are going to use a discriminator column to see which class we are going to instanciate. 2 – Employee Mapper – XML Sometimes a single database query might return result sets of many different (but hopefully somewhat related) data types. The discriminator element was designed to deal with this situation, and others, including class inheritance hierarchies. The discriminator is pretty simple to understand, as it behaves much like a switch statement in Java. A discriminator definition specifies column and javaType attributes. The column is where MyBatis will look for the value to compare. The javaType is required to ensure the proper kind of equality test is performed (although String would probably work for almost any situation). SELECT id, name, employee_type, manager_id, info, developer_id, product FROM employee E left join manager M on M.employee_id = E.id left join developer D on D.employee_id = E.id In this example, MyBatis would retrieve each record from the result set and compare its employee type value. If it matches any of the discriminator cases, then it will use the resultMap specified by the case. This is done exclusively, so in other words, the rest of the resultMap is ignored (unless it is extended, which we talk about in a second). If none of the cases match, then MyBatis simply uses the resultMap as defined outside of the discriminator block. So, if the managerResult was declared as follows: Now all of the properties from both the managerResult and developerResult will be loaded. Once again though, some may find this external definition of maps somewhat tedious. Thereforethere’s an alternative syntax for those that prefer a more concise mapping style. For example: SELECT id, name, employee_type, manager_id, info, developer_id, product FROM employee E left join manager M on M.employee_id = E.id left join developer D on D.employee_id = E.id Remember that these are all Result Maps, and if you don’t specify any results at all, then MyBatis willautomatically match up columns and properties for you. So most of these examples are more verbosethan they really need to be. That said, most databases are kind of complex and it’s unlikely that we’ll beable to depend on that for all cases. 3 - Employee Mapper – Annotations We did the configuration in XML, now let’s try to use annotations to do the same thing we did using XML. This is the code for EmployeeMapper.java: package com.loiane.data; import java.util.List; import org.apache.ibatis.annotations.Case;import org.apache.ibatis.annotations.Result;import org.apache.ibatis.annotations.Select;import org.apache.ibatis.annotations.TypeDiscriminator; import com.loiane.model.Developer;import com.loiane.model.Employee;import com.loiane.model.Manager; public interface EmployeeMapper { final String SELECT_EMPLOYEE = "SELECT id, name, employee_type, manager_id, info, developer_id, product " + "FROM employee E left join manager M on M.employee_id = E.id " + "left join developer D on D.employee_id = E.id "; /** * Returns the list of all Employee instances from the database. * @return the list of all Employee instances from the database. */ @Select(SELECT_EMPLOYEE) @TypeDiscriminator(column = "employee_type", cases = { @Case (value="1", type = Manager.class, results={ @Result(property="managerId", column="manager_id"), @Result(property="info"), }), @Case (value="2", type = Developer.class, results={ @Result(property="developerId", column="developer_id"), @Result(property="project", column="product"), }) }) List getAllEmployeesAnnotation();} If you are reading this blog lately, you are already familiar with the @Select and @Result annotations. So let’s skip it. Let’s talk about the @TypeDiscriminator and @Case annotations. @TypeDiscriminator A group of value cases that can be used to determine the result mapping to perform. Attributes: column, javaType, jdbcType, typeHandler, cases. The cases attribute is an array of Cases. @Case A single case of a value and its corresponding mappings. Attributes: value, type, results. The results attribute is an array of Results, thus this Case Annotation is similar to an actual ResultMap, specified by the Results annotation below. In this example: We set the column atribute for @TypeDiscriminator to determine which column MyBatis will look for the value to compare. And we set an array of @Case. For each @Case we set the value, so if the column matches the value, MyBatis will instanciate a object of type we set and we also set an array of @Result to match column with class atribute. Note one thing: using XML we set the id and name properties. We did not set these properties using annotations. It is not necessary, because the column matches the atribute name. But if you need to set, it is going to look like this: @Select(SELECT_EMPLOYEE)@Results(value = { @Result(property="id"), @Result(property="name")})@TypeDiscriminator(column = "employee_type", cases = { @Case (value="1", type = Manager.class, results={ @Result(property="managerId", column="manager_id"), @Result(property="info"), }), @Case (value="2", type = Developer.class, results={ @Result(property="developerId", column="developer_id"), @Result(property="project", column="product"), })})List getAllEmployeesAnnotation(); 4 – EmployeeDAO In the DAO, we have two methods: the first one will call the select statement from the XML and the second one will call the annotation method. Both returns the same result. package com.loiane.dao; import java.util.List; import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory; import com.loiane.data.EmployeeMapper;import com.loiane.model.Employee; public class EmployeeDAO { /** * Returns the list of all Employee instances from the database. * @return the list of all Employee instances from the database. */ @SuppressWarnings("unchecked") public List selectAll(){ SqlSessionFactory sqlSessionFactory = MyBatisConnectionFactory.getSqlSessionFactory(); SqlSession session = sqlSessionFactory.openSession(); try { List list = session.selectList("Employee.getAllEmployees"); return list; } finally { session.close(); } } /** * Returns the list of all Employee instances from the database. * @return the list of all Employee instances from the database. */ public List selectAllUsingAnnotations(){ SqlSessionFactory sqlSessionFactory = MyBatisConnectionFactory.getSqlSessionFactory(); SqlSession session = sqlSessionFactory.openSession(); try { EmployeeMapper mapper = session.getMapper(EmployeeMapper.class); List list = mapper.getAllEmployeesAnnotation(); return list; } finally { session.close(); } } The output if you call one of these methods and print: Employee ID = 1 Name = Kate Manager ID = 1 Info = info KateEmployee ID = 2 Name = Josh Developer ID = 1 Project = webEmployee ID = 3 Name = Peter Developer ID = 2 Project = desktopEmployee ID = 4 Name = James Manager ID = 2 Info = info JamesEmployee ID = 5 Name = Susan Developer ID = 3 Project = web Download If you want to download the complete sample project, you can get it from my GitHub account: https://github.com/loiane/ibatis-discriminator If you want to download the zip file of the project, just click on download: There are more articles about iBatis to come. Stay tooned! From http://loianegroner.com/2011/03/ibatis-mybatis-discriminator-column-example-inheritance-mapping-tutorial/
March 22, 2011
by Loiane Groner
· 34,125 Views
article thumbnail
IBatis (MyBatis): Handling Constructors
this tutorial will walk you through how to setup ibatis ( mybatis ) in a simple java project and will present an example using a class constructor with arguments. pre-requisites for this tutorial i am using: ide: eclipse (you can use your favorite one) database: mysql libs/jars: mybatis , mysql conector and junit (for testing) this is how your project should look like: sample database please run the script into your database before getting started with the project implementation. you will find the script (with dummy data) inside the sql folder. 1 – pojo i represented the beans here with a uml model, but you can download the complete source code in the end of this article. as you can see, we do not have a default construtor in this class, only a constructor with some arguments. some persistence frameworks requires a default constructor, but you have to be careful with your business logic. let’s say there are a couple of mandatory atributes in your class. nothing is going to stop you if you do not set these atributes and try to insert, update on the database. and you problably will get an exception for that. to prevent this kind of situation, you can create a constructor with the mandatory arguments. and ibatis/ mybatis can handle this situation for you, because you do not need to create a default constructor. 2 – blog mapper – xml while properties will work for most data transfer object (dto) type classes, and likely most of yourdomain model, there may be some cases where you want to use immutable classes. often tables thatcontain reference or lookup data that rarely or never changes is suited to immutable classes.constructor injection allows you to set values on a class upon instantiation, without exposing publicmethods. mybatis also supports private properties and private javabeans properties to achieve this, butsome people prefer constructor injection. the constructor element enables this. in order to inject the results into the constructor, mybatis needs to identify the constructor by the type of its parameters. java has no way to introspect (or reflect) on parameter names. so when creating a constructor element, ensure that the arguments are in order, and that the data types are specified. if you need, you can still map another attributes, such as association, collection in your resultmap. following is the blog.xml file: select idblog as id, name, url from blog 3 - blog mapper – annotations we did the configuration in xml, now let’s try to use annotations to do the same thing we did using xml. this is the code for blogmapper.java: package com.loiane.data; import java.util.list; import org.apache.ibatis.annotations.arg; import org.apache.ibatis.annotations.constructorargs; import org.apache.ibatis.annotations.select; import com.loiane.model.blog; public interface blogmapper { /** * returns the list of all blog instances from the database. * @return the list of all blog instances from the database. */ @select("select idblog as id, name, url from blog ") @constructorargs(value = { @arg(column="id",javatype=integer.class), @arg(column="url",javatype=string.class) }) list selectallblogs(); } let’s take a look at the @constructorargs and @arg annotations: @constructorargs collects a group of results to be passed to a result object constructor. attributes: value, which is an array of args. xml equivalent: constructor @arg a single constructor argument that is part of a constructorargs collection. attributes: id, column, javatype, jdbctype, typehandler. the id attribute is a boolean value that identifies the property to be used for comparisons, similar to the xml element. xml equivalent: idarg, arg we do not need to use the @results annotation because the other attributes has the same name, so mybatis knows how to map them. download if you want to download the complete sample project, you can get it from my github account: https://github.com/loiane/ibatis-constructor if you want to download the zip file of the project, just click on download: there are more articles about ibatis to come. stay tooned! happy coding! once again though, some may find this external definition of maps somewhat tedious. thereforethere’s an alternative syntax for those that prefer a more concise mapping style.
March 12, 2011
by Loiane Groner
· 19,677 Views
article thumbnail
IBatis (MyBatis): Handling Joins: Advanced Result Mapping, Association, Collections, N+1 Select Problem
This tutorial will present examples using advanced result mappings, how to handle mappings with association, collections, the n+1 problem, and more.
March 2, 2011
by Loiane Groner
· 121,309 Views · 3 Likes
article thumbnail
The Easiest Ways to Navigate Methods in a Class using Eclipse Keyboard Shortcuts
java classes can get big and hairy, making it difficult to find the method you’re looking for when browsing or editing a class. there is no specific order to where methods can be in a class and different developers have different preferences about where to put them. you could use the mouse wheel and scroll ferociously until you eventually find the method or you could even use page down/page up on your keyboard. but these methods can be time-consuming and haphazard, especially when the class has lots of methods or they’re scattered in an arbitrary order. luckily, eclipse has a number of fast and easy ways to help you navigate methods in a class, especially using the keyboard. i’ll discuss some of those keyboard shortcuts and also which ones to use when. quick outline the quick outline is basically a scaled-down popup version of the outline view. the main advantage over the outline view is that it has a search box that allows you to search for a method. here’s how to use the quick outline: press ctrl+o from anywhere within the class. type a search term in the search box and eclipse will just show all methods that match the search term. by default eclipse does an exact match search, but you can use wildcards. once you see the method you’re interested in, press down to select the method (if it’s not selected already). press enter once the method is selected. eclipse will take you directly to the method’s declaration. this is an example of the popup for java’s arraylist . searching for *rem will search for all method names that contain the word rem . here’s an example: notes: sort the view using the the down arrow menu in the top right corner. it makes it easier to find methods by scanning. resize the quick outline popup to see more methods. eclipse remembers the size of the popup for the next time you open it. next member & previous member another way to move between methods is to use two features called go to next member and go to previous member. when you press ctrl+shift+down , eclipse moves the cursor to the next method in the class. pressing ctrl+shift+up moves to the previous method. here’s a video to give you a quick example of how these shortcuts work: this shortcut works best if you’re already positioned in a method or if the class has few fields. that’s because to eclipse a member can either be a method or a field. if you’re at the top of the class, you have to move through all the fields before you actually start moving through the methods themselves, a time-consuming process especially for bigger classes with lots of fields. it helps to generate getters and setters at the bottom of the class because you don’t have to navigate through them to get to the useful methods. open declaration if you’ve got lots of private methods in your class then open declaration might be the best way to navigate between them. when you’re positioned on a method call and press f3 , eclipse takes you directly to the definition of that method. for example, if you’re busy in the method process() and your cursor’s positioned on initprocessing() , pressing f3 will take you directly to the declaration for that method further down the class. public void process() { //do things... initprocessing(); //... } ... private void initprocessing() { //init something... } this feature works very well with alt+left (backward history). see the section below for more details about the backward history. navigating back to a previously viewed method while browsing code, you’ll often want to return to the previous method you were viewing once you’re done viewing the method it calls. to do this, use alt+left (backward history) to move back to the last navigation point. this feature isn’t specific to just methods, but also works for navigating between previously visited editors. but it works great if you’ve just been browsing methods within a class. quick mentions eclipse’s outline view also allows easy navigation but mostly with the mouse. you could navigate to the view using alt+shift+q, o , and you can move to methods by typing their first letter, but i’ve found the quick outline to be more keyboard friendly. also, the outline view doesn’t support wildcard searches. you can also use eclipse’s call hierarchy ( ctrl+alt+h ) especially if you’re trying to understand the flow of methods in a class and move between them easily. knowing how to navigate between views and editors with the keyboard helps a lot since you’ll be moving between the call hierarchy view and editors a lot. what should i use when? use next/previous member shortcut if the class is small or you have a good idea of where other methods are in relation to the current method (eg. are they above/below the current method). use the quick outline if you don’t know the class too well or there are lots of methods in the class. use open declaration if you’re moving between many private methods of the class. it’s normally the fastest way to move to another private method in the class, but only if you’re already positioned in a method that calls it. from http://eclipseone.wordpress.com/2011/02/21/the-easiest-ways-to-navigate-methods-in-a-class-using-eclipse-keyboard-shortcuts/
February 22, 2011
by Byron M
· 66,642 Views · 2 Likes
article thumbnail
Getting Started with iBatis (MyBatis): Annotations
This tutorial will walk you through how to setup iBatis (MyBatis) in a simple Java project and will present examples using simple insert, update, select and delete statements using annotations. This is the third tutorial of the iBatis/MyBatis series, you can read the first 2 tutorials on the following links: Introduction to iBatis (MyBatis), An alternative to Hibernate and JDBC Getting Started with iBatis (MyBatis): XML Configuration iBatis/ MyBatis 3 offers a new feature: annotations. But it lacks examples and documentation about annotations. I started to explore and read the MyBatis mailing list archive to write this tutorial. Another thing you will notice is the limitation related to annotations. I am going to demonstrate some examples that you can do with annotations in this tutorial. All the power of iBatis is in its XMl configuration. So let’s play a little bit with annotations. It is much simpler and you can use it for simple queries in small projects. As I already mentioned, if you want something more complex, you will have to use XML configuration. One more thing before we get started: this tutorial is the same as the previous one, but instead of XML, we are going to use annotations. Pre-Requisites For this tutorial I am using: IDE: Eclipse (you can use your favorite one) DataBase: MySQL Libs/jars: Mybatis, MySQL conector and JUnit (for testing) This is how your project should look like: Sample Database Please run this script into your database before getting started with the project implementation: I will not post the sample database here again. You can get it from the previous post about iBatis or download this sample project. The files are the same. 1 – Contact POJO We will create a POJO class first to respresent a contact with id, name, phone number and email address – same as previous post. 2 – ContactMapper In this file, we are going to set up all the queries using annotations. It is the MyBatis-Interface for the SQLSessionFactory. A mapper class is simply an interface with method definitions that match up against the SqlSession methods. Mapper interfaces do not need to implement any interface or extend any class. As long as the method signature can be used to uniquely identify a corresponding mapped statement. Mapper interfaces can extend other interfaces. Be sure that you have the statements in the appropriate namespace when using XML binding to Mapper interfaces. Also, the only limitation is that you cannot have the same method signature in two interfaces in a hierarchy (a bad idea anyway). A mapperclass is simply an interface with method definitions that match up against the SqlSession methods. You can create some strings with the SQL code. Remember it has to be the same code as in XML Configuration. package com.loiane.data; import java.util.List; import org.apache.ibatis.annotations.Delete;import org.apache.ibatis.annotations.Insert;import org.apache.ibatis.annotations.Options;import org.apache.ibatis.annotations.Param;import org.apache.ibatis.annotations.Result;import org.apache.ibatis.annotations.Results;import org.apache.ibatis.annotations.Select;import org.apache.ibatis.annotations.Update; import com.loiane.model.Contact; public interface ContactMapper { final String SELECT_ALL = "SELECT * FROM CONTACT"; final String SELECT_BY_ID = "SELECT * FROM CONTACT WHERE CONTACT_ID = #{id}"; final String UPDATE = "UPDATE CONTACT SET CONTACT_EMAIL = #{email}, CONTACT_NAME = #{name}, CONTACT_PHONE = #{phone} WHERE CONTACT_ID = #{id}"; final String UPDATE_NAME = "UPDATE CONTACT SET CONTACT_NAME = #{name} WHERE CONTACT_ID = #{id}"; final String DELETE = "DELETE FROM CONTACT WHERE CONTACT_ID = #{id}"; final String INSERT = "INSERT INTO CONTACT (CONTACT_EMAIL, CONTACT_NAME, CONTACT_PHONE) VALUES (#{name}, #{phone}, #{email})"; /** * Returns the list of all Contact instances from the database. * @return the list of all Contact instances from the database. */ @Select(SELECT_ALL) @Results(value = { @Result(property="id", column="CONTACT_ID"), @Result(property="name", column="CONTACT_NAME"), @Result(property="phone", column="CONTACT_PHONE"), @Result(property="email", column="CONTACT_EMAIL") }) List selectAll(); /** * Returns a Contact instance from the database. * @param id primary key value used for lookup. * @return A Contact instance with a primary key value equals to pk. null if there is no matching row. */ @Select(SELECT_BY_ID) @Results(value = { @Result(property="id"), @Result(property="name", column="CONTACT_NAME"), @Result(property="phone", column="CONTACT_PHONE"), @Result(property="email", column="CONTACT_EMAIL") }) Contact selectById(int id); /** * Updates an instance of Contact in the database. * @param contact the instance to be updated. */ @Update(UPDATE) void update(Contact contact); /** * Updates an instance of Contact in the database. * @param name name value to be updated. * @param id primary key value used for lookup. */ void updateName(@Param("name") String name, @Param("id") int id); /** * Delete an instance of Contact from the database. * @param id primary key value of the instance to be deleted. */ @Delete(DELETE) void delete(int id); /** * Insert an instance of Contact into the database. * @param contact the instance to be persisted. */ @Insert(INSERT) @Options(useGeneratedKeys = true, keyProperty = "id") void insert(Contact contact);} @Select The @Select annotation is very simple. Let’s take a look at the first select statment of this class: selectAll. Note that you don’t need to use the mapping if your database table columns mach the name of the class atributes. I used different names to use the @Result annotation. If table columns match with atribute names, you don’t need to use the @Result annotation. Not let’s take a look on the second method: selectById. Notice that we have a parameter. It is a simple parameter – easy to use when you have a single parameter. @Update Let’s say you want to update all the columns. You can pass the object as parameter and iBatis will do all the magic for you. Remember to mach the parameter name with the atribute name, otherwise iBatis can get confused, Now let’s say you want to use 2 or 3 paramaters, and they don’t belong to an object. If you take a look at iBatis XML configuration you will see you have to set the option parameterType (remember?) and specify you parameter type in it, in another words, you can use only one parameter. If you are using annotation, you can use more than one parameter using the @Param annotation. @Delete The @Delete annotation is also very simple. It follows the previous rules related to parameters. @Insert The @Insert annotation also follows the rules related to parameters. You can use an object or use the @Param annotation to specify more than one parameter. What about the generation key? Well, if your database supports auto generation key, you can set it up using annotations with the @Options annotation. You will need to specify the option useGeneratedKeys and keyProperty. If your database does not support auto generation key, sorry, but I still did not figure out how to do it (in last case, use can do it manually and then pass as parameter to your insert query). 3 – MyBatisConnectionFactory Every MyBatis application centers around an instance of SqlSessionFactory. A SqlSessionFactory instance can be acquired by using the SqlSessionFactoryBuilder. SqlSessionFactoryBuilder can build a SqlSessionFactory instance from an XML configuration file, of from a custom prepared instance of the Configuration class. An observation about this file: on the previous example, we set the mappers on the iBatis Configuration XML file. Using annotations, we will set the mapper manually. In a future example, I’ll show you how to work with XML and Annotations together. package com.loiane.dao; import java.io.FileNotFoundException;import java.io.IOException;import java.io.Reader; import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder; import com.loiane.data.ContactMapper; public class MyBatisConnectionFactory { private static SqlSessionFactory sqlSessionFactory; static { try { String resource = "SqlMapConfig.xml"; Reader reader = Resources.getResourceAsReader(resource); if (sqlSessionFactory == null) { sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); sqlSessionFactory.getConfiguration().addMapper(ContactMapper.class); } } catch (FileNotFoundException fileNotFoundException) { fileNotFoundException.printStackTrace(); } catch (IOException iOException) { iOException.printStackTrace(); } } public static SqlSessionFactory getSqlSessionFactory() { return sqlSessionFactory; } } 4 – ContactDAO Now that we set up everything needed, let’s create our DAO. To call the sql statments, we need to do one more configuration, that is to set and get the mapper from the SqlSessionFactory. Then we just need to call the mapper method. It is a little bit different, but it does the same thing. package com.loiane.dao; import java.util.List; import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory; import com.loiane.data.ContactMapper;import com.loiane.model.Contact; public class ContactDAO { private SqlSessionFactory sqlSessionFactory; public ContactDAO(){ sqlSessionFactory = MyBatisConnectionFactory.getSqlSessionFactory(); } /** * Returns the list of all Contact instances from the database. * @return the list of all Contact instances from the database. */ public List selectAll(){ SqlSession session = sqlSessionFactory.openSession(); try { ContactMapper mapper = session.getMapper(ContactMapper.class); List list = mapper.selectAll(); return list; } finally { session.close(); } } /** * Returns a Contact instance from the database. * @param id primary key value used for lookup. * @return A Contact instance with a primary key value equals to pk. null if there is no matching row. */ public Contact selectById(int id){ SqlSession session = sqlSessionFactory.openSession(); try { ContactMapper mapper = session.getMapper(ContactMapper.class); Contact list = mapper.selectById(id); return list; } finally { session.close(); } } /** * Updates an instance of Contact in the database. * @param contact the instance to be updated. */ public void update(Contact contact){ SqlSession session = sqlSessionFactory.openSession(); try { ContactMapper mapper = session.getMapper(ContactMapper.class); mapper.update(contact); session.commit(); } finally { session.close(); } } /** * Updates an instance of Contact in the database. * @param name name value to be updated. * @param id primary key value used for lookup. */ public void updateName(String name, int id){ SqlSession session = sqlSessionFactory.openSession(); try { ContactMapper mapper = session.getMapper(ContactMapper.class); mapper.updateName(name, id); session.commit(); } finally { session.close(); } } /** * Insert an instance of Contact into the database. * @param contact the instance to be persisted. */ public void insert(Contact contact){ SqlSession session = sqlSessionFactory.openSession(); try { ContactMapper mapper = session.getMapper(ContactMapper.class); mapper.insert(contact); session.commit(); } finally { session.close(); } } /** * Delete an instance of Contact from the database. * @param id primary key value of the instance to be deleted. */ public void delete(int id){ SqlSession session = sqlSessionFactory.openSession(); try { ContactMapper mapper = session.getMapper(ContactMapper.class); mapper.delete(id); session.commit(); } finally { session.close(); } } 5 – Mapper Configuration File The MyBatis XML configuration file contains settings and properties that have a dramatic effect on how MyBatis behaves. This time, we do not need to configure alias or xml config files. We did all the magic with annotations, so we have a simple config file with only the information about the database we want to connect with. Download I suggest you to take a look at the org.apache.ibatis.annotations package and try to find out what each annotation can do. Unfortunatelly, you won’t find much documentation or examples on MyBatis website. I also created a TestCase class. If you want to download the complete sample project, you can get it from my GitHub account: https://github.com/loiane/ibatis-annotations-helloworld If you want to download the zip file of the project, just click on download: There are more articles about iBatis to come. Stay tooned! In next articles, I’m going to demonstrate how to implement the feature using XML and then Annotations (when it is possible). Happy Coding! From http://loianegroner.com/2011/02/getting-started-with-ibatis-mybatis-annotations/
February 22, 2011
by Loiane Groner
· 72,143 Views
article thumbnail
Getting Started with iBatis (MyBatis): XML Configuration
This tutorial will walk you through how to setup iBatis (MyBatis) in a simple Java project and will present examples using simple insert, update, select and delete statements.
February 18, 2011
by Loiane Groner
· 112,569 Views
article thumbnail
Introduction to iBatis (MyBatis), An alternative to Hibernate and JDBC
i started to write a new article series about ibatis / mybatis . this is the first article and it will walk you through what is ibatis / mybatis and why you should use it. for those who does not know ibatis / mybatis yet, it is a persistence framework – an alternative to jdbc and hibernate , available for java and .net platforms. i’ve been working with it for almost two years, and i am enjoying it! the first thing you may notice in this and following articles about ibatis/mybatis is that i am using both ibatis and mybatis terms. why? until june 2010, ibatis was under apache license and since then, the framework founders decided to move it to google code and they renamed it to mybatis. the framework is still the same though, it just has a different name now. i gathered some resources, so i am just going to quote them: what is mybatis/ibatis? the mybatis data mapper framework makes it easier to use a relational database with object-oriented applications. mybatis couples objects with stored procedures or sql statements using a xml descriptor. simplicity is the biggest advantage of the mybatis data mapper over object relational mapping tools.to use the mybatis data mapper, you rely on your own objects, xml, and sql. there is little to learn that you don’t already know. with the mybatis data mapper, you have the full power of both sql and stored procedures at your fingertips. ( www.mybatis.org ) ibatis is based on the idea that there is value in relational databases and sql, and that it is a good idea to embrace the industrywide investment in sql. we have experiences whereby the database and even the sql itself have outlived the application source code, and even multiple versions of the source code. in some cases we have seen that an application was rewritten in a different language, but the sql and database remained largely unchanged. it is for such reasons that ibatis does not attempt to hide sql or avoid sql. it is a persistence layer framework that instead embraces sql by making it easier to work with and easier to integrate into modern object-oriented software. these days, there are rumors that databases and sql threaten our object models, but that does not have to be the case. ibatis can help to ensure that it is not. ( ibatis in action book) so… what is ibatis ? a jdbc framework developers write sql, ibatis executes it using jdbc. no more try/catch/finally/try/catch. an sql mapper automatically maps object properties to prepared statement parameters. automatically maps result sets to objects. support for getting rid of n+1 queries. a transaction manager ibatis will provide transaction management for database operations if no other transaction manager is available. ibatis will use external transaction management (spring, ejb cmt, etc.) if available. great integration with spring, but can also be used without spring (the spring folks were early supporters of ibatis). what isn’t ibatis ? an orm does not generate sql does not have a proprietary query language does not know about object identity does not transparently persist objects does not build an object cache essentially, ibatis is a very lightweight persistence solution that gives you most of the semantics of an o/r mapping toolkit, without all the drama. in other words ,ibatis strives to ease the development of data-driven applications by abstracting the low-level details involved in database communication (loading a database driver, obtaining and managing connections, managing transaction semantics, etc.), as well as providing higher-level orm capabilities (automated and configurable mapping of objects to sql calls, data type conversion management, support for static queries as well as dynamic queries based upon an object’s state, mapping of complex joins to complex object graphs, etc.). ibatis simply maps javabeans to sql statements using a very simple xml descriptor. simplicity is the key advantage of ibatis over other frameworks and object relational mapping tools.( http://www.developersbook.com ) who is using ibatis/mybatis? see the list in this link: http://www.apachebookstore.com/confluence/oss/pages/viewpage.action?pageid=25 i think the biggest case is myspace , with millions of users. very nice! this was just an introduction, so in next articles i will show how to create an application using ibatis/mybatis – step-by-step. enjoy! from http://loianegroner.com/2011/02/introduction-to-ibatis-mybatis-an-alternative-to-hibernate-and-jdbc/
February 9, 2011
by Loiane Groner
· 42,444 Views · 5 Likes
article thumbnail
Simple RESTful web services with Glassfish
Here’s a quick guide to creating a RESTful web service with Glassfish using JAX-RS. First create a new maven project called restwebdemo using the jee6-sandbox-archetype so we have a model and some data to work with. To get this working with Glassfish, open the persistence.xml file and change the jta-data-source name to jdbc/__default. Also, make sure that the javaDB is up and running by going to $glassfish_dir/bin and typing asadmin start-database. Verify that the application is working correctly by going to http://localhost:8080/restwebdemo/ and you should get a list of courses. Before we start getting to the interesting stuff, we have one more boring piece of configuration to perform specific to web services. We need to add the jersey servlet container to our web.xml file: Jersey Web Application com.sun.jersey.spi.container.servlet.ServletContainer 1 Jersey Web Application /rest/* This also tells Jersey to handle urls starting with /rest and pass it along to our web service methods. Now we can dive right in an create a new server bean that will respond to requests for web services. For now we’ll just return a simple message from a POJO. @Path("sample") public class SimpleService { @Path("greet") @GET public String doGreet() { return "Hello Stranger, the time is "+ new Date(); } } The path annotation on the class indicates that this is a root resource class and the path value given specifies the base URI for all the web service methods contained in the class. On the doGreet method we have @Path which is used to specify the path template this method should match. The @GET annotation is used to differentiate between a sub-resource method that handles the actual web service request and a sub-resource locator method that returns an object that will instead be used to handle the request. In this case, the method has the @GET annotation which means this method handles the request and returns the result. If you navigate to http://localhost:8080/restwebdemo/rest/sample/greet/ you should see a welcome message with the current date and time. Now we’ll look at adding parameterized web services that extracts parameters from the request URL and uses them to form the output. Add the following method to the web service class: @Path("sayHello/{name}") @GET public String doSayHello(@PathParam("name") String name) { return "Hello there "+name; } Again we have the path annotation to indicate what URLs this method will match, and this time we have have {name} added to the URL. This lets us extract a part of the url and give it a name. This name is used in the @PathParam annotation in the method signature to assign the URL fragment to the name parameter . To test our new method, redeploy the application and go to the URL http://localhost:8080/restwebdemo/rest/sample/sayHello/Andy to get the response Hello there Andy We can also use request parameters to provide values to the method by using the @QueryParam annotation. We’ll create another method that is similar but uses a query parameter instead. @Path("sayHello") @GET public String doSayHelloWithRequestParam(@QueryParam("name") String name) { return "Hi there "+name; } This time, the URL to use is http://localhost:8080/restwebdemo/rest/sample/sayHello?name=Andy to get the same message. To make things more interesting, lets add a new page that lets us enter a name in a form and submit it to the web service. Add a new page called form.html with the following content : Name Go to this page at http://localhost:8080/restwebdemo/form.html, enter your name and click submit and you should be greeted by name in the next page. Notice that we had to set the form method to GET because our web service is only set up to respond to GET requests. If we change the form method to POST we can get the following error message : HTTP Status 405 - Method Not Allowed type Status report message Method Not Allowed description The specified HTTP method is not allowed for the requested resource (Method Not Allowed). Remember, with REST, those actual verbs have meaning and adds meaning to the request so it is strict on how it matches the method to be called. To solve this problem, we can add a new method to handle form POSTs like so : @Path("sayHello") @POST public String doSayHelloWithFormParam(@FormParam("name") String name) { return "Hi there " + name; } Here we changed the @GET to a @POST to allow the different verb and changed the annotation on the name method parameter to @FormParam. The path remains the same because we can have service methods that match the same path, but for different request verbs. We can even have the same verb and path as long as the content type returned is different. The content type is used to specify the type of output the is returned from the method. It is set by adding a @javax.ws.rs.Produces (not to be confused with the CDI Produces annotation). The annotation takes a string parameter that indicates the type of media returned from the method. Common media types are defined as constants in the MediaType class so you can use : @Path("sayHello") @POST @Produces(MediaType.APPLICATION_XML) public String doSayHelloWithFormParam(@FormParam("name") String name) { return "Hi there " + name+""; } If you run your form again, and post it, you will get an xml response as follows : Hi there Andy Depending on your browser, if you return just the text, you will get an error because the plain text isn’t valid XML and the browser expects XML because that is the response type set on the response from the web service. To finish up, we are going to do something a little more interesting, we will create a web service to return the name of a course from the database using the sandbox data built into the archetype. For various reasons, we will take the most direct route to getting data access which is to make the web service bean a stateless bean and inject a persistence context using the @PersistenceContext annotation. Add the @Stateless annotation to the SimpleService class and an entity manager field annotated with @PersistenceContext along with the getters and setters. Add a new method to return the course name for the given course id parameter. We will return it as text for the time being : @Path("courseName/{id}") @GET public String getCourseNameFromId(@PathParam("id") Long id) { Course c = entityManager.find(Course.class, id); if (c == null) { return "Not Found, try the index page and come back"; } else { return c.getTitle(); } } Note that the automatic type conversion takes place and the value is converted to a Long automatically. If the course is not found, we suggest the user goes to the main page of the demo. We aren’t just being overly helpful, the test data is generated when you request one of the application pages for the first time. In the current persistence context, when you redeploy, the database is dropped and rebuilt so it will be empty. You need to go to the front page to automatically create the data and then go back to your page to view the course. An example URL is http://localhost:8080/restwebdemo/rest/sample/courseName/124. Of course you could grab the course object and build your own XML or JSON response to send back to the client, or use a third party library like Jackson to build the JSON response. However, as we’ll see next time, Java EE 6 has all these goodies built in for us, and with a few annotations, we’ll be slinging objects back and forth in no time at all. You can download the source code for the project from here. Simply unzip, build with maven (mvn clean package) and deploy to Glassfish.
February 4, 2011
by Andy Gibson
· 60,771 Views
article thumbnail
Work with Multiple Instances of NetBeans IDE
Generally NetBeans IDE works with a default workspace. In this scenario, if you want to manage multiple sets of projects, you have to create a project group, which allows you to switch between project groups as and when required. But the problem in this is that if the workspace is damaged, and you delete it, all your settings are lost and everything is reset to the default NetBeans IDE settings. The solution is to work with multiple workspaces, that is, multiple instances, of NetBeans IDE. And here is how to do that: Right-click the NetBeans IDE shortcut and choose "Properties". In the shortcut tab, in Target, type after netbeans.exe "--userdir [Folder Path]". Make another shortcut of NetBeans IDE and provide a different folder path. Like this you can create as many workspaces as you want. If one workspace is damaged, it will not effect the settings of the others. Isn't that great? :) Also posted at: http://goo.gl/fb/rrvnA
February 1, 2011
by Ravindra Gullapalli
· 42,870 Views · 2 Likes
article thumbnail
Apache Solr: Get Started, Get Excited!
we've all seen them on various websites. crappy search utilities. they are a constant reminder that search is not something you should take lightly when building a website or application. search is not just google's game anymore. when a java library called lucene was introduced into the apache ecosystem, and then solr was built on top of that, open source developers began to wield some serious power when it came to customizing search features. in this article you'll be introduced to apache solr and a wealth of applications that have been built with it. the content is divided as follows: introduction setup solr applications summary 1. introduction apache solr is an open source search server. it is based on the full text search engine called apache lucene . so basically solr is an http wrapper around an inverted index provided by lucene. an inverted index could be seen as a list of words where each word-entry links to the documents it is contained in. that way getting all documents for the search query "dzone" is a simple 'get' operation. one advantage of solr in enterprise projects is that you don't need any java code, although java itself has to be installed. if you are unsure when to use solr and when lucene, these answers could help. if you need to build your solr index from websites, you should take a look into the open source crawler called apache nutch before creating your own solution. to be convinced that solr is actually used in a lot of enterprise projects, take a look at this amazing list of public projects powered by solr . if you encounter problems then the mailing list or stackoverflow will help you. to make the introduction complete i would like to mention my personal link list and the resources page which lists books, articles and more interesting material. 2. setup solr 2.1. installation as the very first step, you should follow the official tutorial which covers the basic aspects of any search use case: indexing - get the data of any form into solr. examples: json, xml, csv and sql-database. this step creates the inverted index - i.e. it links every term to its documents. querying - ask solr to return the most relevant documents for the users' query to follow the official tutorial you'll have to download java and the latest version of solr here . more information about installation is available at the official description . next you'll have to decide which web server you choose for solr. in the official tutorial, jetty is used, but you can also use tomcat. when you choose tomcat be sure you are setting the utf-8 encoding in the server.xml . i would also research the different versions of solr, which can be quite confusing for beginners: the current stable version is 1.4.1. use this if you need a stable search and don't need one of the latest features. the next stable version of solr will be 3.x the versions 1.5 and 2.x will be skipped in order to reach the same versioning as lucene. version 4.x is the latest development branch. solr 4.x handles advanced features like language detection via tika, spatial search , results grouping (group by field / collapsing), a new "user-facing" query parser ( edismax handler ), near real time indexing, huge fuzzy search performance improvements, sql join-a like feature and more. 2.2. indexing if you've followed the official tutorial you have pushed some xml files into the solr index. this process is called indexing or feeding. there are a lot more possibilities to get data into solr: using the data import handler (dih) is a really powerful language neutral option. it allows you to read from a sql database, from csv, xml files, rss feeds, emails, etc. without any java knowledge. dih handles full-imports and delta-imports. this is necessary when only a small amount of documents were added, updated or deleted. the http interface is used from the post tool, which you have already used in the official tutorial to index xml files. client libraries in different languages also exist. (e.g. for java (solrj) or python ). before indexing you'll have to decide which data fields should be searchable and how the fields should get indexed. for example, when you have a field with html in it, then you can strip irrelevant characters , tokenize the text into 'searchable terms', lower case the terms and finally stem the terms . in contrast, if you would have a field with text in it that should not be interpreted (e.g. urls) you shouldn't tokenize it and use the default field type string. please refer to the official documentation about field and field type definitions in the schema.xml file. when designing an index keep in mind the advice from mauricio : "the document is what you will search for. " for example, if you have tweets and you want to search for similar users, you'll need to setup a user index - created from the tweets. then every document is a user. if you want to search for tweets, then setup a tweet index; then every document is a tweet. of course, you can setup both indices with the multi index options of solr. please also note that there is a project called solr cell which lets you extract the relevant information out of several different document types with the help of tika. 2.3. querying for debugging it is very convenient to use the http interface with a browser to query solr and get back xml. use firefox and the xml will be displayed nicely: you can also use the velocity contribution , a cross-browser tool, which will be covered in more detail in the section about 'search application prototyping' . to query the index you can use the dismax handler or standard query handler . you can filter and sort the results: q=superman&fq=type:book&sort=price asc you can also do a lot more ; one other concept is boosting. in solr you can boost while indexing and while querying. to prefer the terms in the title write: q=title:superman^2 subject:superman when using the dismax request handler write: q=superman&qf=title^2 subject check out all the various query options like fuzzy search , spellcheck query input , facets , collapsing and suffix query support . 3. applications now i will list some interesting use cases for solr - in no particular order. to see how powerful and flexible this open source search server is. 3.1. drupal integration the drupal integration can be seen as generic use case to integrate solr into php projects. for the php integration you have the choice to either use the http interface for querying and retrieving xml or json. or to use the php solr client library . here is a screenshot of a typical faceted search in drupal : for more information about faceted search look into the wiki of solr . more php projects which integrates solr: open source typo3- solr module magento enterprise - solr module . the open source integration is out dated. oxid - solr module . no open source integration available. 3.2. hathi trust the hathi trust project is a nice example that proves solr's ability to search big digital libraries. to quote directly from the article : "... the index for our one million book index is over 200 gigabytes ... so we expect to end up with a two terabyte index for 10 million books" other examples for libraries: vufind - aims to replace opac internet archive national library of australia 3.3. auto suggestions mainly, there are two approaches to implement auto-suggestions (also called auto-completion) with solr: via facets or via ngramfilterfactory . to push it to the extreme you can use a lucene index entirely in ram. this approach is used in a large music shop in germany. live examples for auto suggestions: kaufda.de 3.4. spatial search applications when mentioning spatial search, people have geographical based applications in mind. with solr, this ordinary use case is attainable . some examples for this are : city search - city guides yellow pages kaufda.de spatial search can be useful in many different ways : for bioinformatics, fingerprints search, facial search, etc. (getting the fingerprint of a document is important for duplicate detection). the simplest approach is implemented in jetwick to reduce duplicate tweets, but this yields a performance of o(n) where n is the number of queried terms. this is okay for 10 or less terms, but it can get even better at o(1)! the idea is to use a special hash set to get all similar documents. this technique is called local sensitive hashing . read this nice paper about 'near similarity search and plagiarism analysis' for more information. 3.5. duckduckgo duckduckgo is made with open source and its "zero click" information is done with the help of solr using the dismax query handler: the index for that feature contains 18m documents and has a size of ~12gb. for this case had to tune solr: " i have two requirements that differ a bit from most sites with respect to solr: i generally only show one result, with sometimes a couple below if you click on them. therefore, it was really important that the first result is what people expected. false positives are really bad in 0-click, so i needed a way to not show anything if a match wasn't too relevant. i got around these by a) tweaking dismax and schema and b) adding my own relevancy filter on top that would re-order and not show anything in various situations. " all the rest is done with tuned open source products. to quote gabriel again: "the main results are a hybrid of a lot of things, including external apis, e.g. bing, wolframalpha, yahoo, my own indexes and negative indexes (spam removal), etc. there are a bunch of different types of data i'm working with. " check out the other cool features such as privacy or bang searches . 3.6. clustering support with carrot2 carrot2 is one of the "contributed plugins" of solr. with carrot2 you can support clustering : " clustering is the assignment of a set of observations into subsets (called clusters) so that observations in the same cluster are similar in some sense. " see some research papers regarding clustering here . here is one visual example when applying clustering on the search "pannous" - our company : 3.7. near real time search solr isn't real time yet, but you can tune solr to the point where it becomes near real time, which means that the time ('real time latency') that a document takes to be searchable after it gets indexed is less than 60 seconds even if you need to update frequently. to make this work, you can setup two indices. one write-only index "w" for the indexer and one read-only index "r" for your application. index r refers to the same data directory of w, which has to be defined in the solrconfig.xml of r via: /pathto/indexw/data/ to make sure your users and the r index see the indexed documents of w, you have to trigger an empty commit every 60 seconds: wget -q http://localhost:port/solr/update?stream.body=%3ccommit/%3e -o /dev/null everytime such a commit is triggered a new searcher without any cache entries is created. this can harm performance for visitors hitting the empty cache directly after this commit, but you can fill the cache with static searches with the help of the newsearcher entry in your solrconfig.xml. additionally, the autowarmcount property needs to be tuned, which fills the cache with a newsearcher from old entries. also, take a look at the article 'scaling lucene and solr' , where experts explain in detail what to do with large indices (=> 'sharding') and what to do for high query volume (=> 'replicating'). 3.8. loggly = full text search in logs feeding log files into solr and searching them at near real-time shows that solr can handle massive amounts of data and queries the data quickly. i've setup a simple project where i'm doing similar things , but loggly has done a lot more to make the same task real-time and distributed. you'll need to keep the write index as small as possible otherwise commit time will increase too great. loggly creates a new solr index every 5 minutes and includes this when searching using the distributed capabilities of solr ! they are merging the cores to keep the number of indices small, but this is not as simple as it sounds. watch this video to get some details about their work. 3.9. solandra = solr + cassandra solandra combines solr and the distributed database cassandra , which was created by facebook for its inbox search and then open sourced. at the moment solandra is not intended for production use. there are still some bugs and the distributed limitations of solr apply to solandra too. tthe developers are working very hard to make solandra better. jetwick can now run via solandra just by changing the solrconfig.xml. solandra also has the advantages of being real-time (no optimize, no commit!) and distributed without any major setup involved. the same is true for solr cloud. 3.10. category browsing via facets solr provides facets , which make it easy to show the user some useful filter options like those shown in the "drupal integration" example. like i described earlier , it is even possible to browse through a deep category tree. the main advantage here is that the categories depend on the query. this way the user can further filter the search results with this category tree provided by you. here is an example where this feature is implemented for one of the biggest second hand stores in germany. a click on 'schauspieler' shows its sub-items: other shops: game-change 3.11. jetwick - open twitter search you may have noticed that twitter is using lucene under the hood . twitter has a very extreme use case: over 1,000 tweets per second, over 12,000 queries per second, but the real-time latency is under 10 seconds! however, the relevancy at that volume is often not that good in my opinion. twitter search often contains a lot of duplicates and noise. reducing this was one reason i created jetwick in my spare time. i'm mentioning jetwick here because it makes extreme use of facets which provides all the filters to the user. facets are used for the rss-alike feature (saved searches), the various filters like language and retweet-count on the left, and to get trending terms and links on the right: to make jetwick more scalable i'll need to decide which of the following distribution options to choose: use solr cloud with zookeeper use solandra move from solr to elasticsearch which is also based on apache lucene other examples with a lot of facets: cnet reviews - product reviews. electronics reviews, computer reviews & more. shopper.com - compare prices and shop for computers, cell phones, digital cameras & more. zappos - shoes and clothing. manta.com - find companies. connect with customers. 3.12. plaxo - online address management plaxo.com , which is now owned by comcast, hosts web addresses for more than 40 million people and offers smart search through the addresses - with the help of solr. plaxo is trying to get the latest 'social' information of your contacts through blog posts, tweets, etc. plaxo also tries to reduce duplicates . 3.13. replace fast or google search several users report that they have migrated from a commercial search solution like fast or google search appliance (gsa) to solr (or lucene). the reasons for that migration are different: fast drops linux support and google can make integration problems. the main reason for me is that solr isn't a black box —you can tweak the source code, maintain old versions and fix your bugs more quickly! 3.14. search application prototyping with the help of the already integrated velocity plugin and the data import handler it is possible to create an application prototype for your search within a few hours. the next version of solr makes the use of velocity easier. the gui is available via http://localhost:port/solr/browse if you are a ruby on rails user, you can take a look into flare. to learn more about search application prototyping, check out this video introduction and take a look at these slides. 3.15. solr as a whitelist imagine you are the new google and you have a lot of different types of data to display e.g. 'news', 'video', 'music', 'maps', 'shopping' and much more. some of those types can only be retrieved from some legacy systems and you only want to show the most appropriated types based on your business logic . e.g. a query which contains 'new york' should result in the selection of results from 'maps', but 'new yorker' should prefer results from the 'shopping' type. with solr you can set up such a whitelist-index that will help to decide which type is more important for the search query. for example if you get more or more relevant results for the 'shopping' type then you should prefer results from this type. without the whitelist-index - i.e. having all data in separate indices or systems, would make it nearly impossible to compare the relevancy. the whitelist-index can be used as illustrated in the next steps. 1. query the whitelist-index, 2. decide which data types to display, 3. query the sub-systems and 4. display results from the selected types only. 3.16. future solr is also useful for scientific applications, such as a dna search systems. i believe solr can also be used for completely different alphabets so that you can query nucleotide sequences - instead of words - to get the matching genes and determine which organism the sequence occurs in, something similar to blast . another idea you could harness would be to build a very personalized search. every user can drag and drop their websites of choice and query them afterwards. for example, often i only need stackoverflow, some wikis and some mailing lists with the expected results, but normal web search engines (google, bing, etc.) give me results that are too cluttered. my final idea for a future solr-based app could be a lucene/solr implementation of desktop search. solr's facets would be especially handy to quickly filter different sources (files, folders, bookmarks, man pages, ...). it would be a great way to wade through those extra messy desktops. 4. summary the next time you think about a problem, think about solr! even if you don't know java and even if you know nothing about search: solr should be in your toolbox. solr doesn't only offer professional full text search, it could also add valuable features to your application. some of them i covered in this article, but i'm sure there are still some exciting possibilities waiting for you!
January 25, 2011
by Peter Karussell
· 147,269 Views
article thumbnail
Changing Eclipse Default Encoding to UTF-8 for JSP files
Try creating a new JSP file in your Eclipse and you’ll notice that the JSP page directive will have encoding something like: But for a better I18N and L10N support, it is recommended to follow UTF-8 encoding where ever possible. So, how do we change the default JSP file encoding to UTF-8 in eclipse? Simple. Just do these things: In Eclipse, go to Windows -> Preferences -> Web -> JSP Files Select UTF-8 encoding from the Encoding dropdown box there. That’s it! And if you wonder how this change works, you can very well see that. In the same Preferences window, go to this location: Preferences -> Web -> JSP Files -> Editor -> Templates. Then in the right hand side, you’ll see a list of templates defined for JSP files. And in a new JSP file template, you can see this code: Here as you might have guessed, the ${encoding} will be replaced by whatever we set in the above step. The same method can be used to change the default encoding type for other file types too (css, html). From http://veerasundar.com/blog/2010/12/changing-eclipse-default-encoding-to-utf-8-for-jsp-files/
December 8, 2010
by Veera Sundar
· 26,588 Views · 1 Like
article thumbnail
The Domain Model as REST Anti-pattern
Today JavaLobby published yet anotherdomain-model-as-RESTarticle, using Spring and Jersey. As already pointed out, this really is an anti-pattern, and is not RESTful, and cannot be so either. The point that all of these types of articles miss is theHATEOASpart, the hyperlinking of resources. If you expose your domain model, basically saying "here's all I got, use as you see fit", there is no sensible way to create links between resources that expose the application state. There is no sensible way to tell the client "here's what you can do next", because the "REST" API allows anything at any time. Here's an example, from my own app, which showed me the problem with this approach. I have users in my system. I need two ways to work with their passwords: the user must be allowed to change his own password, and the administrator shall be allowed to reset any users' password. In the beginning, when I was exposing my domain model, the URL's for this were as follows: /user//changepassword/user//resetpassword I'm just doing what the article suggests, which is to expose my domain model, and all that I can do with it. What's the problem with this? The first and most obvious problem is that it's very hard to determine who is allowed to do what here. I need to have authorization checks on both "changepassword" and "resetpassword". The first needs to check if it is the same user that accesses it, and the second needs to check if the accessing user has the administrator role. Also, since the client MUST get to these resources by following links in hypermedia (that's a constraint, remember?), the most obvious thing to do is to list them when accessing /user//. But then my link lists need to do these authorization checks as well, because if the user is not an administrator, then the "resetpassword" link should not be there. I should not allow clients to see links they cannot reasonably follow! My UI will also be quite complicated, because in one screen I might do "resetpassword" and a number of other administrative tasks, each of which uses different parts of the domain model, and so its exposure to the API, and consequently, its brittleness if the API changes, is immense. It's just a very bad situation, and one which you'll get into by following the guidelines in all of these expose-your-domain-model articles. So what to do instead? The trick is to expose usecases instead. It's that simple. Now, the main problem with doing this is that you have to actually know what your usecases are! And this is probably why all of these articles do the domain-model anti-pattern: because of their simplified nature they only thought to the point of "we gotta have users in our system" and not take the next step "what can we do with them?", because then you need to decide a whole lot more about what your system does. Since articles need to be reasonably focused on one thing, they just don't go there. But for You, if you do that, you end up with the mess outlined above. What did we do in our REST API to fix the above? We simply looked at our usecases, and rearranged the REST API accordingly. For the above, they relate to two different usecases which are account handling and user administration. And so we changed the API to something like this: /account/changepassword/administration/users//resetpassword If a client goes to /account/, which it can do by first going to "/" and finding that link, it will receive a list of links with what you can do on your own account, such as "changepassword". Do a GET on that link, and the client gets a form with two fields: the old password and the new password. The client might show this as three fields though, with a duplicate new password field to ensure that the user typed it correctly. The client can then POST to "changepassword" to make the actual change. I don't have to make any authorization checks, since the client is implicitly accessing its own account, so there's no way to screw it up, even deliberately. For the admin side, the client browses to /administration/users/ (and again, that link was retrieved from "/" if the user is an administrator), lists/searches the users, gets the link to a particular user, do a GET on "resetpassword" to get the form for it, and then fills it in and POST it to make the change. The REST API has at all times told the client what it is allowed to do, by using hypertext to drive the application state. This is what HATEOAS means in practice, and it is VERY helpful if you expose your usecases, and VERY annoying if you expose your domain model (simply because you can't). This approach also removes the issue outlined in the article with circular references, simply because in usecases, there are no circular references. Another effect of this is that links in the REST API will almost always be relative, since all they do is guide the client further into a usecase, or sub-usecase. If you expose domain models you have to have absolute links, and they will be going here there and everywhere, exposing the internal associations between entities. It's stupid beyond belief, but this is what pretty much all of the current articles on "RESTful" frameworks tell you to do. And I say: DON'T! It'll only bring you misery. From a security point of view the above is also easier to work with. Now all I have to do is add a check on "/administration/" for the administrator role, and after that the user can do anything below that point. No need to duplicate that check everywhere (and no need to use aspects to get around this annoyance)! Now that you know what to do, the next question might be: how to do it? The problem here is that since all the current "REST" frameworks haven't thought HATEOAS through, they don't really allow you to make REST API's for your applications, and so, they will not be very easy to use. You have to work against them. This goes for Jersey and friends as well, as they don't allow this usecase approach to URL parsing. What we have done in my project, Streamflow, is to create our own wrapper on top ofRestlet. Restlet provides an excellent base for REST applications, but is too low-level to have to deal with in the application code. By putting a thin wrapper on top of it, which understand the notion of usecases and links, we have been able to really reduce the amount of code needed to do all of this. Here's sample code for "change password". The code uses a routing technique, so in order to get to /account/changepassword, the framework first takes "/" and finds a resource for that. This resource then knows how to get to "/account/", which in turn knows how to get to "changepassword". The code looks like this: public class RootResource extends CommandQueryResource{ @SubResource public void account() { subResource( AccountResource.class ); }...} When the client hits "/" the framework will automatically look at this class, and present hypermedia (JSON or HTML at this point, but Atom Services is also an option) for it. The client clicks "/account/", which leads to this: public class AccountResource extends CommandQueryResource{ public AccountResource( ) { super( AccountContext.class ); } @SubResource public void profile() { subResourceContexts( ProfileContext.class, ContactableContext.class ); } To find out what the client can do on this level you look in AccountContext. If you want to continue further down into the profile handling of an account (setting email, phone, etc.) the client would follow "/account/profile/" link that is presented. In our case, let's look at AccountContext: public class AccountContext{ public void changepassword( ChangePasswordCommand newPassword ) throws WrongPasswordException { UserAuthentication user = RoleMap.role( UserAuthentication.class ); user.changePassword( newPassword.oldPassword().get(), newPassword .newPassword().get() ); } It exposes one interaction on this level of the usecase, which is /account/changepassword. The parameter tells the framwork what it requires as input, so if the client does GET it can look at the ChangePasswordCommand value object and present it as a form. If the client does a POST the framework parses the input into the value object and invokes the method, allowing it to "do it's thing". In this case it looks up the UserAuthentication role, which is a Qi4j mixin that our user entity implements. This entity was registered automatically by the authentication filter, so I don't have to look it up. For the administration usecase the code would get access to the "" part of the URL so that it can locate the user from the repository. And that's pretty much it. Not only is this easier to work with for clients (who simply follow links in hypermedia), but the code in both client and application is also absolutely trivial. I can also find out what my REST API looks like in total by starting with RootResource and explore the API by clicking on the classes it references. Since the API is so deterministic given these classes I can also generate documentation automatically that basically says, "given your user authorization level, here are all the resources you can access in the API". In particular, when your API becomes hypermedia driven like this, what you want to expose as documentation is the set of "rel" attributes that the client must know, in this case "account" and "changepassword". What the URL's look like is none of the clients business! It should just go to "/" and follow links based on the "rel" attribute of those links. Then you can say that your API is "RESTful". Until you do that, no, you may have a "web API" or a "HTTP API", but it aint REST. There are more details in how this works, and how to turn links on/off depending on internal state, but the gist of how to think is as above. From http://www.jroller.com/rickard/entry/the_domain_model_as_rest
December 8, 2010
by Rickard Oberg
· 31,761 Views · 2 Likes
article thumbnail
Microchip's Embedded Software Development on the NetBeans Platform
Vince Sheard (pictured right) is the Manager of the MPLAB® Integrated Development Environment (IDE) team at Microchip Technology Inc. He has been working at Microchip for more than 10 years, and was the lead architect for the MPLAB X IDE version 1.0, prior to stepping into the management roll. This, the port of MPLAB to the NetBeans Platform, is the sixth major architecture change of the MPLAB IDE since its inception in 1992. Microchip Technology Inc., headquartered in Chandler, Arizona, was spun off from General Instrument in 1989. The Company went public in 1993, and is a leading provider of microcontroller, analog, and Flash-IP solutions, providing low-risk product development, lower total system cost and faster time to market for thousands of diverse customer applications worldwide. Headquartered in Chandler, Arizona, Microchip offers outstanding technical support along with dependable delivery and quality. For more information, visit the Microchip website at http://www.microchip.com. (The MPLAB X landing page is http://www.microchip.com/mplabx, which will be available in the next few days.) Hi, Vince. What's MPLAB, in a nutshell? MPLAB® is an integrated development environment or IDE. It is similar to other IDEs, but there are two important differences. The first difference is that the MPLAB IDE is our customers’ window into Microchip’s PIC® microcontrollers embedded in their designs. Many people believe they understand their PC, because it is “right here.” An embedded device is more difficult to get a handle on. It’s the brain of a product “over there.” It’s not a computer, it’s a thing. The MPLAB IDE gives embedded developers an opportunity to dig into the brain of that thing. The second important difference is that the MPLAB IDE seamlessly covers Microchip’s entire portfolio of more than 700 8-bit, 16-bit and 32-bit PIC microcontrollers. The differences between these devices are massive, from a tiny 6-pin, 8-bit microcontroller that could fit under your fingernail, to a huge 32-bit microcontroller that is much more powerful than the iconic IBM mainframe of last century. The MPLAB IDE provides a consistent and supportive environment in which to debug our customers’ original, creative works of software that differentiate their products. What are the MPLAB IDE’s main features and how does it distinguish itself from its competitors? Integrated development environments share many features: project creation and management, programmers’ editor, language tool integration and build tools, image preparation and programming, and debug facilities. These are the MPLAB X IDE’s main features, too. A large difference comes in the presentation of an embedded target, rather than a PC target, which presents a developer with a less coupled and less easily controlled object for their development. That tightens the focus, but there are other IDEs that support embedded development. The MPLAB X IDE is distinguished by its seamless and timely support of Microchip devices, the vast ecosystem of tightly integrated compilers and hardware tools that also support those devices, and the evolutionary grace of a tool that has grown with our customers and technologies until the three form a smooth and supportive system for developing innovative embedded products. What are the typical technical challenges of an application of this kind? The principal challenge we face is how to provide the facilities developers need in the most intuitive and useful way possible. It’s easy to provide tons and tons of features, but with the GUI technologies of today, one can only present a small fraction of what is provided and available for use. One of the gauges for how well we’ve done our job is when our customers present a fine point of usage that we’ve already discussed and disagreed on how to implement. Those "complaints" are really wonderful because they come from expert tool users who understand the tools they are using. Of course, we are always hustling to present new Microchip devices in the same light that we present established devices. We’re also challenged to exploit the advanced debug facilities of new devices in a way that is most beneficial for our customers. What's the architecture of the application and why did you make the choices that you did? We’re moving away from a Windows OS-only, COM-based architecture. As our customers’ development sophistication has grown, so have their needs. Our customers now require Linux, Mac, and Windows support. Microchip is a worldwide company with customers who may only be fluent in a single language, so that impacts our choices. We also have a number of educational institutions who place interesting demands on the IDE, along with a number of advanced customers who are very forward-looking and are really pushing the envelope of what was previously thought possible. The most telling choice we had to make, though, was the choice of NetBeans as a fully capable, modern, lightweight and flexible platform for our next-generation MPLAB X IDE: Where does the NetBeans Platform fit into all of this? NetBeans is unique among current open-source IDE platform offerings, in that it is the most advanced for addressing our primary challenge, which I described above. The NetBeans IDE presents standard operations in a way that really minimizes hunting around and wasting time, to find out how to accomplish what you need to do. Take, for instance, the classic edit, compile, debug “cycle.” In NetBeans, like in other IDEs, the edit part is pretty easy: open the source file in the programmers’ editor and make the changes you need. It’s really not much different than editing a document with a word processor. The next step is where the difference really shows. In some IDEs, you have to compile or build an image and then figure out how to load it and start a debugging session. In some IDEs, that’s just brutal to figure out, especially in embedded systems where, as we said, the target is not “right here,” it’s “over there.” In NetBeans, it’s a single button press (DebugRun), even in an embedded context like ours. After that, the rest of the steps are taken care of. If any errors occur during the sequence, we take it home by capturing the errors and placing the user in context for an easy solution; and the ability to move on. That’s just one example. NetBeans is way ahead of the curve compared to other menu/toolbar/property sheet IDEs. What are the 3 main benefits of the NetBeans Platform, in this context? First and foremost is the ability to really optimize developers’ time. That’s a major factor in our customers’ focus. Second is the fact that NetBeans is a modern, lightweight and fully capable IDE platform. It doesn’t suffer from the bloat and outdated aspects of some other IDE platforms. Included with these benefits are the abilities to localize the IDE and to utilize it on multiple operating systems. Last, but not least, is the huge benefit of a professionally executed development, maintained by a focused organizing committee and maintained by a tight-knit development community—all headed by the Oracle contributions. That’s a significant departure from some other high-profile, open-source platforms that are available. How did you end up choosing the NetBeans Platform over its alternatives? When you consider all of the benefits I just mentioned, I think it’s pretty much a no-brainer. How did you get started with it? We first discussed the concepts with Sun Microsystems, as we wanted to provide a benefit to the overall NetBeans IDE from an embedded side. We created a proof of concept by plugging in our existing debuggers to the NetBeans IDE on a Windows operating system. We were fortunate to find someone who previously worked within Sun Microsystems on the NetBeans Platform, who came in on contract and gave us some one-on-one training. This was mainly because we had an aggressive schedule and wanted to be able to get up to speed faster. Any tips and tricks for others going down the same road? The mail lists are very helpful. We found many things we wanted to do being asked by others on the mailing lists. Many of the developers monitor these lists frequently, and respond more often than not in a timely fashion. The documentation suite, videos, written documents and interaction with the community are all extremely helpful in getting to the root of any matter quickly. The IDE is well organized and uses common techniques within the code base, which quickly become familiar. Other platforms treat information as job security. Some people may know, but they want you to pay for the information, in one way or another. Not so with NetBeans; everyone involved is completely open and collaborative. Any specific things that surprised you about the NetBeans Platform (in a good or bad way)? NetBeans prevents development with any form of interdependency between modules. For instance, you cannot have A->B and B->A. This really is a good thing and ensures that you break your modules up more to create a common module. The way JUnit is integrated into the IDE makes it so seamless to create your unit tests while developing the code. Source-code revision control worked quite smoothly from within the IDE. A hindrance for us is that there is no way to view a block of memory in hex form, when running under Java (using the JVM debugger). This is something often required when doing embedded development. Since we are developing code for our debug tools, we wanted to see the code blocks being transported from the IDE to the tool in hex, but could not. Anything else you'd like to share? It is great how fully featured the editor is. We are often so deep in developing what is required for the embedded side that we still discover things the editor does that we hadn’t come across. We are using the NetBeans IDE to create our own IDE, which is a completely new, yet compatible, incarnation of our IDE. The NetBeans developers at Oracle/Sun are extremely open to assist in getting value added to the current IDE, which makes our job even easier.
December 3, 2010
by Geertjan Wielenga
· 20,894 Views · 10 Likes
article thumbnail
Generating Client JAVA code for WSDL using SOAP UI
create a soap ui project using your wsdl. set the preferences in soap ui for axis2 home directory. right click on the wsdl in soap ui and click generate code. select adb binding and the following settings and click generate following is the directory structure and code files generated. that’s it, you can now use this code from you ide by importing it. ps: you will need to add the axis2 jars to your project class path. for more details visit my blog @ http://nitinaggarwal.wordpress.com/
November 12, 2010
by Nitin Aggarwal
· 210,387 Views · 3 Likes
article thumbnail
MyBatis (formerly iBatis) – Examples and Hints using SELECT, INSERT and UPDATE Annotations
MyBatis is a lightweight persistence framework for Java and .NET. This blog entry addresses the Java side. MyBatis is an alternative positioned somewhere between plain JDBC and ORM frameworks (e.g. EclipseLink or Hibernate). MyBatis usually uses XML, but it also supports annotations since version 3. The documentation is very detailed for XML, but lacks annotation examples. Just the Annotations itself are described, but no examples how to use them. I could not find any good and easy examples anywhere, so I will describe some very basic examples for SELECT, INSERT and UPDATE statements by implementing a Data Access Object (DAO) using MyBatis. These examples are a good starting point to create more complex MyBatis queries using a DAO. You can find the full source code at the end of this blog. A simple SQL-Table I use a very simple table with two attributes. The name of the table is “simple_information”. The primary key is a Integer and may not be null (info_id). The only real data is a character and may also not be null (info_content). That is enough “complexity” to learn the usage of MyBatis annotations. The Java class “SimpleInformationEntity” is a POJO which contains these two attributes. @SELECT-Statement The @Select annotation is very easy to use, if you want to use exactly one paramter. If you need more than one paramter, use the @Param annotation (which is described below at the update example). You do not have to map the found information to a SimpleInformationEntity object, as you would have to do with a JDBC ResultSet. The magic of the framework does this for you. final String GET_INFO = “SELECT * FROM simple_information WHERE info_id = #{info_id}”; @Select(GET_INFO) public SimpleInformationEntity getSimpleInformationById(int info_id) throws Exception; @INSERT-Statement You can use the object (which you want to be persist) as parameter. You do not have to use several parameters for each attribute of the object. The magic of the framework does this for you. final String PERSIST_INFO = “INSERT INTO simple_information(info_id, info_content) VALUES (#{infoId}, #{infoContent})”; @Insert(PERSIST_INFO) public int persistInformation(SimpleInformationEntity simpleInfo) throws Exception; @UPDATE-Statement You cannot use more than one parameter within a method. If you want to understand why, look at some MyBatis XML examples in the documenation: There you use the attribute “parameterType”, which must be exactly one “parameter”! So you will get a (strange) exception, if you use two or more parameters. Instead you have to use the @Param annotation, if you need more than one parameter. final String UPDATE_INFO = “UPDATE simple_information SET info_content = #{newInfo} WHERE info_id = #{infoId}”; @Update(UPDATE_INFO) public int updateInformation(@Param(“infoId”) int info_id, @Param(“newInfo”) String new_content) throws Exception; Configuration You have to add your MyBatis-Interface for the Mapper to the SQLSessionFactory: sqlSessionFactory.getConfiguration().addMapper(InfoMapper.class); Some Hints for developing with MyBatis The following means helped me a lot to use MyBatis annotations despite the lack of documentation about using annotations: - MyBatis is open source! So add the sources to your build path and use the debugging function of your IDE to enter the MyBatis source code while executing some queries. You will see what MyBatis expects as input and how it is processed. - Read the documentation about using MyBatis XML. This does not really make any sense you think? It does! The processing deep inside MyBatis does not change if you use annotations instead of XML. It is just another way to develop persistence queries. E.g. if you know that a XML select query may just use exactly one parameterType-attribute, then you know that you may just use one parameter in an annotation-based method too! If you need more parameters, you have to use the @Param annotation. - If you get any strange exception that does not make any sense, then clean and re-compile your project. This often helps, because as with other persistence frameworks such as Hibernate, the bytecode enhancement sometimes confuses your IDE. Conclusion: @MyBatis-Team: Improve and extend the documentation instead of improving the framework itself! MyBatis is a nice lightweigt persistence framework. But the documentation is not enough detailed. Some important information is completely missing. Especially, if you are a newbie to MyBatis / iBatis, it is very tough to develop with MyBatis using annotations instead of XML. Besides the usage of annotations, another good example for missing documentation is how to configure transactions in MyBatis by using JNDI and a J2EE / JEE Application server. You have to use google to find out, and if you are lucky you will find a mailing list or blog entry describing your problem. If not, you have to try it out. The missing documentation makes MyBatis much more tough than it actually is. So in the next months, the MyBatis team should improve and extend the documentation instead of improving the framework itself… Best regards, Kai Wähner (Twitter: @Kai Waehner) [Content from my Blog: MyBatis (formerly iBatis) - Examples and Hints using Select, Insert and Update Annotations - Kai Wähner's IT-Blog] Appendix: Source Code Here you see all the necessary source code, also including a MyBatis Connection Factory, which reads the configuration data from a XML file. ############################################################################ Connection Factory (using a static initializer) ############################################################################ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import de.waehner.kai.persistence.InfoDAO.InfoMapper; public class MyBatisConnectionFactory { private static SqlSessionFactory sqlSessionFactory; static { Reader reader = null; try { InputStream in = MyBatisConnectionFactory.class.getResourceAsStream(“myBatisConfiguration.xml”); reader = new InputStreamReader(in); if (sqlSessionFactory == null) { sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); sqlSessionFactory.getConfiguration().addMapper(InfoMapper.class); } in.close(); } catch (FileNotFoundException fileNotFoundException) { fileNotFoundException.printStackTrace(); } catch (IOException iOException) { iOException.printStackTrace(); } } public static SqlSessionFactory getSqlSessionFactory() { return sqlSessionFactory; } } ############################################################################ Data Acces Object (including the MyBatis-Mapper as inner Class) ############################################################################ import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; public class InfoDAO { public interface InfoMapper { final String GET_INFO = “SELECT * FROM simple_information WHERE info_id = #{info_id}”; @Select(GET_INFO) public SimpleInformationEntity getSimpleInformationById(int info_id) throws Exception; final String PERSIST_INFO = “INSERT INTO simple_information(info_id, info_content) VALUES (#{infoId}, #{infoContent})”; @Insert(PERSIST_INFO) public int persistInformation(SimpleInformationEntity simpleInfo) throws Exception; final String UPDATE_INFO = “UPDATE simple_information SET info_content = #{newInfo} WHERE info_id = #{infoId}”; @Update(UPDATE_INFO) public int updateInformation(@Param(“infoId”) int info_id, @Param(“newInfo”) String new_content) throws Exception; } public SimpleInformationEntity getSingleAlarm(int info_id) throws Exception { SqlSessionFactory sqlSessionFactory = MyBatisConnectionFactory.getSqlSessionFactory(); SqlSession session = sqlSessionFactory.openSession(); try { InfoMapper mapper = session.getMapper(InfoMapper.class); SimpleInformationEntity simpleInfo = mapper.getSimpleInformationById(info_id); return simpleInfo; } finally { session.close(); } } public int persistInformation(SimpleInformationEntity simpleInfo) throws Exception { SqlSessionFactory sqlSessionFactory = MyBatisConnectionFactory.getSqlSessionFactory(); SqlSession session = sqlSessionFactory.openSession(); try { InfoMapper mapper = session.getMapper(InfoMapper.class); int answer = mapper.persistInformation(simpleInfo); return answer; } finally { session.close(); } } public int updateInformation(int info_id, String new_content) throws Exception { SqlSessionFactory sqlSessionFactory = MyBatisConnectionFactory.getSqlSessionFactory(); SqlSession session = sqlSessionFactory.openSession(); try { InfoMapper mapper = session.getMapper(InfoMapper.class); int answer = mapper.updateInformation(info_id, new_content); return answer; } finally { session.close(); } } } ############################################################################ SimpleInformation Entity (a simple POJO) ############################################################################ import java.io.Serializable; public class SimpleInformationEntity implements Serializable{ private static final long serialVersionUID = -821826330941829539L; private int infoId; private String infoContent; public int getInfoId() { return infoId; } public void setInfoId(int infoId) { this.infoId = infoId; } public String getInfoContent() { return infoContent; } public void setInfoContent(String infoContent) { this.infoContent = infoContent; } }
November 2, 2010
by Kai Wähner DZone Core CORE
· 79,311 Views · 2 Likes
article thumbnail
Generate, Rename and Delete Getters/Setters Instantly in Eclipse
despite the arguments and debates about getters and setters in java, the fact is that they’re a reality and you have to work with them. but managing getters and setters is a time-consuming effort. creating a getter/setter for 5 fields in a class can take minutes, renaming one is error-prone and deleting one is just plain inconvenient. there are options like project lombok (that implicitly creates getters/setters without the need to code them) and you could avoid getters/setters altogether by redesigning your classes. but these options aren’t always available, so it’s a good thing eclipse has some handy features for managing getters and setters. combined with the ability to generate constructors based on fields , you can get the boilerplate code out of the way in seconds and get on with the real coding. generate getters and setters to generate getters and setters, do the following: create the fields you want in the class then press alt+shift+s, r . a dialog will pop up allowing you to choose the fields you want to generate getters and setters for. click select all to create getters/setters for all fields. of course you can choose individual fields as required. change insertion point to last member . this tells eclipse that you want to put the methods at the bottom of the class. this is normally the best option for me as i want them out of the way. click ok . eclipse will create the getters and setters for you. here’s an example of what the dialog should look like. note: by default, eclipse doesn’t allow you to create a setter for a final field – the setter just doesn’t appear in the dialog. this can be a nuisance, especially if you’ve enabled autoformatting to make fields final where possible. to bypass this restriction, enable the checkbox allow setters for final fields on the dialog. the setter for the field will now appear in the dialog. once you click ok, eclipse will remove the final keyword from the field and generate the setter. eclipse also remembers this setting. another way to add just a single getter/setter is to position your cursor anywhere in the class (outside any method), start typing either “get” or “set” and press ctrl+space . the options on the autocomplete menu will include any getters/setters of fields that don’t have any defined yet. this is a quick way to create a single getter/setter but isn’t geared for bulk creation. here’s an example of how the autocomplete looks: rename getters and setters the easiest way to rename getters/setters is to use the rename refactoring. place your cursor on the field name (anywhere in the class, not just the declaration) and press alt+shift+r . if you’re using in-place rename (the default), then just rename the field, press enter and eclipse will rename the corresponding getters and setters as well. if you’ve chosen to use the classic refactor dialog (see note below) then make sure you enable rename getter and rename setter on the rename dialog. note: you can choose to do renaming using the traditional rename dialog by going to window > preferences > java and unchecking rename in editor without dialog . i prefer using the rename dialog as it highlights the whole name by default making it easier to overwrite and i have the option of not renaming the getters and setters if i don’t want to. the eclipse default these days is to use the new in-place renaming. although eclipse will rename the getter/setter, it won’t rename the argument passed to the setter method. if you want consistency, you can navigate to that method (eg. using ctrl+o ) and rename the argument yourself. delete getters and setters deleting getters and setters isn’t as straightforward as just deleting the field in the editor. however, you can delete a field and its getters/setters from the outline view. open the outline view ( alt+shift+q, o ), select the field you want to delete and press delete (or right-click, delete). eclipse will ask you whether you want to delete the getters/setters as well. just choose yes to all and they will be removed. you need to have fields visible in the outline view to use this feature (ie. untoggle the hide fields button ). you can select multiple fields simultaneously. and you can delete individual getters/setters (excluding the field) by just selecting the getter/setter and pressing delete . from http://eclipseone.wordpress.com/2010/10/26/generate-rename-and-delete-getterssetters-in-eclipse/
October 27, 2010
by Byron M
· 157,634 Views · 2 Likes
article thumbnail
Know the JVM Series: Shutdown Hooks
Shutdown Hooks are a special construct that allow developers to plug in a piece of code to be executed when the JVM is shutting down.
October 23, 2010
by Yohan Liyanage
· 85,388 Views · 1 Like
article thumbnail
REST API: for Infrastructure, Domain or Application Layer?
It seems that lots of projects/products/services want to expose a REST API these days. But I have found very few that actually follow the REST constraints, and in a lot of the cases it doesn't even make sense for them to follow REST constraints in the first place. One of the main constraints that is commonly violated is the hypertext constraint. Basically, all state changes have to be done by following links, starting from a bookmarked URL. But almost noone does that. However, should they? This article will outline various layers that REST API's can be implemented in, and when it makes sense, and when not. To begin with, in a typical enterprise app there are three options for layers that you might want to expose using a REST API. These are the infrastructure layer, the domain layer, and the application layer. Infrastructure layer If we start with the infrastructure layer, we are typically talking about a database vendor that wants to allow developers to access it using "REST". The API would allow you to create/remove databases, and then insert/update/delete data. Typically it's pretty normal stuff, and the API doesn't change all that much between versions. Accessing this over HTTP maybe makes sense, but is it RESTful? I'll give you an example. I installed CouchDB, and given the hypermedia constraint I should then be able to go to "http://localhost:5984/", and it will tell me what I can do next (like create a database). But when I do a GET on that URL I get this: {"couchdb":"Welcome","version":"1.0.1"} So now what? The hypermedia doesn't tell me what I can do, so therefore as a REST client I will assume there's nothing I can do. This very simple test shows that the HTTP API for CouchDB isn't really RESTful at all. The question is: should it be? That is obviously up to the developers to decide. But if I were the architect I would maybe say, no, it shouldn't be RESTful. Why? Because I want to allow URL templates to be used, so that the client, given the server URL and a document id, is allowed to construct a URL on its own and GET the document. If this was truly RESTful the client would have to do a query in a form first, with the id, in order to get the URL of the document to be retrieved. That might be inefficient for a database, so I might opt not to do this. Which is, in effect, what they already have done. The only problem is that they call it RESTful, when it isn't, so it gives me as a developer the wrong impression of what I can expect from it. This line of reasoning could be done for pretty much most infrastructure layer API's. They're not RESTful, though many say they are, and most likely they shouldn't try to be! IT'S OK! Just say "Accessible over HTTP, see docs for URL templates and whatnot", and be done with it. Domain layer The next potential layer to be exposed over REST is the domain layer. This typically means that you take your domain entities and expose their data straight on the web, through CRUD operations. Very straightforward. There are tons of articles and blogs that show how to do this. But is it RESTful? Or is it even a good idea in the first place? The first test, again, would be to see if the app follows the hypermedia constraint. In this option it is technically possible to allow queries that will list the various URL's to entities in your domain, which you then can update/delete. So on the surface it might seem like you are following the hypermedia constraint. The problem usually comes with the fact that you are exposing domain state rather than application state. Let me explain through a simple example. Let's say you are building an issue tracker. You can access individual issues through links like: /issue/123 which on GET gives you documents such as: {"status":"OPEN","description":"Some issue"} Awesome. Now a client can change the status to "CLOSED" and PUT that. Tada! Case closed. Or is it? What if a client then decides to reopen it, by simply posting a new status of "OPEN" to it. Ok, that worked. But should it? Maybe your domain model really would have wanted it to only go to "REOPENED" from the "CLOSED" state. But how do you express that? How is the client to know that this is the only valid transition? And what happens when we have many versions of clients, each of which has a slightly different set of rules for what you are allowed to do when? Basically, chaos is ensured. And this is the problem with exposing your domain model using a REST API. The client has to own the application logic, and there's no way the server can be sure that it has the "right" logic. And the client, even if it *wants* to play nice (if code ever wants anything is debatable), will have a hard time knowing whether it is playing by the rules or not. It might even get a bit neurotic, trying to do the right thing, whatever that means. In summary, exposing your domain model does not help the client know what the valid state transitions are, and makes it very hard to do other things like role-based security authorization (maybe only an admin is allowed to REOPEN a CLOSED case?). I would therefore recommend that noone exposes their domain models using a REST API. Application layer Finally we come to the application layer. The application layer is designed to implement usecases of the domain model, and has all the context and logic needed to ensure that only valid state transitions are made. In short, it seems like it is especially appropriate to being exposed through a REST API, as it can at all points tell the client what it can do (either based on state or authorization rules or any other type of rules it might have). If we go back to the issue tracker, what would this mean in practice? It could mean that when you do a GET on /issue/123 you get something like this back: {"data":{"status":"OPEN","description":"Some issue"},"links":[{"close":"/issue/123/close.json"}]} This now instead of referring to viewing the domain state of an issue refers to the usecase of viewing an issue with the intent of working on it. There might be other URL's and other queries that only return the data, or maybe a table of the data, or somesuch. But this one, specifically, refers to the usecase of working with the issue. So, as a REST client I can now inspect the data, and then look at what links are available. If the client has a UI it can enable a button that says "Close issue" based on the available link, since it detected a link relation "close" that it understands. The client can then do GET on that link, find out whether the server expects any form to be filled in, and then submit it using POST, thereby letting the server application layer logic transition the issue to the "CLOSED" state. We are no longer relying on the client to contain the logic of knowing when to allow what, and the client also does not have to know how to construct the URL. As long as it can parse the hypertext (and we might use a custom JSON mediatype to indicate what "data" and "links" mean) and do something with it, we're fine. If we in the future change the domain model to also allow the "resolve" link relation for "OPEN" issues, old clients can ignore it, and new clients can enable new actions in the UI that uses it. In summary, the application layer is a very good candidate to be exposed through a REST API. It encapsulates the application rules for when the various state transitions are allowed, and can make use of user authorization to further enable/disable actions. This takes away a lot of responsibilities from the client, which now also can be "dynamic" in the sense that it can easily react to what state changes are available when by simply checking link availability in the hypermedia returned from the server. The main issue with exposing the application layer through a REST API is that there are pretty much no available frameworks that help you do all this in an easy way. But this is not REST's "fault", obviously, but rather that the "REST" community hasn't yet matured to understand what it should and what it should not do. In the Streamflow project we rolled our own simple framework for doing the above, and I'm very happy with that, but unfortunately most other frameworks seems to be in the "expose your domain model" camp, which means that a lot of this link management is non-trivial to do. This is a fixable situation though. I hope that this post has somewhat clarified what the issues are with exposing infrastructure and domain models through REST API's, and why it's not really a good idea in the first place, and why exposing the application layer really is the logical and simpler option. From http://www.jroller.com/rickard/entry/rest_api_for_infrastructure_domain
October 18, 2010
by Rickard Oberg
· 21,324 Views
  • Previous
  • ...
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • Next
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook
×