注解提供了一种简单的方式来实现简单映射语句,而不会引入大量的开销。能够读懂别人写的代码,特别是框架相关的代码。本来可能需要很多配置文件,需要很多逻辑才能实现的内容,就可以使用一个或者多个注解的方式来代替,这样就使得编程更加的简洁,代码更加清晰。
由于开发越来越流行,mybatis也可以使用注解开发方式,这样我们可以减少编程时编写的mapper映射文件。此次是围绕着一些基本的CRUD来学习,再学习复杂的映射关系和延迟加载。
@Insert: 实现新增
@Update:实现更新
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result一起使用,封装多个结果的集合(其内使用@Result处理当前对象的基本属性,再处理返回值)
@ResultMap:实现引用@Results定义的封装
@One:实现一对一结果集 封装
@Many:实现一对多结果集封装
@SelectProvider:实现动态SQL映射
@CacheNamespace:实现注解二级缓存的使用
注意:复杂的注解不好编写的情况下可以使用Mapper文件配合使用
在StudentMapper接口中使用注解的方式操作数据库数据
package com.etime.mapper;
import com.etime.pojo.Student;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
public interface StudentMapper {
//使用@Select注解查询所有学生信息
@Select("select * from student")
List<Student> getAllStudent();
//使用@Insert注解向学生表中插入数据
@Insert("insert student(sname,cid) values(#{sname},#{cid})")
int addStudent(Student student);
//使用@Delete注解根据学生id删除学生信息
@Delete("delete from student where sid=#{sid}")
int delStudent(int sid);
//使用@Update注解根据学生id更新学生数据库信息
@Update("update student set sname=#{sname} where sid=#{sid}")
int updateStudent(Student student);
}
测试:
//通过@Select注解方式查询学生的所有信息
@Test
public void t04(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> studentList = studentMapper.getAllStudent();
studentList.forEach(System.out::println);
}
//通过@Insert注解向学生表中插入数据
@Test
public void t05(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
int row = studentMapper.addStudent(new Student(0,"王小二",2));
System.out.println("数据库影响行数:"+row);
}
//通过@Delete注解根据学生id删除学生信息
@Test
public void t06(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
int row = studentMapper.delStudent(7);
System.out.println("数据库受影响行数:"+row);
}
//通过@Update注解根据学生id更改学生信息
@Test
public void t07(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
//注意这里的学生对象不能够使用匿名对象,因为需要设置学生更新条件id
Student student = new Student(3,"缓缓",2);
int row = studentMapper.updateStudent(student);
System.out.println("数据库影响行数:"+row);
}
运行结果:
@Results代替了标签< resultMap> 该注解中可以使用单个@Result注解,也可以使用@Result集合
格式:
@Results ({@Result () , @Result ()}) 或者@Result (@Result())
@Result注解代替了< id> 标签和< result>标签
id 是否是主键字段
column 数据库中列的名
property 需要装配的属性名
one 需要使用 @One 注解 (@Result (one = @One) ())
many 需要使用的@Many 注解 (@Result (many = @many) ())
代替了< association>标签,是多表查询的关键,在注解中用来制定子查询返回单一对象
select 指定用来多表查询 的 sqlmapper
fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。
语法格式:
@Result(column = " “,property=” ",one=@Onet(select = " "))
代替了< Collection>标签,是多表查询的关键,在注解中用来指定子查询返回对象集合。
注意:聚集元素用来处理"一对多"的关系。需要指定映射的Java实体类的属性,属性的javaType(一般为ArrayList)但是注解中可以不定义;
语法格式:
@Result(property=" “,column=” “,many=@Many(select=” "))
在HusbandMapper.java接口中使用注解进行查询注入数据
HusbandMapper.java
package com.etime.mapper;
import com.etime.pojo.Husband;
import com.etime.pojo.Wife;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface HusbandMapper {
//使用一对一关系注解实现查询
@Select("select * from husband")//查询所有丈夫的信息
//将信息放入结果集合中
@Results({
@Result(property = "hid",column = "hid"),//设置字段属性对应的数据库列名
@Result(property = "hname",column = "hname"),
@Result(property = "wid",column = "wid"),
//对根据丈夫表内的对应妻子wid到妻子表中查找妻子的信息
@Result(property = "wife",javaType = Wife.class,column = "wid",
one=@One(select = "com.etime.mapper.WifeMapper.getWifeByWid"))
})
List<Husband> getAllHusband();
}
在WifeMapper.java中进行注解的使用,对妻子的基本数据进行数据查取
package com.etime.mapper;
import com.etime.pojo.Wife;
import org.apache.ibatis.annotations.Select;
public interface WifeMapper {
//通过@Select查询注解的方方式获取到妻子的基本数据
@Select("select * from wife where wid=#{wid}")
Wife getWifeByWid(int wid);
}
对妻子和丈夫的一对一的关系进行测试:
//使用一对一关系注解查询丈夫和妻子的基本信息
@Test
public void t07(){
SqlSession sqlSession =sqlSessionUtil.getSqlSession();
HusbandMapper husbandMapper = sqlSession.getMapper(HusbandMapper.class);
List<Husband> list = husbandMapper.getAllHusband();
list.forEach(System.out::println);
sqlSession.close();
}
最终得到的测试结果为:
这里即将的测试的关系是多个学生属于同一班的关系
创建学生实体类:
package com.etime.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Student {
private int sid;
private String sname;
private int cid;
//创建一个班级类的属性给到学生实体类,不同的学生来自不同的班,多个学生属于同一个班级
private Classes classes;
}
创建班级实体类:
package com.etime.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Classes {
private int cid;
private String cname;
}
在StudentMapper.java接口中使用注解的方式处理查询语句一查查询到的数据 问题,并处理 查询到的班级classes返回的值
package com.etime.mapper;
import com.etime.pojo.Classes;
import com.etime.pojo.Student;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface StudentMapper {
//使用@Select查询所有学生信息
@Select("select * from student")
//使用@Results注解处理查询到的学生实体类中的基本属性以及对应的班级信息
//并通过one = @One 的方式把查询到接收到的返回班级实体类进行处理
@Results({
@Result(property = "sid",column = "sid"),
@Result(property = "sname",column = "sname"),
@Result(property = "cid",column = "cid"),
@Result(property = "classes",javaType = Classes.class,column = "cid",
one = @One(select = "com.etime.mapper.ClassesMapper.getClassesByCid"))
})
List<Student> getAllStudent();
}
在ClassesMapper.java中使用注解的方式根据班级id查询班级的相关信息
ClassesMapper.java
package com.etime.mapper;
import com.etime.pojo.Classes;
import org.apache.ibatis.annotations.Select;
public interface ClassesMapper {
//使用@Select注解的方式通过查询返回值为班级对象给到学生实体类做数据处理的StudentMapper接口的one = @One处理
@Select("select * from classes where cid=#{cid}")
Classes getClassesByCid(int cid);
}
编写测试:
@Test
public void t08(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> list = studentMapper.getAllStudent();
list.forEach(System.out::println);
sqlSession.close();
}
由上面的准备我们将测试多对一查询的情况:
对代码进行修改测试查看是否书写更简便些
修改学生实体类:
Student.java
package com.etime.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Student {
private int sid;
private String sname;
private int cid;
}
对班级实体类进行修改
Classes.java
package com.etime.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Classes {
private int cid;
private String cname;
List<Student> stuList;
}
对学生类的数据获取接口做修改
public interface StudentMapper {
//使用@Select查询所有学生信息
@Select("select * from student where cid=#{cid}")
Student getStudentByCid(int cid);
}
对班级类进行数据获取进行数据处理
package com.etime.mapper;
import com.etime.pojo.Classes;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface ClassesMapper {
//使用@Select注解的方式通过查询返回值为学生对象给到班级实体类做数据处理的ClassesMapper接口的many = @Many多条数据处理
//其实由这里可以看出来多对一和一对多是差不多的看是哪一个为主体
//这里返回来处理的是集合所以javaType给到的是List.call 数据做处理的也是@Many注解(注意many=@Many别误解为多对多)
@Select("select * from classes")
@Results({
@Result(property = "cid",column = "cid"),
@Result(property = "cname",column = "cname"),
@Result(property = "stuList",javaType = List.class,column = "cid",
many = @Many(select = "com.etime.mapper.StudentMapper.getStudentByCid"))
})
List<Classes> getAllClasses();
}
由上可知的一对多的方式进行的数据查询可以看出,其实两种方式都差不多,只是看是怎么看他们之间的关系型,以谁为主体
运行结果:
由上面的关系可知在开发中常见的还属是多对多的关系,接下来进行注解的测试对多对多关系的测试
众所周知的学生和课程之间是常见的多对多的关系,接下来就以学生关系来测试多对多的关系
创建课程实体类:
package com.etime.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@Data
@NoArgsConstructor
public class Course {
private int courseid;
private String coursename;
}
创建学生实体类对象:
Student.java
package com.etime.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Student implements Serializable {
private int sid;
private String sname;
private int cid;
private List<StudentCourse> studentCourseList;
}
创建学生和课程的关系表的实体类:
StudentCourse.java
package com.etime.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class StudentCourse {
private int scid;
private int sid;
private int courseid;
private Course course;
}
创建课程CourseMapper.java接口查询数据:
package com.etime.mapper;
import com.etime.pojo.Course;
import org.apache.ibatis.annotations.Select;
public interface CourseMapper {
//由课程id到课程表中进行查询课程信息
@Select("select * from course where courseid=#{courseid}")
Course getCourseByCourseid(int courseid);
}
创建学生StudentMapper.java接口查询数据处理:
package com.etime.mapper;
import com.etime.pojo.Classes;
import com.etime.pojo.Student;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface StudentMapper {
//使用@Select查询所有学生信息
//通过@Result注解中的属性many = @Many进行数据处理,将得到的课程对象返回到学生实体类对象studentCourseList中
@Select("select * from student")
@Results({
@Result(property = "sid",column = "sid"),
@Result(property = "sname",column = "sname"),
@Result(property = "cid",column = "cid"),
@Result(property = "studentCourseList",javaType = List.class,column = "sid",
many = @Many(select = "com.etime.mapper.StudentCourseMapper.getStudentCourseBySid"))
})
List<Student> getStudentAndCourse();
}
创建学生课程接口StudentCourseMapper.java查询数据,对数据进行处理:
package com.etime.mapper;
import com.etime.pojo.Course;
import com.etime.pojo.StudentCourse;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface StudentCourseMapper {
//@Select同样的通过注解的方式对数据进行全部查询,处理的通过id查询到的课程单个实体类
@Select("select * from studentcourse where sid=#{sid}")
@Results({
@Result(property = "scid",column = "scid"),
@Result(property = "sid",column = "sid"),
@Result(property = "courseid",column = "courseid"),
@Result(property = "course",javaType = Course.class,column = "courseid",
one = @One(select = "com.etime.mapper.CourseMapper.getCourseByCourseid"))
})
//根据学生id查找所有课程对应的id
List<StudentCourse> getStudentCourseBySid(int sid);
}
通过上述的以系列操作,咱们是能够通过注解的方式查询到多对多的关系数据的:
运行结果如图: