转载: MyBatis注解Annotation介绍及Demo

 MyBatis注解Annotation介绍及Demo
2014-04-21 17:09:55
标签: Mybatis   Annotation   注解   ResultMap   SqlBuilder
原创作品,允许转载,转载时请务必以超链接形式标明文章   原始出处  、作者信息和本声明。否则将追究法律责任。 http://computerdragon.blog.51cto.com/6235984/1399742

MyBatis可以利用SQL映射文件来配置,也可以利用Annotation来设置。MyBatis提供的一些基本注解如下表所示。

注解

目标

相应的XML

描述

@CacheNamespace

<cache> 

为给定的命名空间(比如类)配置缓存。属性:

implemetation,eviction,

flushInterval , size  readWrite 

@CacheNamespaceRef

<cacheRef>

参照另外一个命名空间的缓存来使用。

属性:value,也就是类的完全限定名。

@ConstructorArgs

方法

<constructor>

收集一组结果传递给对象构造方法。

属性:value,是形式参数的数组

@Arg

方法

<arg>

<idArg>

单独的构造方法参数,是ConstructorArgs  集合的一部分。属性:id,column,javaTypetypeHandler

id属性是布尔值,来标识用于比较的属性,和<idArg>XML 元素相似

@TypeDiscriminator

方法

<discriminator>

一组实例值被用来决定结果映射的表

现。属性:Column, javaType ,  jdbcType typeHandlercases

cases属性就是实例的数组。

@Case

方法

<case>

单独实例的值和它对应的映射。属性:value  type results 

Results 属性是结果数组,因此这个注解和实际的ResultMap 很相似,由下面的  Results注解指定

@Results

方法

<resultMap>

结果映射的列表,包含了一个特别结果

列如何被映射到属性或字段的详情。

属性:value ,是Result注解的数组

@Result

方法

<result>

<id>

在列和属性或字段之间的单独结果映

射。属性:id column  property 

javaType jdbcType type Handler 

onemanyid 属性是一个布尔值,表

示了应该被用于比较的属性。one 属性是单独的联系,和 <association> 相似,而many 属性是对集合而言的,和

<collection>相似。

@One

方法

<association> 

复杂类型的单独属性值映射。属性:

select,已映射语句(也就是映射器方

法)的完全限定名,它可以加载合适类

型的实例。注意:联合映射在注解 API

中是不支持的。

@Many

方法

<collection>

复杂类型的集合属性映射。属性:

select,是映射器方法的完全限定名,它可加载合适类型的一组实例。注意:联合映射在Java注解中是不支持的。

@Options

方法

映射语句的属性

这个注解提供访问交换和配置选项的宽广范围,它们通常在映射语句上作为属性出现。而不是将每条语句注解变复杂,Options 注解提供连贯清晰的方式来访问它们。属性:useCache=true

flushCache=false

resultSetType=FORWARD_ONLY

statementType=PREPARED

fetchSize= -1timeout=-1 

useGeneratedKeys=false 

keyProperty=”id“

理解Java 注解是很重要的,因为没有办法来指定“null ”作为值。因此,一旦你使用了Options注解,语句就受所有默认值的支配。要注意什么样的默认值来避免不期望的行为

@Insert

@Update

@Delete

方法

<insert>

<update>

<delete>

这些注解中的每一个代表了执行的真实 SQL它们每一个都使用字符串数组(或单独的字符串)。如果传递的是字符串数组,它们由每个分隔它们的单独空间串联起来。属性:value,这是字符串数组用来组成单独的SQL语句

@InsertProvider

@UpdateProvider

@DeleteProvider

@SelectProvider

方法

<insert>

<update>

<delete>

<select>

允许创建动态

SQL

这些可选的SQL注解允许你指定一个

类名和一个方法在执行时来返回运行

SQL基于执行的映射语句, MyBatis

会实例化这个类,然后执行由 provider

指定的方法. 这个方法可以选择性的接

受参数对象作为它的唯一参数,但是必

须只指定该参数或者没有参数。属性:

typemethodtype 属性是类的完全限定名。method  是该类中的那个方法名。

@Param

参数

N/A

当映射器方法需多个参数,这个注解可以被应用于映射器方法参数来给每个参数一个名字。否则,多参数将会以它们的顺序位置来被命名。比如

#{1}#{2} 等,这是默认的。

使用@Param(“person”)SQL中参数应该被命名为#{person}

这些注解都是运用到传统意义上映射器接口中的方法、类或者方法参数中的。

今天主要介绍两种使用注解的方式。

