目前MyBatis支持註解配置,用註解方式來替代映射文件,可是註解配置仍是有點不完善,在開發中使用比較少,大部分的企業仍是在用映射文件來進行配置。不完善的地方體如今於當數據表中的字段名與實體對象的屬性名不一致時,須要配置ResultMap,可是註解的配置只能是在方法前,也就是當前方法能使用這個配置,其餘的方法是不能應用此註解配置的ResultMap。css
註解配置的方式是直接在數據訪問接口的方法前加上相應的註解java
@select(「select * from student 」)sql
public List<Student> find();apache
在MyBatis的主配置文件的mappers節點中註冊全部的數據持久化接口類app
案例:spa
數據持久化接口xml
public interface SubjectDao {對象 @Select("select * from subject")接口 @Results({ci @Result(id=true,column="subjectNo",property="id"), @Result(column="subjectName",property="subjectName"), @Result(column="classHour",property="hour") }) public List<Subject> find(); } |
MyBatis主配置文件的mappers節點配置
<!-- 若是有映射時,對映射文件進行配置 --> <mappers> <!-- 加載單個映射文件,容許映射文件與持久接口類不在同一目錄下。 --> <mapper resource="com/icss/mapping/AdminDao.xml"/> <mapper resource="com/icss/mapping/GradeDao.xml"/> <mapper resource="com/icss/mapping/StudentDao.xml"/>
<!-- 註解配置時,須要在主配置文件中註冊數據持久化接口類 --> <mapper class="com.icss.dao.SubjectDao"/> <!-- 加載這個包中的全部映射文件,要求持久化接口與映射文件必須在同一個目錄中 --> <!-- <package name="com.icss.dao"/> --> </mappers> |
當表中的數據行有一對多或多對一的映射關係時的處理方式
一對多:
//一對多 : many @Select("select * from grade") @Results( { @Result(id=true, column="gradeId",property="gradeId"), @Result(column="gradeName", property="gradeName"), @Result(column="gradeId",property="subjects", many=@Many(select = "com.etc.dao.SubjectDao.findSubjectByGradeId")) } ) public List<Grade> find(); |
多對一:
@Select("select * from subject") @Results({ @Result(id=true,column="subjectNo",property="id"), @Result(column="subjectName",property="subjectName"), @Result(column="classHour",property="hour"), //多對一的狀況操做,根據年級編號調用年級的數據持久化接口的方法,返回一個年級對象存儲在grade這個屬性中。 @Result(column="gradeId",property="grade",one=@One(select="com.icss.dao.GradeDao.getGradeById")) }) public List<Subject> find(); |
數據持久化層代碼:
package com.icss.dao; import java.util.List; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; 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 org.apache.ibatis.annotations.Update; import com.icss.entity.Subject; public interface SubjectDao { @Select("select * from subject") @Results({ @Result(id=true,column="subjectNo",property="id"), @Result(column="subjectName",property="subjectName"), @Result(column="classHour",property="hour"), //多對一的狀況操做,根據年級編號調用年級的數據持久化接口的方法,返回一個年級對象存儲在grade這個屬性中。 @Result(column="gradeId",property="grade",one=@One(select="com.icss.dao.GradeDao.getGradeById")) }) public List<Subject> find(); //根據年級查詢課程 @Select("select * from subject where gradeId=#{id}") @Results({ @Result(id=true,column="subjectNo",property="id"), @Result(column="subjectName",property="subjectName"), @Result(column="classHour",property="hour"), //多對一的狀況操做,根據年級編號調用年級的數據持久化接口的方法,返回一個年級對象存儲在grade這個屬性中。 @Result(column="gradeId",property="grade",one=@One(select="com.icss.dao.GradeDao.getGradeById")) }) public List<Subject> findByGID(int id);
//新增 @Insert("insert into subject(null,#{subjectName},#{hour},#{grade.gradeId})") public int add(Subject subject);
//刪除 @Delete("delete from subject where subjectNo=#{id}") public int delete(int id);
//修改 @Update("update subejct set subjectName=#{subjectName},classHour=#{hour}," + " gradeId=#{grade.gradeId} where subjectNo=#{id}") public int update(Subject subject); } |
在團隊開發中,建議統一用其中的一種處理方式,用註解就所有用註解,用映射文件就統一用映射文件。
錯誤的處理方法:
<!-- 字段與屬性名不一致,不能用resultType屬性 --> <select id="getStudents" resultMap="studentMap" parameterType="map"> select * from student <if test="name != null"> where name like '%'+#{name}+'%' </if> </select> |
正確的方式是在參數傳入以前就加了這些通配符。
sqlSession = SqlSessionFactoryUtil.getsqlSession(); StudentDao dao= sqlSession.getMapper(StudentDao.class);
//參數傳入到映射文件前就加了模糊查詢的通配符 Map<String, String> map = new HashMap<>(); map.put("name", "%張%"); //調用方法,執行查詢 list=dao.getStudents(map);
映入文件以下: <!-- 字段與屬性名不一致,不能用resultType屬性 --> <select id="getStudents" resultMap="studentMap" parameterType="map"> select * from student <if test="name != null"> where name like #{name} </if> </select> |
MyBatis 的一個強大的特性之一一般是它的動態 SQL 能力,也是MyBatis最有特點的地方,就是它的動態SQL,解決了咱們多條件時SQL指令的拼接問題。查詢學生信息:條件可能(姓名,年齡,年級,性別,地址)
一般使用動態 SQL 不多是獨立的一部分,MyBatis 固然使用一種強大的動態 SQL 語 言來改進這種情形,這種語言能夠被用在任意映射的 SQL 語句中。 動態SQL很是簡單,與JSTL的使用很是相似。
if:當條件成立時,則把內部的SQL拼接到外部的SQL指令中。
<!-- 字段與屬性名不一致,不能用resultType屬性 --> <select id="getStudents" resultMap="studentMap" parameterType="map"> select * from student <if test="name != null"> where name like #{name} </if> </select> |
這是一個多重if-else結構,若是隻有一個when和otherwise,則能夠認爲是if-else結構
<!-- 字段與屬性名不一致,不能用resultType屬性 --> <select id="getStudents" resultMap="studentMap" parameterType="map"> select * from student <choose> <when test="name != null"> where name like #{name} </when> <otherwise> where age > #{age} </otherwise> </choose> </select> |
當條件比較多的時候,要進行條件拼接,where的做用是進行條件拼接,自動加上where 關鍵字,並且會把多餘的and 或 or 這些鏈接關鍵字去掉。
<!-- 字段與屬性名不一致,不能用resultType屬性 --> <select id="getStudents" resultMap="studentMap" parameterType="map"> select * from student <where> <if test="name != null"> and name like #{name} </if> <if test="age != null"> and age > #{age} </if> </where> </select> 拼接後的SQL: select * from student where and name like '%張%' and age > 22 標紅的 and 會自動去掉. |
set: 用於修改的SQL指令
在修改的SQL指令中自動加上set關鍵字,同時把多餘的逗號(,)去掉。很是適合部分值
<update id="update" parameterType="map"> update student <set> <if test="name != null"> name=#{name}, </if> <if test="age != null"> age=#{age}, </if> <if test="sex != null"> sex=#{sex}, </if> <if test="phone != null"> phone=#{phone} </if> </set> where studentNo=1002 </update> 拼接後的SQL: update student set name='肖月月',age=20,sex='女' where studentNo=1002 |
這個動態 SQL 通用的必要操做是迭代一個集合, 一般是構建在 IN 條件中.
<select id="getStudents1" resultMap="studentMap" parameterType="list"> select * from student where address in <foreach item="s" collection="list" open="(" close=")" separator=","> #{s} </foreach> </select> |
業務層處理:
sqlSession = SqlSessionFactoryUtil.getsqlSession(); StudentDao dao= sqlSession.getMapper(StudentDao.class);
List<String> arr = new ArrayList<String>(); arr.add("廣州市"); arr.add("深圳市"); //調用方法,執行查詢 list=dao.getStudents1(arr); |