1.使用注解配置SQL映射器
在映射器Mapper接口上使用注解
映射语句
@Insert、@Update、@Delete、@SelectStatements
结果映射
一对一映射、一对多映射
动态SQL
SelectProvider
InsertProvider
UpdateProvider
DeleteProvider
2.在映射器mapper接口上使用注解
MyBatis对于大部分的基础XML的映射器元素(、)提供了基于注解的配置项,然后在某一些情况下,基于注解的配置还不能支持一些基础XML的配置。
Mybatis提供了多种基于注解来支持不同的语句(statemant),如SELETCT、UPDATE、INSERT、DELETE。下面讲解这些注解该如何使用。
2.1@Insert
我们可以使用@insert注解来定义一个Insert映射语句:使用@insert返回SQL语句执行后数据库受影响的行数
@Insert("insert into student values (null,#{name},#{email},#{address},#{phone})")
public int insertStudent(Student s);
自动生成主键
我们可以使用@options注解的useGeneratedKeys和keyProperty属性让数据库产生auto_increament(自增长列的值),然后将生成的主键输入到对象的属性中!
@Insert("insert into student values (null,#{name},#{email},#{address},#{phone})")
@Options(useGeneratedKeys=true,keyProperty="id")
public int insertStudent(Student s);
有一些数据库,例如Oracle,并不支持AUTO_increament列属性,它使用序列来产生主键(SEQUENCE)的值!
我们可以使用注解来为任意SQL语句来指定主键值,作为主键列的值.假设我们有一个名为
STU_ID_SEQ的序列为主键生成自增
@Insert("insert into student values (null,#{name},#{email},#{address},#{phone})")
@SelectKey(statement="SELECT STUD_ID_SEQ.NEXTVAL FROM DUAL",keyProperty="id",resultType=Integer.class,before=true)
public int insertStudent(Student s);
这里使用@selectKey来生成主键值,并存储到了student对象的id属性上,由于设置的是before=true,该语句则将会在INSERT语句执行之前执行!
2.2 @update
我们可以使用@update注解来定义一个update映射语句:
@Update("update student set name=#{name},email=#{email},address=#{address},phone=#{phone} where id=#{id}")
public int updateStudent(Student s);
update语句返回SQL语句执行成功后数据库受影响的行数!
2.3 @delete
我们可以使用@delete注解来定义一个delete映射语句:
@Delete("delete from student where id=#{id}")
public int deleteStudent(int id);
delete语句返回SQL语句执行成功后数据库受影响的行数!
2.4 @select
我们可以使用@select注解来定义一个select映射语句:
简单的select语句
@Select("select * from student where id=#{id}")
public Student findStudentById(int id);
@Select("select * from student")
public List<Student> findStudents();
2.5 结果映射
@Select("select * from student")
@Results({
@Result(id=true,column="id",property="id"),
@Result(column="name",property="name"),
@Result(column="email",property="email"),
@Result(column="address",property="address"),
@Result(column="phone",property="phone")
})
public List<Student> findAllStudents();
3.关联映射
3.1一对一映射
MyBatis提供了@one注解来使用嵌套select语句加载一对一关联查询数据。
3.1.1需求
查询学生的时候关联查询该学生对应的身份证信息
3.1.2 Mapper接口文件
@Select("select * from card where id=#{id}")
public Card findCardById(int id);
@Select("select * from student where id=#{id}")
@Results({
@Result(id=true,column="id",property="id"),
@Result(column="name",property="name"),
@Result(column="email",property="email"),
@Result(column="address",property="address"),
@Result(column="phone",property="phone"),
@Result(property="card",column="card_id",one=@One(select="com.mybatis.mapper.StudentMapper.findCardById"))
})
public Student selectStudentWithCard(int id);
也可以在StudentMapper.xml文件中进行配置,然后使用@ResultMap注解引用xml中的配置
<resultMap type="Student" id="stuMap">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="email" column="email" />
<result property="phone" column="phone" />
<result property="address" column="address" />
<association property="card" resultMap="CardResultMap"/>
</resultMap>
<resultMap type="Card" id="CardResultMap">
<id property="id" column="card_id"/>
<result property="number" column="number"/>
<result property="birthday" column="birthday"/>
<result property="mingzu" column="mingzu"/>
</resultMap>
@Select("select * from student,card WHERE student.card_id=card.id and student.id=#{id}")
@ResultMap("com.mybatis.mapper.StudentMapper.stuMap")
public Student selectStudentWithCard1(int id);
3.2 一对多映射
3.2.1 需求
查询教师关联查询该讲师的学生信息
3.2.2 Mapper接口文件
@Select("select * from student where teacher_id=#{id}")
public List<Student> findStudentsByTeacherId(int id);
@Select("select * from teacher where t_id=#{id}")
@Results({
@Result(id=true,column="t_id",property="id"),
@Result(column="t_name",property="name"),
@Result(column="t_age",property="age"),
@Result(column="t_sex",property="sex"),
@Result(property="students",column="t_id",many=@Many(select="com.mybatis.mapper.TeacherMapper.findStudentsByTeacherId"))
})
public Teacher findTeacherById(int id);
也可以在TeacherMapper.xml文件中进行配置,然后使用@ResultMap注解引用xml中的配置
<resultMap type="Teacher" id="teacherMap">
<id property="id" column="t_id" />
<result property="name" column="t_name" />
<result property="age" column="t_age" />
<result property="sex" column="t_sex" />
<collection property="students" resultMap="StudentMap"/>
</resultMap>
<resultMap type="Student" id="StudentMap">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="email" column="email" />
<result property="phone" column="phone" />
<result property="address" column="address" />
</resultMap>
@Select("select * from teacher,student where teacher.t_id=student.teacher_id and teacher.t_id=#{id}")
@ResultMap(value="com.mybatis.mapper.TeacherMapper.teacherMap")
public Teacher findTeacherById1(int id);
3.3 多对多映射
3.3.1 需求
查询课程的时候关联查询该课程下面所有的学生
3.3.2 Mapper接口文件
@Select("select * from student_course,student where student_course.student_id=student.id and student_course.course_id=#{id}")
public List<Student> getStudentsByCourseId();
@Select("select * from course where c_id=#{id}")
@Results({
@Result(id=true,column="c_id",property="id"),
@Result(column="c_name",property="name"),
@Result(column="c_time",property="time"),
@Result(property="students",column="c_id",many=@Many(select="com.mybatis.mapper.CourseMapper.getStudentsByCourseId"))
})
public Course getCourseById(Integer id);
也可以在CourseMapper.xml文件中进行配置,然后使用@ResultMap注解引用xml中的配置
<resultMap type="Course" id="courseMap">
<id column="c_id" property="id" />
<result column="c_name" property="name" />
<result column="c_time" property="time" />
<collection property="students" resultMap="StudentMap" />
</resultMap>
<resultMap type="Student" id="StudentMap">
<id property="id" column="student_id" />
<result property="name" column="name" />
<result property="email" column="email" />
<result property="phone" column="phone" />
<result property="address" column="address" />
</resultMap>
@Select("select * from course,student_course,student where student_course.student_id=student.id and student_course.course_id=course.c_id and course.c_id=#{id}")
@ResultMap(value="com.mybatis.mapper.CourseMapper.courseMap")
public Course getCourseById1(Integer id);
4.动态SQL
4.1@SelectProvider
Mybatis使用@SelectProvider注解来创建一个简单SELECT查询的映射语句
创建一个TeacherDynaSqlProvider类,定义一个生成SQL的方法findTeacherByIdSql
public class TeacherDynaSqlProvider {
public String findTeacherByIdSql(int t_id){
return "select * from teacher where t_id=#{t_id}";
}
}
在mapper文件中国定义查询语句
@SelectProvider(type=TeacherDynaSqlProvider.class,method="findTeacherByIdSql")
@Results({
@Result(id=true,column="t_id",property="id"),
@Result(column="t_name",property="name"),
@Result(column="t_age",property="age"),
@Result(column="t_sex",property="sex")
})
public Teacher findTeacherById2(int t_id);
这里我们使用了@SelectProvider来指定一个类,并调用其中的方法,用来提供SQL语句
但是使用字符串拼接SQL是非常困难的,并且很容易出错!所以针对这种情况,Mybatis提供了一个SQL工具类,来构造SQL语句!
public class TeacherDynaSqlProvider {
public String findTeacherByIdSql() {
SQL sql = new SQL();
sql.SELECT("*");
sql.FROM("teacher");
sql.WHERE("t_id=#{t_id}");
return sql.toString();
}
}
使用Map传入参数
@SelectProvider(type=TeacherDynaSqlProvider.class,method="findTeachersSql")
@Results({
@Result(id=true,column="t_id",property="id"),
@Result(column="t_name",property="name"),
@Result(column="t_age",property="age"),
@Result(column="t_sex",property="sex")
})
public List<Teacher> findTeachers(Map<String, Object> map);
public String findTeachersSql(Map<String, Object> map){
String name =(String) map.get("name");
String sex =(String) map.get("sex");
SQL sql = new SQL();
sql.SELECT("*");
sql.FROM(TABLE_NAME);
if(name!=null){
sql.WHERE("t_name like #{name}");
}
if(sex!=null){
sql.WHERE("t_sex=#{sex}");
}
return sql.toString();
}
4.2 @InsertProvider
我们可以使用@InsertProvider来构建新增SQL语句
public String insertSql(Teacher t){
SQL sql = new SQL();
sql.INSERT_INTO(TABLE_NAME);
if(t.getName()!=null){
sql.VALUES("t_name", "#{name}");
}
if(t.getAge()!=null){
sql.VALUES("t_age", "#{age}");
}
if(t.getSex()!=null){
sql.VALUES("t_sex", "#{sex}");
}
return sql.toString();
}
Mapper接口
@InsertProvider(type=TeacherDynaSqlProvider.class,method="insertSql")
public int insertTeacher(Teacher t);
4.3 @UpdateProvider
public String updateSql(Teacher t){
SQL sql = new SQL();
sql.UPDATE(TABLE_NAME);
if(t.getName()!=null){
sql.SET("t_name=#{name}");
}
if(t.getAge()!=null){
sql.SET("t_age=#{age}");
}
if(t.getSex()!=null){
sql.SET("t_sex=#{sex}");
}
sql.WHERE("t_id=#{id}");
return sql.toString();
}
Mapper接口
@UpdateProvider(type=TeacherDynaSqlProvider.class,method="updateSql")
public int updateTeacher(Teacher t);
4.4 @DeleteProvider
public String deleteSql(){
SQL sql = new SQL();
sql.DELETE_FROM(TABLE_NAME);
sql.WHERE("t_id=#{id}");
return sql.toString();
}
Mapper接口
@DeleteProvider(type=TeacherDynaSqlProvider.class,method="deleteSql")
public int deleteById(int id);
5.总结
MyBatis注解的配置方式,其实在工作用应用不是很广泛。后期MyBati可以实现逆向工程,Mapper中自动生成,提高开发效率!