ECM
ECM
总版主
总版主
  • 社区居民
  • 忠实会员
  • 原创写手
阅读:1022回复:0

MyBatis注解Annotation介绍及Demo

楼主#
更多 发布于:2016-08-07 21:34
MyBatis可以利用SQL映射文件来配置,也可以利用Annotation来设置。MyBatis提供的一些基本注解如下表所示。
注解
目标
相应的XML
描述
@CacheNamespace

<cache>
为给定的命名空间(比如类)配置缓存。属性:
implemetation,eviction,
flushInterval , size 和 readWrite 。
@CacheNamespaceRef

<cacheRef>
参照另外一个命名空间的缓存来使用。
属性:value,也就是类的完全限定名。
@ConstructorArgs
方法
<constructor>
收集一组结果传递给对象构造方法。
属性:value,是形式参数的数组
@Arg
方法
<arg>
<idArg>
 
单独的构造方法参数,是ConstructorArgs 集合的一部分。属性:id,column,javaType,typeHandler。
id属性是布尔值,来标识用于比较的属性,和<idArg>XML 元素相似
@TypeDiscriminator
方法
<discriminator>
一组实例值被用来决定结果映射的表
现。属性:Column, javaType , jdbcType typeHandler,cases。
cases属性就是实例的数组。
@Case
方法
<case>
单独实例的值和它对应的映射。属性:value ,type ,results 。
Results 属性是结果数组,因此这个注解和实际的ResultMap 很相似,由下面的 Results注解指定
@Results
方法
<resultMap>
结果映射的列表,包含了一个特别结果
列如何被映射到属性或字段的详情。
属性:value ,是Result注解的数组
@Result
方法
<result>
<id>
在列和属性或字段之间的单独结果映
射。属性:id ,column , property ,
javaType ,jdbcType ,type Handler ,
one,many。id 属性是一个布尔值,表
示了应该被用于比较的属性。one 属性是单独的联系,和 <association> 相似,而many 属性是对集合而言的,和
<collection>相似。
@One
方法
<association>
复杂类型的单独属性值映射。属性:
select,已映射语句(也就是映射器方
法)的完全限定名,它可以加载合适类
型的实例。注意:联合映射在注解 API
中是不支持的。
@Many
方法
<collection>
复杂类型的集合属性映射。属性:
select,是映射器方法的完全限定名,它可加载合适类型的一组实例。注意:联合映射在 Java注解中是不支持的。
@Options
方法
映射语句的属性
这个注解提供访问交换和配置选项的宽广范围,它们通常在映射语句上作为属性出现。而不是将每条语句注解变复杂,Options 注解提供连贯清晰的方式来访问它们。属性:useCache=true,
flushCache=false,
resultSetType=FORWARD_ONLY,
statementType=PREPARED,
fetchSize= -1,timeout=-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
指定的方法. 这个方法可以选择性的接
受参数对象作为它的唯一参数,但是必
须只指定该参数或者没有参数。属性:
type,method。type 属性是类的完全限定名。method 是该类中的那个方法名。
@Param
参数
N/A
当映射器方法需多个参数,这个注解可以被应用于映射器方法参数来给每个参数一个名字。否则,多参数将会以它们的顺序位置来被命名。比如
#{1},#{2} 等,这是默认的。
使用@Param(“person”),SQL中参数应该被命名为#{person}。
这些注解都是运用到传统意义上映射器接口中的方法、类或者方法参数中的。
今天主要介绍两种使用注解的方式。
一种是直接在映射器接口中写SQL语句,一种是利用SqlBuilder来创建SQL再由映射器接口来调用
准备前提:
1,配置常规的MyBatis主配置文件,即各种数据源,别名等设置。在利用注解配置SQL的时候,一般不需要在主配置文件中配置Mapper,个别情况下需要配置。
2,数据库表Blog:
01.
DROP TABLE IF EXISTS `blog`;
02.
CREATE TABLE `blog` (
03.
`id` int(10) NOT NULL auto_increment,
04.
`title` varchar(200) NOT NULL,
05.
`date` varchar(50) NOT NULL,
06.
`authername` varchar(15) NOT NULL,
07.
`content` varchar(500) NOT NULL,
08.
PRIMARY KEY  (`id`)
09.
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
数据库表User:
1.
DROP TABLE IF EXISTS `user`;
2.
CREATE TABLE `user` (
3.
`id` int(11) NOT NULL auto_increment,
4.
`userName` varchar(50) default NULL,
5.
`userAge` int(11) default NULL,
6.
`userAddress` varchar(200) default NULL,
7.
PRIMARY KEY  (`id`)
8.
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3,分别写User和Blog对应的JavaBean即setter和getter实体类。
第一种 映射器接口中写SQL语句
映射器接口注解
 
01.
package com.whut.inter;
02.
import java.util.List;
03.
import org.apache.ibatis.annotations.Delete;
04.
import org.apache.ibatis.annotations.Insert;
05.
import org.apache.ibatis.annotations.Param;
06.
import org.apache.ibatis.annotations.Select;
07.
import org.apache.ibatis.annotations.Update;
08.
import com.whut.model.User;
09.
//最基本的注解CRUD
10.
public interface IUserDAO {
11.
@Select("select *from User")
12.
public List<User> retrieveAllUsers();
13.
 
14.
//注意这里只有一个参数,则#{}中的标识符可以任意取
15.
@Select("select *from User where id=#{idss}")
16.
public User retrieveUserById(int id);
17.
 
18.
@Select("select *from User where id=#{id} and userName like #{name}")
19.
public User retrieveUserByIdAndName(@Param("id")int id,@Param("name")String names);
20.
 
21.
@Insert("INSERT INTO user(userName,userAge,userAddress) VALUES(#{userName},"
22.
+ "#{userAge},#{userAddress})")
23.
public void addNewUser(User user);
24.
 
25.
@Delete("delete from user where id=#{id}")
26.
public void deleteUser(int id);
27.
 
28.
@Update("update user set userName=#{userName},userAddress=#{userAddress}"
29.
+ " where id=#{id}")
30.
public void updateUser(User user);
31.
}
测试代码:
001.
package com.whut.test;
002.
import java.io.IOException;
003.
import java.io.Reader;
004.
import java.util.List;
005.
import org.apache.ibatis.io.Resources;
006.
import org.apache.ibatis.session.SqlSession;
007.
import org.apache.ibatis.session.SqlSessionFactory;
008.
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
009.
import com.whut.inter.IUserDAO;
010.
import com.whut.model.User;
011.
public class TestUser {
012.
private static SqlSessionFactory sqlSessionFactory;
013.
private static Reader reader;
014.
static {
015.
try {
016.
Reader reader = Resources.getResourceAsReader("mybatic-config.xml");
017.
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
018.
// 由于使用了注解,所以在主配置文件没有mapper,需要在代码里显示注册该mapper接口
019.
sqlSessionFactory.getConfiguration().addMapper(IUserDAO.class);
020.
} catch (IOException e) {
021.
e.printStackTrace();
022.
}
023.
}
024.
public static void main(String[] args) {
025.
// testSelectAll();
026.
// testSelectByConditions();
027.
//testAddUser();
028.
//testDeleteUser();
029.
 
030.
testUpateUser();
031.
}
032.
public static void testSelectAll() {
033.
// sqlSessionFactory.getConfiguration().addMapper(IUserDAO.class);
034.
SqlSession session = sqlSessionFactory.openSession();
035.
try {
036.
IUserDAO userDAO = session.getMapper(IUserDAO.class);
037.
List<User> users = userDAO.retrieveAllUsers();
038.
System.out.println("用户编号\t" + "姓名\t" + "年龄\t住址");
039.
for (User u : users) {
040.
System.out.println(u.getId() + "\t" + u.getUserName() + "\t"
041.
+ u.getUserAge() + "\t" + u.getUserAddress());
042.
}
043.
} finally {
044.
session.close();
045.
}
046.
}
047.
public static void testSelectByConditions() {
048.
SqlSession session = sqlSessionFactory.openSession();
049.
try {
050.
IUserDAO userDAO = session.getMapper(IUserDAO.class);
051.
User u = userDAO.retrieveUserByIdAndName(4, "%spring%");
052.
if (u != null) {
053.
System.out.println("用户编号\t" + "姓名\t" + "年龄\t住址");
054.
System.out.println(u.getId() + "\t" + u.getUserName() + "\t"
055.
+ u.getUserAge() + "\t" + u.getUserAddress());
056.
}
057.
} finally {
058.
session.close();
059.
}
060.
}
061.
public static void testAddUser() {
062.
User u = new User();
063.
u.setUserName("dongtian");
064.
u.setUserAge(51);
065.
u.setUserAddress("hubeisheng");
066.
SqlSession session = sqlSessionFactory.openSession();
067.
try {
068.
IUserDAO userDAO = session.getMapper(IUserDAO.class);
069.
userDAO.addNewUser(u);
070.
session.commit();
071.
} finally {
072.
session.close();
073.
}
074.
}
075.
public static void testDeleteUser() {
076.
SqlSession session = sqlSessionFactory.openSession();
077.
try {
078.
IUserDAO userDAO = session.getMapper(IUserDAO.class);
079.
userDAO.deleteUser(7);
080.
session.commit();
081.
} finally {
082.
session.close();
083.
}
084.
}
085.
 
086.
public static void testUpateUser() {
087.
User u = new User();
088.
u.setId(4);
089.
u.setUserName("dongtian");
090.
u.setUserAge(51);
091.
u.setUserAddress("hubeisheng");
092.
SqlSession session = sqlSessionFactory.openSession();
093.
try {
094.
IUserDAO userDAO = session.getMapper(IUserDAO.class);
095.
userDAO.updateUser(u);
096.
session.commit();
097.
} finally {
098.
session.close();
099.
}
100.
}
101.
}
 
第二种 映射器接口调用SqlBuilder生成的SQL进行执行
映射器接口
 
01.
package com.whut.inter;
02.
import java.util.List;
03.
import org.apache.ibatis.annotations.CacheNamespace;
04.
import org.apache.ibatis.annotations.DeleteProvider;
05.
import org.apache.ibatis.annotations.InsertProvider;
06.
import org.apache.ibatis.annotations.Options;
07.
import org.apache.ibatis.annotations.Param;
08.
import org.apache.ibatis.annotations.Result;
09.
import org.apache.ibatis.annotations.ResultMap;
10.
import org.apache.ibatis.annotations.Results;
11.
import org.apache.ibatis.annotations.SelectProvider;
12.
import org.apache.ibatis.annotations.UpdateProvider;
13.
import org.apache.ibatis.type.JdbcType;
14.
import com.whut.model.Blog;
15.
import com.whut.sqlTool.BlogSqlProvider;
16.
@CacheNamespace(size=100)
17.
public interface IBlogDAO {
18.
@SelectProvider(type = BlogSqlProvider.class, method = "getSql")
19.
@Results(value ={
20.
@Result(id=true, property="id",column="id",javaType=Integer.class,jdbcType=JdbcType.INTEGER),
21.
@Result(property="title",column="title",javaType=String.class,jdbcType=JdbcType.VARCHAR),
22.
@Result(property="date",column="date",javaType=String.class,jdbcType=JdbcType.VARCHAR),
23.
@Result(property="authername",column="authername",javaType=String.class,jdbcType=JdbcType.VARCHAR),
24.
@Result(property="content",column="content",javaType=String.class,jdbcType=JdbcType.VARCHAR),
25.
})
26.
public Blog getBlog(@Param("id") int id);
27.
 
28.
@SelectProvider(type = BlogSqlProvider.class, method = "getAllSql")
29.
@Results(value ={
30.
@Result(id=true, property="id",column="id",javaType=Integer.class,jdbcType=JdbcType.INTEGER),
31.
@Result(property="title",column="title",javaType=String.class,jdbcType=JdbcType.VARCHAR),
32.
@Result(property="date",column="date",javaType=String.class,jdbcType=JdbcType.VARCHAR),
33.
@Result(property="authername",column="authername",javaType=String.class,jdbcType=JdbcType.VARCHAR),
34.
@Result(property="content",column="content",javaType=String.class,jdbcType=JdbcType.VARCHAR),
35.
})
36.
public List<Blog> getAllBlog();
37.
 
38.
@SelectProvider(type = BlogSqlProvider.class, method = "getSqlByTitle")
39.
@ResultMap(value = "sqlBlogsMap")
40.
//这里调用resultMap,这个是SQL配置文件中的,必须该SQL配置文件与本接口有相同的全限定名
41.
//注意文件中的namespace路径必须是使用@resultMap的类路径
42.
public List<Blog> getBlogByTitle(@Param("title")String title);
43.
 
44.
@InsertProvider(type = BlogSqlProvider.class, method = "insertSql")
45.
public void insertBlog(Blog blog);
46.
 
47.
@UpdateProvider(type = BlogSqlProvider.class, method = "updateSql")
48.
public void updateBlog(Blog blog);
49.
 
50.
@DeleteProvider(type = BlogSqlProvider.class, method = "deleteSql")
51.
@Options(useCache = true, flushCache = false, timeout = 10000)
52.
public void deleteBlog(int ids);
53.
 
54.
}
 
SQL生成器(利用SqlBuilder生成)
01.
package com.whut.sqlTool;
02.
import java.util.Map;
03.
import static org.apache.ibatis.jdbc.SqlBuilder.*;
04.
public class BlogSqlProvider {
05.
private final static String TABLE_NAME = "blog";
06.
public String getSql(Map<Integer, Object> parameter) {
07.
BEGIN();
08.
//SELECT("id,title,authername,date,content");
09.
SELECT("*");
10.
FROM(TABLE_NAME);
11.
//注意这里这种传递参数方式,#{}与map中的key对应,而map中的key又是注解param设置的
12.
WHERE("id = #{id}");
13.
return SQL();
14.
}
15.
public String getAllSql() {
16.
BEGIN();
17.
SELECT("*");
18.
FROM(TABLE_NAME);
19.
return SQL();
20.
}
21.
public String getSqlByTitle(Map<String, Object> parameter) {
22.
String title = (String) parameter.get("title");
23.
BEGIN();
24.
SELECT("*");
25.
FROM(TABLE_NAME);
26.
if (title != null)
27.
WHERE(" title like #{title}");
28.
return SQL();
29.
}
30.
public String insertSql() {
31.
BEGIN();
32.
INSERT_INTO(TABLE_NAME);
33.
VALUES("title", "#{title}");
34.
//  VALUES("title", "#{tt.title}");
35.
//这里是传递一个Blog对象的,如果是利用上面tt.方式,则必须利用Param来设置别名
36.
VALUES("date", "#{date}");
37.
VALUES("authername", "#{authername}");
38.
VALUES("content", "#{content}");
39.
return SQL();
40.
}
41.
public String deleteSql() {
42.
BEGIN();
43.
DELETE_FROM(TABLE_NAME);
44.
WHERE("id = #{id}");
45.
return SQL();
46.
}
47.
public String updateSql() {
48.
BEGIN();
49.
UPDATE(TABLE_NAME);
50.
SET("content = #{content}");
51.
WHERE("id = #{id}");
52.
return SQL();
53.
}
54.
}
 
注意由于在映射器接口中调用了@ResultMap,该注解内容是SQL配置文件ResultMap的ID,它是允许访问SQL配置文件中的ResultMap,则需要在相应的SQL配置相应ResultMap,然后再在主配置文件加上该SQL配置的Mapper路径。并且该SQL配置文件的namespace必须与使用@ResultMap的映射器接口的全限定相同。Blog.xml如下。
01.
<?xml version="1.0" encoding="UTF-8"?>
02.
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
03.
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
04.
<mapper namespace="com.whut.inter.IBlogDAO">
05.
<resultMap type="Blog" id="sqlBlogsMap">
06.
<id property="id" column="id"/>
07.
<result property="title" column="title"/>
08.
<result property="authername" column="authername"/>
09.
<result property="date" column="date"/>
10.
<result property="content" column="content"/>
11.
</resultMap>
12.
</mapper>
再在主配置文件mybatis-config.xml加入一句mapper。
1.
<mappers>
2.
<mapper resource="com/whut/model/Blog.xml"/>
3.
</mappers>
 
测试类
001.
package com.whut.test;
002.
import java.io.IOException;
003.
import java.io.Reader;
004.
import java.util.List;
005.
import org.apache.ibatis.io.Resources;
006.
import org.apache.ibatis.session.SqlSession;
007.
import org.apache.ibatis.session.SqlSessionFactory;
008.
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
009.
import com.whut.inter.IBlogDAO;
010.
import com.whut.model.Blog;
011.
/**
012.
* 注意这里是一种利用SqlBuilder以及多种设置来注解使用
013.
* @author zxl
014.
*
015.
*/
016.
public class TestBlog {
017.
private static SqlSessionFactory sqlSessionFactory;
018.
private static Reader reader;
019.
static {
020.
try {
021.
Reader reader = Resources.getResourceAsReader("mybatic-config.xml");
022.
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
023.
// 由于使用了注解,所以在主配置文件没有mapper,需要在代码里显示注册该mapper接口
024.
//sqlSessionFactory.getConfiguration().addMapper(IBlogDAO.class);
025.
} catch (IOException e) {
026.
e.printStackTrace();
027.
}
028.
}
029.
 
030.
public static void main(String[] args) {
031.
//testOneBlog();
032.
//testAllBlog();
033.
//testBlogByTitle();
034.
//testAddBlog();
035.
//testDeleteBlog();
036.
 
037.
testUpdateBlog();
038.
}
039.
 
040.
public static void testOneBlog()
041.
{
042.
SqlSession session=sqlSessionFactory.openSession();
043.
try{
044.
IBlogDAO dao=session.getMapper(IBlogDAO.class);
045.
Blog  blog=dao.getBlog(2);
046.
System.out.println(blog.getId()+"\t"+blog.getAuthername()+"\t"+blog.getTitle());
047.
}finally{
048.
session.close();
049.
}
050.
 
051.
}
052.
public static void testAllBlog()
053.
{
054.
SqlSession session=sqlSessionFactory.openSession();
055.
try{
056.
IBlogDAO dao=session.getMapper(IBlogDAO.class);
057.
List<Blog>  blogs=dao.getAllBlog();
058.
System.out.println("编号\t作者\t标题");
059.
for(Blog blog:blogs)
060.
System.out.println(blog.getId()+"\t"+blog.getAuthername()+"\t"+blog.getTitle());
061.
}finally{
062.
session.close();
063.
}
064.
}
065.
public static void testBlogByTitle()
066.
{
067.
SqlSession session=sqlSessionFactory.openSession();
068.
try{
069.
IBlogDAO dao=session.getMapper(IBlogDAO.class);
070.
List<Blog>  blogs=dao.getBlogByTitle("%<a href="http://www.it165.net/edu/ebg/" target="_blank" class="keylink">word</a>%");
071.
System.out.println("编号\t作者\t标题");
072.
for(Blog blog:blogs)
073.
System.out.println(blog.getId()+"\t"+blog.getAuthername()+"\t"+blog.getTitle());
074.
}finally{
075.
session.close();
076.
}
077.
}
078.
 
079.
public static void testAddBlog()
080.
{
081.
SqlSession session=sqlSessionFactory.openSession();
082.
Blog blog=new Blog();
083.
blog.setTitle("chuntian");
084.
blog.setAuthername("xiaohua");
085.
blog.setDate("2013/12/25");
086.
blog.setContent("bushuangyayya");
087.
try{
088.
IBlogDAO dao=session.getMapper(IBlogDAO.class);
089.
dao.insertBlog(blog);
090.
session.commit();
091.
}finally{
092.
session.close();
093.
}
094.
}
095.
 
096.
public static void testDeleteBlog()
097.
{
098.
SqlSession session=sqlSessionFactory.openSession();
099.
try{
100.
IBlogDAO dao=session.getMapper(IBlogDAO.class);
101.
dao.deleteBlog(5);
102.
session.commit();
103.
}finally{
104.
session.close();
105.
}
106.
}
107.
 
108.
public static void testUpdateBlog()
109.
{
110.
SqlSession session=sqlSessionFactory.openSession();
111.
Blog blog=new Blog();
112.
blog.setId(6);
113.
blog.setTitle("daxuexiaoyuan");
114.
blog.setAuthername("xiaohua");
115.
blog.setDate("2013/2/25");
116.
blog.setContent("冷死了");
117.
try{
118.
IBlogDAO dao=session.getMapper(IBlogDAO.class);
119.
dao.updateBlog(blog);
120.
session.commit();
121.
}finally{
122.
session.close();
123.
}
124.
}
125.
}
 
注意事项:
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。

 

 

 

 

 

 

 

异常中心网是一家专门收集整理程序员编程过程中遇到的常见异常(exception)以及各种异常问答中心的网站。异常中心网旨在,减少程序员在编码遇到异常,处理各种异常时间和痛苦,让程序员能更愉快的、快速的定位异常并查找对应的异常解决方案。异常中心网诚心打造最完美的编程社区为程序员用户服务,努力成为最好的程序员乐园程序员社区程序异常中心程序bug中心异常问答中心

 

喜欢0 评分0
游客

返回顶部