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.
01.
package
com.loiane.data;
02.
03.
import
java.util.List;
04.
05.
import
org.apache.ibatis.annotations.Delete;
06.
import
org.apache.ibatis.annotations.Insert;
07.
import
org.apache.ibatis.annotations.Options;
08.
import
org.apache.ibatis.annotations.Param;
09.
import
org.apache.ibatis.annotations.Result;
10.
import
org.apache.ibatis.annotations.Results;
11.
import
org.apache.ibatis.annotations.Select;
12.
import
org.apache.ibatis.annotations.Update;
13.
14.
import
com.loiane.model.Contact;
15.
16.
public
interface
ContactMapper {
17.
18.
final
String SELECT_ALL =
"SELECT * FROM CONTACT"
;
19.
final
String SELECT_BY_ID =
"SELECT * FROM CONTACT WHERE CONTACT_ID = #{id}"
;
20.
final
String UPDATE =
"UPDATE CONTACT SET CONTACT_EMAIL = #{email}, CONTACT_NAME = #{name}, CONTACT_PHONE = #{phone} WHERE CONTACT_ID = #{id}"
;
21.
final
String UPDATE_NAME =
"UPDATE CONTACT SET CONTACT_NAME = #{name} WHERE CONTACT_ID = #{id}"
;
22.
final
String DELETE =
"DELETE FROM CONTACT WHERE CONTACT_ID = #{id}"
;
23.
final
String INSERT =
"INSERT INTO CONTACT (CONTACT_EMAIL, CONTACT_NAME, CONTACT_PHONE) VALUES (#{name}, #{phone}, #{email})"
;
24.
25.
/**
26.
* Returns the list of all Contact instances from the database.
27.
* @return the list of all Contact instances from the database.
28.
*/
29.
@Select
(SELECT_ALL)
30.
@Results
(value = {
31.
@Result
(property=
"id"
, column=
"CONTACT_ID"
),
32.
@Result
(property=
"name"
, column=
"CONTACT_NAME"
),
33.
@Result
(property=
"phone"
, column=
"CONTACT_PHONE"
),
34.
@Result
(property=
"email"
, column=
"CONTACT_EMAIL"
)
35.
})
36.
List<Contact> selectAll();
37.
38.
/**
39.
* Returns a Contact instance from the database.
40.
* @param id primary key value used for lookup.
41.
* @return A Contact instance with a primary key value equals to pk. null if there is no matching row.
42.
*/
43.
@Select
(SELECT_BY_ID)
44.
@Results
(value = {
45.
@Result
(property=
"id"
),
46.
@Result
(property=
"name"
, column=
"CONTACT_NAME"
),
47.
@Result
(property=
"phone"
, column=
"CONTACT_PHONE"
),
48.
@Result
(property=
"email"
, column=
"CONTACT_EMAIL"
)
49.
})
50.
Contact selectById(
int
id);
51.
52.
/**
53.
* Updates an instance of Contact in the database.
54.
* @param contact the instance to be updated.
55.
*/
56.
@Update
(UPDATE)
57.
void
update(Contact contact);
58.
59.
/**
60.
* Updates an instance of Contact in the database.
61.
* @param name name value to be updated.
62.
* @param id primary key value used for lookup.
63.
*/
64.
void
updateName(
@Param
(
"name"
) String name,
@Param
(
"id"
)
int
id);
65.
66.
/**
67.
* Delete an instance of Contact from the database.
68.
* @param id primary key value of the instance to be deleted.
69.
*/
70.
@Delete
(DELETE)
71.
void
delete(
int
id);
72.
73.
/**
74.
* Insert an instance of Contact into the database.
75.
* @param contact the instance to be persisted.
76.
*/
77.
@Insert
(INSERT)
78.
@Options
(useGeneratedKeys =
true
, keyProperty =
"id"
)
79.
void
insert(Contact contact);
80.
}
@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.
01.
package
com.loiane.dao;
02.
03.
import
java.io.FileNotFoundException;
04.
import
java.io.IOException;
05.
import
java.io.Reader;
06.
07.
import
org.apache.ibatis.io.Resources;
08.
import
org.apache.ibatis.session.SqlSessionFactory;
09.
import
org.apache.ibatis.session.SqlSessionFactoryBuilder;
10.
11.
import
com.loiane.data.ContactMapper;
12.
13.
public
class
MyBatisConnectionFactory {
14.
15.
private
static
SqlSessionFactory sqlSessionFactory;
16.
17.
static
{
18.
19.
try
{
20.
21.
String resource =
"SqlMapConfig.xml"
;
22.
Reader reader = Resources.getResourceAsReader(resource);
23.
24.
if
(sqlSessionFactory ==
null
) {
25.
sqlSessionFactory =
new
SqlSessionFactoryBuilder().build(reader);
26.
27.
sqlSessionFactory.getConfiguration().addMapper(ContactMapper.
class
);
28.
}
29.
}
30.
31.
catch
(FileNotFoundException fileNotFoundException) {
32.
fileNotFoundException.printStackTrace();
33.
}
34.
catch
(IOException iOException) {
35.
iOException.printStackTrace();
36.
}
37.
}
38.
39.
public
static
SqlSessionFactory getSqlSessionFactory() {
40.
41.
return
sqlSessionFactory;
42.
}
43.
44.
}
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.
001.
package
com.loiane.dao;
002.
003.
import
java.util.List;
004.
005.
import
org.apache.ibatis.session.SqlSession;
006.
import
org.apache.ibatis.session.SqlSessionFactory;
007.
008.
import
com.loiane.data.ContactMapper;
009.
import
com.loiane.model.Contact;
010.
011.
public
class
ContactDAO {
012.
013.
private
SqlSessionFactory sqlSessionFactory;
014.
015.
public
ContactDAO(){
016.
sqlSessionFactory = MyBatisConnectionFactory.getSqlSessionFactory();
017.
}
018.
019.
/**
020.
* Returns the list of all Contact instances from the database.
021.
* @return the list of all Contact instances from the database.
022.
*/
023.
public
List<Contact> selectAll(){
024.
025.
SqlSession session = sqlSessionFactory.openSession();
026.
027.
try
{
028.
029.
ContactMapper mapper = session.getMapper(ContactMapper.
class
);
030.
List<Contact> list = mapper.selectAll();
031.
032.
return
list;
033.
}
finally
{
034.
session.close();
035.
}
036.
}
037.
038.
/**
039.
* Returns a Contact instance from the database.
040.
* @param id primary key value used for lookup.
041.
* @return A Contact instance with a primary key value equals to pk. null if there is no matching row.
042.
*/
043.
public
Contact selectById(
int
id){
044.
045.
SqlSession session = sqlSessionFactory.openSession();
046.
047.
try
{
048.
049.
ContactMapper mapper = session.getMapper(ContactMapper.
class
);
050.
Contact list = mapper.selectById(id);
051.
052.
return
list;
053.
}
finally
{
054.
session.close();
055.
}
056.
}
057.
058.
/**
059.
* Updates an instance of Contact in the database.
060.
* @param contact the instance to be updated.
061.
*/
062.
public
void
update(Contact contact){
063.
064.
SqlSession session = sqlSessionFactory.openSession();
065.
066.
try
{
067.
068.
ContactMapper mapper = session.getMapper(ContactMapper.
class
);
069.
mapper.update(contact);
发表评论
- 浏览: 896828 次
- 性别:
- 来自: 合肥
最新评论
- wodesunday: :idea:
SQL的分段统计查询语句 - wodesunday: 引用
SQL的分段统计查询语句 - BlueSkator: 讲的有点浅,没有深入进去
tomcat需要的重新发布和重启服务器的几种情况 - zt0714: [color=brown][/color]test
Mybatis与Ibatis比较 - 花神47699: [img] [/img]
常见的几种jsp和struts中文件上传方法总结
评论