注解配置SQL映射(一)
Mybatis对于大部分的基于XML的映射器元素提供了对应的基于注解的配置项。然而某些情况下,基于注解配置还不能支持基于XML的一些元素。
映射语句
在Mybatis中提供了多种注解支持不同类型的语句比如@Select,@Insert,@Update,@Delete。
@Insert
@Insert("INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,ADDR_ID, PHONE)
VALUES(#{studId},#{name},#{email},#{address.addrId},#{phone})")
int insertStudent(Student student);
使用了@Insert注解会返回影响的行数。
在Insert中我们如何自动生成注解可以使用Options注解的useGeneratedKeys。
@Insert("INSERT INTO STUDENTS(NAME,EMAIL,ADDR_ID, PHONE)
VALUES(#{name},#{email},#{address.addrId},#{phone})")
@Options(useGeneratedKeys = true, keyProperty = "studId")
int insertStudent(Student student);
这里的主键值会通过MySQL数据库自动生成。并且生成的值将会被设置到student对象的studId属性中。
对于没有自增的可以使用序列
@Insert("INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,ADDR_ID, PHONE)
VALUES(#{studId},#{name},#{email},#{address.addrId},#{phone})")
@SelectKey(statement="SELECT STUD_ID_SEQ.NEXTVAL FROM DUAL",
keyProperty="studId", resultType=int.class, before=true)
int insertStudent(Student student);
@Update
@Update("UPDATE STUDENTS SET NAME=#{name}, EMAIL=#{email},
PHONE=#{phone} WHERE STUD_ID=#{studId}")
int updateStudent(Student student);
@Delete
@Delete("DELETE FROM STUDENTS WHERE STUD_ID=#{studId}")
int deleteStudent(int studId);
@Select
@Select("SELECT STUD_ID AS STUDID, NAME, EMAIL, PHONE FROM
STUDENTS WHERE STUD_ID=#{studId}")
Student findStudentById(Integer studId);
结果映射
@Select("SELECT * FROM STUDENTS")
@Results(
{
@Result(id=true,column = "stud_id",property = "studId"),
@Result(column = "name",property = "default"),
@Result(column = "email",property = "email"),
@Result(column = "addr_id",property = "address.addrId")
}
)
List<Student> findAllStudents();
由于结果集只对当前方法有效不对所有方法有效果需要多次重写,所以可以在Mapper的配置文件中配置,然后用@ResultMap引用。
public interface StudentMapper
{
@Select("SELECT * FROM STUDENTS WHERE STUD_ID=#{studId}")
@ResultMap("com.mybatis3.mappers.StudentMapper.StudentResult")
Student findStudentById(int studId);
@Select("SELECT * FROM STUDENTS")
@ResultMap("com.mybatis3.mappers.StudentMapper.StudentResult")
List<Student> findAllStudents();
}
一对一映射
@Select("SELECT ADDR_ID AS ADDRID, STREET, CITY, STATE, ZIP, COUNTRY
FROM ADDRESSES WHERE ADDR_ID=#{id}")
Address findAddressById(int id);
@Select("SELECT * FROM STUDENTS WHERE STUD_ID=#{studId} ")
@Results(
{
@Result(id = true, column = "stud_id", property = "studId"),
@Result(column = "name", property = "name"),
@Result(column = "email", property = "email"),
@Result(property = "address", column = "addr_id",
one = @One(select = "com.mybatis3.mappers.StudentMapper.
findAddressById"))
})
Student selectStudentWithAddress(int studId);
这里使用了@One的注解的select属性来指定一个使用了完全限定名的方法上,该方法会返回一个Address对象。使用column="addr_id",则STUDENTS表中列addr_id的值将会作为输入参数传递给findAddressById()方法。
这里也会引来N+1问题。所以我们更多的采用的是连接查询:
@Select("select stud_id, name, email, a.addr_id, street, city,
state, zip, country" + " FROM students s left outer join addresses a
on s.addr_id=a.addr_id" + " where stud_id=#{studId} ")
@ResultMap("com.mybatis3.mappers.StudentMapper.
StudentWithAddressResult")
Student selectStudentWithAddress(int id);
一对多映射
@Select("SELECT tutor_id, name as tutor_name, email, addr_id
FROM tutors where tutor_id=#{tutorId}")
@Results(
{
@Result(id = true, column = "tutor_id", property = "tutorId"),
@Result(column = "tutor_name", property = "name"),
@Result(column = "email", property = "email"),
@Result(property = "address", column = "addr_id",
one = @One(select = " com.mybatis3.
mappers.TutorMapper.findAddressById")),
@Result(property = "courses", column = "tutor_id",
many = @Many(select = "com.mybatis3.mappers.TutorMapper.
findCoursesByTutorId"))
})
Tutor findTutorById(int tutorId);
一对多种也会引来N+1问题,所以还是使用连接查询。
@Select("SELECT T.TUTOR_ID, T.NAME AS TUTOR_NAME, EMAIL,
A.ADDR_ID, STREET, CITY, STATE, ZIP, COUNTRY, COURSE_ID, C.NAME,
DESCRIPTION, START_DATE, END_DATE FROM TUTORS T LEFT OUTER
JOIN ADDRESSES A ON T.ADDR_ID=A.ADDR_ID LEFT OUTER JOIN COURSES
C ON T.TUTOR_ID=C.TUTOR_ID WHERE T.TUTOR_ID=#{tutorId}")
@ResultMap("com.mybatis3.mappers.TutorMapper.TutorResult")
Tutor selectTutorById(int tutorId);