一种是直接在映射器接口中写SQL语句,一种是利用SqlBuilder来创建SQL再由映射器接口来调用

准备前提:

1,配置常规的MyBatis主配置文件,即各种数据源,别名等设置。在利用注解配置SQL的时候,一般不需要在主配置文件中配置Mapper,个别情况下需要配置。

2,数据库表Blog:

1
2
3
4
5
6
7
8
9
DROP  TABLE  IF EXISTS `blog`;
CREATE  TABLE  `blog` (
 `id`  int(10)  NOT  NULL  auto_increment,
 `title`  varchar(200)  NOT  NULL,
 `date`  varchar(50)  NOT  NULL,
 `authername`  varchar(15)  NOT  NULL,
 `content`  varchar(500)  NOT  NULL,
 PRIMARY  KEY   (`id`)
) ENGINE=InnoDB  DEFAULT  CHARSET=utf8;

数据库表User:

1
2
3
4
5
6
7
8
DROP  TABLE  IF EXISTS `user`;
CREATE  TABLE  `user` (
 `id`  int(11)  NOT  NULL  auto_increment,
 `userName`  varchar(50)  default  NULL,
 `userAge`  int(11)  default  NULL,
 `userAddress`  varchar(200)  default  NULL,
 PRIMARY  KEY   (`id`)
) ENGINE=InnoDB  DEFAULT  CHARSET=utf8;

3,分别写User和Blog对应的JavaBean即setter和getter实体类。

第一种 映射器接口中写SQL语句

映射器接口注解

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package  com.whut.inter;
import  java.util.List;
import  org.apache.ibatis.annotations.Delete;
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  com.whut.model.User;
//最基本的注解CRUD
public  interface  IUserDAO {
   @Select("select *from User")
   public  List<User> retrieveAllUsers();
                                                                                                                                                                                                                                  
   //注意这里只有一个参数,则#{}中的标识符可以任意取
   @Select("select *from User where id=#{idss}")
   public  User retrieveUserById(int  id);
                                                                                                                                                                                                                                  
   @Select("select *from User where id=#{id} and userName like #{name}")
   public  User retrieveUserByIdAndName(@Param("id")int  id,@Param("name")String names);
                                                                                                                                                                                                                                  
   @Insert("INSERT INTO user(userName,userAge,userAddress) VALUES(#{userName},"
           +  "#{userAge},#{userAddress})")
   public  void  addNewUser(User user);
                                                                                                                                                                                                                                  
   @Delete("delete from user where id=#{id}")
   public  void  deleteUser(int  id);
                                                                                                                                                                                                                                  
   @Update("update user set userName=#{userName},userAddress=#{userAddress}"
           +  " where id=#{id}")
   public  void  updateUser(User user);
}

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package  com.whut.test;
import  java.io.IOException;
import  java.io.Reader;
import  java.util.List;
import  org.apache.ibatis.io.Resources;
import  org.apache.ibatis.session.SqlSession;
import  org.apache.ibatis.session.SqlSessionFactory;
import  org.apache.ibatis.session.SqlSessionFactoryBuilder;
import  com.whut.inter.IUserDAO;
import  com.whut.model.User;
public  class  TestUser {
   private  static  SqlSessionFactory sqlSessionFactory;
   private  static  Reader reader;
   static  {
       try  {
           Reader reader = Resources.getResourceAsReader("mybatic-config.xml");
           sqlSessionFactory =  new  SqlSessionFactoryBuilder().build(reader);
           // 由于使用了注解,所以在主配置文件没有mapper,需要在代码里显示注册该mapper接口
           sqlSessionFactory.getConfiguration().addMapper(IUserDAO.class);
       }  catch  (IOException e) {
           e.printStackTrace();
       }
   }
   public  static  void  main(String[] args) {
       // testSelectAll();
       // testSelectByConditions();
       //testAddUser();
       //testDeleteUser();
                                                                                                                                                                                                               
       testUpateUser();
   }
   public  static  void  testSelectAll() {
       // sqlSessionFactory.getConfiguration().addMapper(IUserDAO.class);
       SqlSession session = sqlSessionFactory.openSession();
       try  {
           IUserDAO userDAO = session.getMapper(IUserDAO.class);
           List<User> users = userDAO.retrieveAllUsers();
           System.out.println("用户编号\t"  +  "姓名\t"  +  "年龄\t住址");
           for  (User u : users) {
               System.out.println(u.getId() +  "\t"  + u.getUserName() +  "\t"
                       + u.getUserAge() +  "\t"  + u.getUserAddress());
           }
       }  finally  {
           session.close();
       }
   }
   public  static  void  testSelectByConditions() {
       SqlSession session = sqlSessionFactory.openSession();
       try  {
           IUserDAO userDAO = session.getMapper(IUserDAO.class);
           User u = userDAO.retrieveUserByIdAndName(4,  "%spring%");
           if  (u !=  null) {
               System.out.println("用户编号\t"  +  "姓名\t"  +  "年龄\t住址");
               System.out.println(u.getId() +  "\t"  + u.getUserName() +  "\t"
                       + u.getUserAge() +  "\t"  + u.getUserAddress());
           }
       }  finally  {
           session.close();
       }
   }
   public  static  void  testAddUser() {
       User u =  new  User();
       u.setUserName("dongtian");
       u.setUserAge(51);
       u.setUserAddress("hubeisheng");
       SqlSession session = sqlSessionFactory.openSession();
       try  {
           IUserDAO userDAO = session.getMapper(IUserDAO.class);
           userDAO.addNewUser(u);
           session.commit();
       }  finally  {
           session.close();
       }
   }
   public  static  void  testDeleteUser() {
       SqlSession session = sqlSessionFactory.openSession();
       try  {
           IUserDAO userDAO = session.getMapper(IUserDAO.class);
           userDAO.deleteUser(7);
           session.commit();
       }  finally  {
           session.close();
       }
   }
                                                                                                                                                                                                           
