前几天还觉得注解麻烦,突然恍然大悟,觉得注解相较于传统的mapper.xml+接口,xml使用接口映射相对较麻烦,所以我们可以使用注解来简化开发。
本文简单介绍一下@Results、@Result、@One和@Many的用法,该注解主要是代替resultMap标签和其子标签,还有一些通过注解crud的用法 学艺不精 还望多多指教
一、resultMap简介
MyBatis是基于“数据库结构不可控”的思想建立的,结果集映射就是MyBatis为我们提供这种理想与现实间转换的手段了,而resultMap就是结果集映射的配置标签了。有没有想到Resultset?哈哈有了mybatis就再也不用手写那些重复的步骤了,Mybatis是什么就不在这里介绍了
1.resultMap简介
在深入ResultMap标签前,我们需要了解从SQL查询结果集到JavaBean或POJO实体的过程。
-
通过JDBC查询得到ResultSet对象
-
遍历ResultSet对象并将每行数据暂存到HashMap实例中,以结果集的字段名或字段别名为键,以字段值为值
-
根据ResultMap标签的type属性通过反射实例化领域模型
-
根据ResultMap标签的type属性和id、result等标签信息将HashMap中的键值对,填充到领域模型实例中并返回
2.使用场景
在项目的实际开发中,有可能会遇到这样两种情况。
-
属性名和字段名不一致的情况,一种解决方法是使用别名,例如pwd as password,另一种就是使用结果集映射
-
多表查询的返回值中可能需要其他对象,或者数组(一对一和一对多)
二.resultMap对应的注解和用法
首先创建一个表
实体字段
实体字段 | 表的列名 |
---|---|
sid | stuid |
sname | stuname |
gid | gid |
grade | grade |
1.@Results注解
代替的是标签resultMap
该注解中可以使用单个@Result注解,也可以使用@Result集合
@Results({@Result(),@Result()})或@Results(@Result())
注意:使用注解是若报出org.apache.ibatis.binding.BindingException:Invalid bound statement (not found):接口全类名.方法名
可能是使用@Results注解时忘记使用@Select注解
@Results({@Result(column="stuid",property="sid"),@Result(column="stuname",property="sname")})
@Select("select * from student where gid=#{0}")
public List<Student> queryStudentByGid();
2.@Result注解
代替了 id标签和result标签
@Result 中 属性介绍:
column 数据库的列名
Property需要装配的属性名
one 需要使用的@One注解(@Result(one=@One)()))
many 需要使用的@Many注解(@Result(many=@many)()))
前两种肯定不陌生了,主要介绍one和many的用法。
@One注解(一对一)
代替了assocation标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
@One注解属性介绍:
select 指定用来多表查询的sqlmapper
fetchType会覆盖全局的配置参数lazyLoadingEnabled
所谓lazyLoadingEnabled就是懒加载,也称为延迟加载,只有在你需要的时候才查询表单
使用格式:
@Result(column=" “,property=”",one=@One(select=""))
例如:在获取某个学生的信息的同时又想获取所属班级的所有信息
学生实体中的字段
public class Student {
private Integer sid;//学生id
private String sname; //学生姓名
private Integer gid; //班级id
private Grade grade; //所属班级的所有信息
}
班级实体的字段
import java.util.List;
public class Grade {
private Integer id;//班级id
private String gname;//班级名称
public Grade() {
super();
// TODO Auto-generated constructor stub
}
}
在Student的字段中,Grade班级实体,需要查询班级表才能获取,学生表中没有该列(所以需要使用多表查询中,一对一关系,的 @Result中的one属性 和@One注解)
@Results({
@Result(column="stuid",property="sid"),
@Result(column="stuname",property="sname"),
@Result(column="gid",property="grade",one=@One(select="cn.et.fuqiang.resultMap.annotation.GradeAnnotationInterface.gradeInStudent"))})
@Select("select * from student")
public List<Student> queryAllStudent();
解析:
因为表中的字段与实体中的不同,所以使用了这两个注解,将表的列与实体的属
@Result(column=“stuid”,property=“sid”),
@Result(column=“stuname”,property=“sname”),
因为实体中还有一个班级实体属性,但表中没有该字段,所以就要用多表查询
@Result(column=“gid”,property=“grade”,one=@One(select=“cn.et.fuqiang.resultMap.annotation.GradeAnnotationInterface.gradeInStudent”))
(这里的property是实体中的字段,而column=gid就相当于关联的条件了
而select就是该关联条件对应的查询方法)
在namespace="cn.et.fuqiang.resultMap.annotation.GradeAnnotationInterface下的方法
@Results(@Result(property="id",column="gid"))
@Select("select * from grade where gid=#{0}")
public Grade gradeInStudent();
@Many注解(多对一)
代替了Collection标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。
注意:聚集元素用来处理“一对多”的关系。需要指定映射的Java实体类的属性,属性的javaType(一般为ArrayList)但是注解中可以不定义;
使用格式:
@Result(property="",column="",many=@Many(select=""))
代码和如上类似,可以通过班级和学生的关系来实现。
3.增删改查
比较常用也好理解 上代码直接
@Insert({" insert into category_ ( name ) values (#{name}) "})
int add(Category var1);
@Delete({" delete from category_ where id= #{id} "})
void delete(int var1);
@Select({"select * from category_ where id= #{id} "})
Category get(int var1);
@Update({"update category_ set name=#{name} where id=#{id} "})
int update(Category var1);
@Select("select count(*) from category_")
public int count();
public class TestMybatis {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
CategoryMapper mapper = session.getMapper(CategoryMapper.class);
// add(mapper);
// delete(mapper);
// get(mapper);
// update(mapper);
listAll(mapper);
session.commit();
session.close();
}
private static void update(CategoryMapper mapper) {
Category c= mapper.get(8);
c.setName("修改了的Category名稱");
mapper.update(c);
listAll(mapper);
}
private static void get(CategoryMapper mapper) {
Category c= mapper.get(8);
System.out.println(c.getName());
}
private static void delete(CategoryMapper mapper) {
mapper.delete(2);
listAll(mapper);
}
private static void add(CategoryMapper mapper) {
Category c = new Category();
c.setName("新增加的Category");
mapper.add(c);
listAll(mapper);
}
private static void listAll(CategoryMapper mapper) {
List<Category> cs = mapper.list();
for (Category c : cs) {
System.out.println(c.getName());
}
}
}
和xml映射方法不同的只不过是将sql语句写到上面去了
Vince_Wang1 发布了20 篇原创文章 · 获赞 0 · 访问量 239 私信 关注