背景:在mybatis中,我们可以通过xml的映射器配置文件实现对数据库的一系列操作,但是书写及其繁琐,掌握内容比较多,并且文件和接口只是名称相同,对应非常麻烦。所以Mybatis官方为我们提供了注解。帮助我们快速开发使用。下面我们一起来学习使用
1.Mybatis常用注解的分类:
基本注解:增删改查
结果映射注解:实现结果的映射关系,完成级联映射
动态SQL注解:实现动态SQL的内容
2.基本注解:
@Insert :类似 xml文件中的标签 <insert>
功能:完成新增操作
用法:@Insert("新增的sql语句")
说明:新增时所用的参数取值是接口方法的入参,可以是对象,也可以是Map集合
#eg.利用注解新增一条学生的数据记录 #参数为Java对象 @Insert("insert into student(sname,birthday,ssex,classid)" + "values(#{sname},#{birthday},#{ssex},#{classid})") public int addStudent(Student s);
注意:在添加学生时,存在主键回填,
主键回填:在添加时,并没有手动给主键值,而是由数据库主键自增实现,添加完成后,开启主键自增,那么此时的对象sid 就会 由 数据库把该条数据记录的自增主键回填给sid
简单来说:添加前sid无值,添加后有值,且和数据库id值一致
如何开启呢,只需要添加一个注解。
@Options:配置注解
useGeneratedKeys = true:开启主键回填
keyProperty = "sid":要填给那个属性
@Options(useGeneratedKeys = true,keyProperty = "sid")//主键回填
eg:开启主键回填
@Insert("insert into student(sname,birthday,ssex,classid)" + "values(#{sname},#{birthday},#{ssex},#{classid})") @Options(useGeneratedKeys = true,keyProperty = "sid")//主键回填 public int addStudent(Student s);
@Delete :类似 xml文件中的标签 <delete>完成新增
功能:完成删除操作,
语法:@Delete("sql语句")
说明:删除时所用的参数取值都是接口方法的入参,可以是对象,也可是Map集合
#利用注解实现根据sid删除学生 @Delete("delete from student where sid = #{sid}") public int deleteStudent(int sid);
@Update:类似 xml文件中的标签 <update>完成新增
功能:完成更新操作
语法:@Update("sql语句")
说明:更新时所用的参数取值都是接口方法的入参,可以是对象,也可是Map集合
#利用注解根据sid实现更新数据 @Update("update student set sname=#{sname},birthday=#{birthday}" + ",ssex=#{ssex},classid=#{classid} where sid=#{sid}") public int updateStudent(Student s);
@Select:类似 xml文件中的标签 <select>完成查询
功能:完成查询操作
语法:@Select("sql语句")
说明:查询时所用的参数取值都是接口方法的入参,可以是对象,也可是Map集合
#利用注解实现全查 @Select("select * from student") public List<Student> findAllStudent();
3.传递多个数的方式(以查询为例):
注意:此处只讲多值传递,单值传递直接使用,命名相同即可
方式一:Map方式 (不推荐,耦合度高)
#例如,此处map的键值, Map<String, Object> map = new HashMap<String, Object>(); map.put("bj",2); map.put("xb","男"); map.put("wz",(1-1)*3); map.put("bc",3); 注意:此种写法,必须要先知道map集合存放值得键。 //那么mapper 接口内 @Select("select * from student where classid=#{bj} and ssex=#{xb} limit #{wz},#{bc}") public List<Student> findStudentByClassidAndSsexlimit(Map<String, Object> map);
方式二:JavaBean方式 (缺点:只能传递对象属性值)
@Select("select * from student where sid=#{sid}") public Student findStudentById(Student stu);
方式三:@Param方式
@Select("select * from student where ssex=#{ssex} and classid=#{classid}" + " limit #{weizhi},#{bc}") public List<Student> findStudentBySsexAndClassidlimit( @Param("ssex")String ssex, @Param("classid") int classid, @Param("weizhi")int weizhi, @Param("bc")int bc);
在XML中还有arg数,param数传递,此处不做演示
4.结果集映射注解:
首先呢,我们要知道什么是结果集映射,在java中类与类之间存在一对一,一对多,多对多的关系,在这种关系中,我们就必须搞清楚关系,形成映射。例如学生和班级的关系,一个班级可以有多个学生,但是一个学生只有一个班级。如果我们查找一个班级里的所有学生(一对多)或者查找一个学生对应的班级(一对一)就需要映射。多对多的关系没办法实现代码,此处不做演示
下面我们以此为例:
一对一:查找学生对应的班级
1.首先,给student类添加一个班级对象 clazz
Studentmapper接口:
注解的作用:@Results:实现映射,id属性:唯一名称, value:内部映射具体属性
@Result:映射每一列,一对一只需要映射,映射不上的JavaBean类型的属性,但是此处,会将参数classid传递,映射给clazz对象的属性。如果此处想Student内部的classid有值,就需要加上此句映射 column:数据库字段名,poperty:java对象属性名
one=@One(select = "调用的外部方法路径"):注意一对一语法规定用One,
#注意: #1.通过注解Results实现映射,它是将student类内部的classid当作参数,传递 #调用clazz类中的findClazzByClassid查找班级对象,完成映射。 @Results(id="nihao",value={ @Result(column = "classid",property = "classid"), @Result(property = "clazz", column="classid", one=@One(select = "com.ape.mapper.ClazzMapper.findClazzByClassid")) }) @Select("select * from student") public List<Student> findAllStudentAndClass();
ClazzMapper接口:
//查询班级根据classid @Select("select * from class where classid=#{classid}") public Clazz findClazzByClassid(@Param("classid")int classid);
一对多:查找一个班级对应的所有学生
1.首先,先给clazz类添加一个List<Student>的属性,因为是多个学生,所以是集合。
ClazzMapper接口:
注解的作用:
@Results,@Result以及其属性与一对一的含义一致。
区别:many=@Many(select = "传递值调用的方法"):注意一对多用的是many
//查询所有的班级对应的学生 @Results(id="dd",value= { @Result(column="classid",property="classid"), //many :一对多 @Result(property = "stulist",column="classid", many=@Many(select = "com.ape.mapper.StudentMapper.findStudentByClassid")) }) @Select("select * from class") public List<Clazz> findAllClazzAndStudent();
StudentMapper接口:
@Select("select * from student where classid = #{classid}") public List<Student> findStudentByClassid(@Param("classid")int classid);
5.动态SQL注解:
首先,我们要知道动态SQL就是动态的拼接条件完成语句的增删改查,在XML中mybatis为我们提供了各种各样的标签,<if>,<where>,<trim>,<set>等等,实现了动态SQL,那么注解呢有所不同.下面我们一起学习
注意:前两种不推荐,重点了解官方的构造器。
方式一:脚本:就是直接通过<script>标签配合字符串,实现
此种方法,繁琐,不推荐,了解即可
//方式一:脚本 @Select("<script>" + "select * from student" + "<where>" + "<if test=\"ssex!=null\"> and ssex=#{ssex}</if>" + "<if test=\"classid!=0\"> and classid=#{classid}</if>" + "</where>" + "</script>") public List<Student> findStudnet(Student s);
方式二:在方法中创建动态sql语句 ---不推荐
注意:此种方法需要建立 内部类,在内部类通过可变字符串实现,并将SQL语句返回
@SelectProvider(type=StudentSql.class,method="getSelectStudentSql") public List<Student> findStudentFunc(Student stu);
内部类代码:
//内部类 class StudentSql{ //手写判断 public String getSelectStudentSql(Student s) { StringBuilder sql = new StringBuilder(); sql.append("select * from student where 1=1 "); if(s.getSsex()!=null) { sql.append("and ssex=#{ssex} "); } if(s.getClassid()!=0) { sql.append("and classid=#{classid}"); } return sql.toString(); } }
方式三:官方推荐 构造器, --推荐
注意:此种方法也是在内部类中实现的。
//方式三:构造器生成动态sql语句,将方式二进行封装 --- 构造器 @SelectProvider(type = StudentSql.class,method="getSelectStudentSqlGZQ") public List<Student> findStudentGZQ(Student s);
构造器代码:
注意:这是官方为我们提供的各种,
1.先定义一个方法。 并返回String
2.return new SQL(){{ // 构造田间}}
注意大小写,内部为我们提供了各种各样的标签。
//内部类 class StudentSql{ //构造器: ------动态sql查询 public String getSelectStudentSqlGZQ(Student s) { return new SQL(){ { //字段名 SELECT("sid"); SELECT("sname,birthday"); SELECT("ssex,classid"); //表 FROM("student"); //条件 if(s.getSsex()!=null) { WHERE("ssex=#{ssex}"); } if(s.getClassid()!=0) { WHERE("classid=#{classid}"); } } }.toString(); } }
此处只演示了查询,增删改查代码一样,大家可以试一试,学习交流。