   public  static  void  testUpateUser() {
       User u =  new  User();
       u.setId(4);
       u.setUserName("dongtian");
       u.setUserAge(51);
       u.setUserAddress("hubeisheng");
       SqlSession session = sqlSessionFactory.openSession();
       try  {
           IUserDAO userDAO = session.getMapper(IUserDAO.class);
           userDAO.updateUser(u);
           session.commit();
       }  finally  {
           session.close();
       }
   }
}

第二种 映射器接口调用SqlBuilder生成的SQL进行执行

映射器接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package  com.whut.inter;
import  java.util.List;
import  org.apache.ibatis.annotations.CacheNamespace;
import  org.apache.ibatis.annotations.DeleteProvider;
import  org.apache.ibatis.annotations.InsertProvider;
import  org.apache.ibatis.annotations.Options;
import  org.apache.ibatis.annotations.Param;
import  org.apache.ibatis.annotations.Result;
import  org.apache.ibatis.annotations.ResultMap;
import  org.apache.ibatis.annotations.Results;
import  org.apache.ibatis.annotations.SelectProvider;
import  org.apache.ibatis.annotations.UpdateProvider;
import  org.apache.ibatis.type.JdbcType;
import  com.whut.model.Blog;
import  com.whut.sqlTool.BlogSqlProvider;
@CacheNamespace(size=100)
public  interface  IBlogDAO {
   @SelectProvider(type = BlogSqlProvider.class, method =  "getSql")
   @Results(value ={
           @Result(id=true, property="id",column="id",javaType=Integer.class,jdbcType=JdbcType.INTEGER),
           @Result(property="title",column="title",javaType=String.class,jdbcType=JdbcType.VARCHAR),
           @Result(property="date",column="date",javaType=String.class,jdbcType=JdbcType.VARCHAR),
           @Result(property="authername",column="authername",javaType=String.class,jdbcType=JdbcType.VARCHAR),
           @Result(property="content",column="content",javaType=String.class,jdbcType=JdbcType.VARCHAR),
           })
   public  Blog getBlog(@Param("id")  int  id);
                                                                                                                                                                                      
   @SelectProvider(type = BlogSqlProvider.class, method =  "getAllSql")
   @Results(value ={
           @Result(id=true, property="id",column="id",javaType=Integer.class,jdbcType=JdbcType.INTEGER),
           @Result(property="title",column="title",javaType=String.class,jdbcType=JdbcType.VARCHAR),
           @Result(property="date",column="date",javaType=String.class,jdbcType=JdbcType.VARCHAR),
           @Result(property="authername",column="authername",javaType=String.class,jdbcType=JdbcType.VARCHAR),
           @Result(property="content",column="content",javaType=String.class,jdbcType=JdbcType.VARCHAR),
           })
   public  List<Blog> getAllBlog();
                                                                                                                                                                                      
   @SelectProvider(type = BlogSqlProvider.class, method =  "getSqlByTitle")
   @ResultMap(value =  "sqlBlogsMap")
   //这里调用resultMap,这个是SQL配置文件中的,必须该SQL配置文件与本接口有相同的全限定名
   //注意文件中的namespace路径必须是使用@resultMap的类路径
   public  List<Blog> getBlogByTitle(@Param("title")String title);
                                                                                                                                                                                      
   @InsertProvider(type = BlogSqlProvider.class, method =  "insertSql")
   public  void  insertBlog(Blog blog);
                                                                                                                                                                                      
   @UpdateProvider(type = BlogSqlProvider.class, method =  "updateSql")
   public  void  updateBlog(Blog blog);
                                                                                                                                                                                      
   @DeleteProvider(type = BlogSqlProvider.class, method =  "deleteSql")
   @Options(useCache =  true, flushCache =  false, timeout =  10000)
   public  void  deleteBlog(int  ids);
                                                                                                                                                                                      
}

SQL生成器(利用SqlBuilder生成)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package  com.whut.sqlTool;
import  java.util.Map;
import  static  org.apache.ibatis.jdbc.SqlBuilder.*;
public  class  BlogSqlProvider {
   private  final  static  String TABLE_NAME =  "blog";
   public  String getSql(Map<Integer, Object> parameter) {
       BEGIN();
       //SELECT("id,title,authername,date,content");
       SELECT("*");
       FROM(TABLE_NAME);
       //注意这里这种传递参数方式,#{}与map中的key对应,而map中的key又是注解param设置的
       WHERE("id = #{id}");
       return  SQL();
   }
   public  String getAllSql() {
       BEGIN();
       SELECT("*");
       FROM(TABLE_NAME);
       return  SQL();
   }
   public  String getSqlByTitle(Map<String, Object> parameter) {
       String title = (String) parameter.get("title");
       BEGIN();
       SELECT("*");
       FROM(TABLE_NAME);
       if  (title !=  null)
           WHERE(" title like #{title}");
       return  SQL();
   }
   public  String insertSql() {
       BEGIN();
       INSERT_INTO(TABLE_NAME);
       VALUES("title",  "#{title}");
       //  VALUES("title", "#{tt.title}");
       //这里是传递一个Blog对象的,如果是利用上面tt.方式,则必须利用Param来设置别名
       VALUES("date",  "#{date}");
       VALUES("authername",  "#{authername}");
       VALUES("content",  "#{content}");
       return  SQL();
   }
   public  String deleteSql() {
       BEGIN();
       DELETE_FROM(TABLE_NAME);
       WHERE("id = #{id}");
       return  SQL();
   }
   public  String updateSql() {
       BEGIN();
       UPDATE(TABLE_NAME);
       SET("content = #{content}");
       WHERE("id = #{id}");
       return  SQL();
   }
}

注意由于在映射器接口中调用了@ResultMap,该注解内容是SQL配置文件ResultMap的ID,它是允许访问SQL配置文件中的ResultMap,则需要在相应的SQL配置相应ResultMap,然后再在主配置文件加上该SQL配置的Mapper路径。并且该SQL配置文件的namespace必须与使用@ResultMap的映射器接口的全限定相同。Blog.xml如下。

1
2
3
4
5
6
7
8
9
10
11
12
<?xml  version="1.0"  encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper  namespace="com.whut.inter.IBlogDAO">
  <resultMap  type="Blog"  id="sqlBlogsMap">
     <id  property="id"  column="id"/>
     <result  property="title"  column="title"/>
     <result  property="authername"  column="authername"/>
     <result  property="date"  column="date"/>
     <result  property="content"  column="content"/>
  </resultMap>
</mapper>

再在主配置文件mybatis-config.xml加入一句mapper。

1
2
3
<mappers>
       <mapper  resource="com/whut/model/Blog.xml"/>
</mappers>


测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package  com.whut.test;
import  java.io.IOException;
import  java.io.Reader;
import  java.util.List;
import  org.apache.ibatis.io.Resources;
import  org.apache.ibatis.session.SqlSession;
import  org.apache.ibatis.session.SqlSessionFactory;
import  org.apache.ibatis.session.SqlSessionFactoryBuilder;
import  com.whut.inter.IBlogDAO;
import  com.whut.model.Blog;
/**
 * 注意这里是一种利用SqlBuilder以及多种设置来注解使用
 * @author zxl
 *
 */
public  class  TestBlog {
   private  static  SqlSessionFactory sqlSessionFactory;
   private  static  Reader reader;
   static  {
       try  {
           Reader reader = Resources.getResourceAsReader("mybatic-config.xml");
           sqlSessionFactory =  new  SqlSessionFactoryBuilder().build(reader);
           // 由于使用了注解,所以在主配置文件没有mapper,需要在代码里显示注册该mapper接口
           //sqlSessionFactory.getConfiguration().addMapper(IBlogDAO.class);
       }  catch  (IOException e) {
           e.printStackTrace();
       }
   }
                                                                                                                          
   public  static  void  main(String[] args) {
       //testOneBlog();
       //testAllBlog();
       //testBlogByTitle();
       //testAddBlog();
       //testDeleteBlog();
                                                                                                                              
       testUpdateBlog();
   }
                                                                                                                          
   public  static  void  testOneBlog()
   {
       SqlSession session=sqlSessionFactory.openSession();
       try{
           IBlogDAO dao=session.getMapper(IBlogDAO.class);
           Blog  blog=dao.getBlog(2);
           System.out.println(blog.getId()+"\t"+blog.getAuthername()+"\t"+blog.getTitle());
       }finally{
           session.close();
       }
                                                                                                                              
   }
   public  static  void  testAllBlog()
   {
       SqlSession session=sqlSessionFactory.openSession();
       try{
           IBlogDAO dao=session.getMapper(IBlogDAO.class);
           List<Blog>  blogs=dao.getAllBlog();
           System.out.println("编号\t作者\t标题");
           for(Blog blog:blogs)
           System.out.println(blog.getId()+"\t"+blog.getAuthername()+"\t"+blog.getTitle());
       }finally{
           session.close();
       }
   }
   public  static  void  testBlogByTitle()
   {
       SqlSession session=sqlSessionFactory.openSession();
       try{
           IBlogDAO dao=session.getMapper(IBlogDAO.class);
           List<Blog>  blogs=dao.getBlogByTitle("%word%");
           System.out.println("编号\t作者\t标题");
           for(Blog blog:blogs)
           System.out.println(blog.getId()+"\t"+blog.getAuthername()+"\t"+blog.getTitle());
       }finally{
           session.close();
       }
   }
                                                                                                                          
   public  static  void  testAddBlog()
   {
       SqlSession session=sqlSessionFactory.openSession();
       Blog blog=new  Blog();
       blog.setTitle("chuntian");
       blog.setAuthername("xiaohua");
       blog.setDate("2013/12/25");
       blog.setContent("bushuangyayya");
       try{
           IBlogDAO dao=session.getMapper(IBlogDAO.class);
           dao.insertBlog(blog);
           session.commit();
       }finally{
           session.close();
       }
   }
                                                                                                                          
   public  static  void  testDeleteBlog()
   {
       SqlSession session=sqlSessionFactory.openSession();
       try{
           IBlogDAO dao=session.getMapper(IBlogDAO.class);
           dao.deleteBlog(5);
           session.commit();
       }finally{
           session.close();
       }
   }
                                                                                                                          
   public  static  void  testUpdateBlog()
   {
       SqlSession session=sqlSessionFactory.openSession();
       Blog blog=new  Blog();
       blog.setId(6);
       blog.setTitle("daxuexiaoyuan");
       blog.setAuthername("xiaohua");
       blog.setDate("2013/2/25");
       blog.setContent("冷死了");
       try{
           IBlogDAO dao=session.getMapper(IBlogDAO.class);
           dao.updateBlog(blog);
           session.commit();
       }finally{
           session.close();
       }
   }
}

注意事项:

1) 在利用注解配置映射器接口的时候,必须要通过

sqlSessionFactory.getConfiguration().addMapper(IBlogDAO.class);来对给映射器接口注册,如果映射器接口中使用了@ResultMap注解,则由于已经在mybatis-config.xml配置了Mapper,则就不需要再次在代码中添加mapper。

2)当方法有多个参数的时候,为了与SQL语句中的#{}对应,一般可以使用@Param("")来为每个参数命别名,使得该别名与#{}对应。当参数只有一个的时候,不需要别名。

3 在进行更新删除添加的时候,如果传递的是一个实体对象,则SQL可以直接使用实体的属性。

4)映射器接口调用SqlBuilder中的方法,都是将参数转换为Map中的key,可以在SqlBuilder的方法中利用Map来获取传递的参数值,进而进行逻辑操作判断。

5)注解中对于返回多条记录的查询可以直接利用@Results和@Result来配置映射,或者利用@ResultMap来调用SQL配置文件中的ResultMap。

本文出自 “在云端的追梦” 博客,请务必保留此出处http://computerdragon.blog.51cto.com/6235984/1399742

你可能感兴趣的:(转载: MyBatis注解Annotation介绍及Demo)