MyBatis(三)配置文件,輸入輸出映射,動態SQL

1.在SqlMapConfig.xml文件中加載db.properties

如果不寫db.properties的話,那么也可以直接給value賦值,但是,這樣寫的話,后果就是維護起來變得麻煩,如果下次改了密碼等信息,還需要在xml中尋找對應的value,代碼一多的話,會很容易出錯且效率不高。相反,可以直接尋找相應的properties文件。

db.properties代碼:

db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/student
db.username=root
db.password=root

"="號左邊是鍵,盡量使用XX.XX.XX的形式,這樣更清晰。

還有一個注意的地方:

<font color=#ff0000 size=4>加載的順序</font>

<font color=#ff0000 size=4>1、 先加載properties中property標簽聲明的屬性

2、 再加載properties標簽引入的java配置文件中的屬性

3、 parameterType的值會和properties的屬性值發生沖突。</font>

<properties resource="db.properties">
      <property name="driver" value="com.mysql.jdbc.Driver"/>
</properties>

2.SqlMapConfig中Mapper的加載

  • 第一種方式:使用相對于類路徑的資源,通過resource標簽直接拿到對應的mapper

    <mapper resource="mapper/student.xml" />

  • 第二種方式:注冊指定包下的所有映射文件。通過加載Mapper接口去加載配置文件必須在同目錄下且文件名相同

    <package name="com.yu.mybatis" />

3.全局配置文件

<font color=#ff0000 size=4>SqlMapConfig.xml的配置內容和順序如下(順序不能亂)</font>:

Properties(屬性)

Settings(全局參數設置)

typeAliases(類型別名)

typeHandlers(類型處理器)

objectFactory(對象工廠)

plugins(插件)

environments(環境信息集合)

environment(單個環境信息)

mappers(映射器)


以typeAliases(類型別名)舉例

<typeAliases>
  <typeAlias type="com.yu.domain.Student" alias="s"/>
</typeAliases>

4.輸入映射(parameterType)

1.簡單pojo
<!--更新數據 -->
<update id="updateStudent" parameterType="com.yu.domain.Student">
    update student set
    name=#{name} ,age=#{age} ,hobby=#{hobby} where
    id=#{id}
</update>
2.包裝pojo類型

1)創建包裝類

public class StudentWrapper {
 public Student getStudent() {
    return student;
}

public void setStudent(Student student) {
    this.student = student;
}

private Student student;
 
}

2)映射文件

<!-- 包裝類型 -->
<select id="getStudentListByWrapper" parameterType="com.yu.domain.StudentWrapper"
    resultType="com.yu.domain.Student">
    select name from student where name=#{student.name}
</select>

3)Mapper接口

public interface StudentMapper {
public List<Student> getStudentListByWrapper(StudentWrapper studentWrapper)throws Exception;
}

4)測試

@Test
public void testSelectStudentListByWrapper() throws Exception {
    SqlSession session = sqlSessionFactory.openSession();
    // 拿到代理對象
    StudentMapper mapper = session.getMapper(StudentMapper.class);
    StudentWrapper studentWrapper = new StudentWrapper();
    Student students = new Student();
    students.setName("Ronaldo");

    studentWrapper.setStudent(students);
    List<Student> studentListByWrapper = mapper.getStudentListByWrapper(studentWrapper);
    System.out.println(studentListByWrapper);
    session.close();
}

5.輸出映射(resultType,resultMap)

  • resultType

<font color=#ff0000 size=4>使用resultType進行結果映射時,需要查詢出的列名和映射的對象的屬性名一致,才能映射成功。

如果查詢的列名和對象的屬性名全部不一致,那么映射的對象為空。
如果查詢的列名和對象的屬性名有一個一致,那么映射的對象不為空,但是只有映射正確那一個屬性才有值。

如果查詢的sql的列名有別名,那么這個別名就是和屬性映射的列名。</font>:**

這里就不貼代碼了。自行測試,debug一下。。。

  • resultMap

使用resultMap進行結果映射時,不需要查詢的列名和映射的屬性名必須一致。但是需要聲明一個resultMap,來對列名和屬性名進行映射。

映射文件:

<!-- ResultMap的使用 -->
<select id="getStudentListByResultMap" parameterType="com.yu.domain.StudentWrapper"
    resultMap="myResultMapId">
    select name name_ from student where name=#{student.name}
</select>

resultMap的值引用上面定義resultMap的id屬性

6.動態SQL

在mybatis中,它提供了一些動態sql標簽,可以讓程序員更快的進行mybatis的開發,這些動態sql可以通過sql的可重用性。

常用的動態sql標簽:if標簽、where標簽、sql片段、foreach標簽

If標簽/where標簽

<select id="getStudentByDnynaicSql" parameterType="com.yu.domain.StudentWrapper"
    resultType="com.yu.domain.Student">

    select * from student
    //where默認去掉第一個AND
    <where>
        <if test="student!=null">
        <if test="student.name!=null and student.name!=''">
            name=#{student.name}
        </if>

        <if test="student.age!=null and student.age!=''">
            and age=#{student.age}
        </if>
    </if>
    </where>
</select>

Mapper接口:

public List<Student> getStudentByDnynaicSql(StudentWrapper studentWrapper) throws Exception;

測試代碼:

    public void getStudentByDnynaicSql() throws Exception {
    SqlSession session = sqlSessionFactory.openSession();
    // 拿到代理對象
    StudentMapper mapper = session.getMapper(StudentMapper.class);
    StudentWrapper studentWrapper = new StudentWrapper();
    Student students = new Student();
    //students.setName("Ronaldo");
    students.setAge(20);
    studentWrapper.setStudent(students);
    List<Student> studentListByWrapper = mapper.getStudentByDnynaicSql(studentWrapper);
    System.out.println(studentListByWrapper);
    session.close();
}

此時我將students.setName("Ronaldo");注釋掉。

少了name=?原因是if語句中做了判斷。

SQL片段

Sql片段可以讓代碼有更高的可重用性

Sql片段需要先定義后使用


<sql id="sqlSection">
<if test="student!=null">
<if test="student.name!=null and student.name!=''">
name=#{student.name}
</if>

        <if test="student.age!=null and student.age!=''">
            and age=#{student.age}
        </if>
    </if>
</sql>

 <select id="getStudentByDnynaicSql" parameterType="com.yu.domain.StudentWrapper"
    resultType="com.yu.domain.Student">

    select * from student
    <where>
        <include refid="sqlSection"></include>
    </where>
</select>

使用sql標簽定義sql片段,用include標簽引入sql片段

foreach

1) 修改包裝pojo

public class StudentWrapper {
 public Student getStudent() {
    return student;
}

public void setStudent(Student student) {
    this.student = student;
}

private Student student;
private List<Integer> list;
public List<Integer> getList() {
    return list;
}

public void setList(List<Integer> list) {
    this.list = list;
}
 
}

2)映射文件:

<!-- foreach標簽 -->
<select id="selectStudentByforeach" resultType="com.yu.domain.Student" 
    parameterType="com.yu.domain.StudentWrapper"> 
     select * from student 
     <where>
     <foreach collection="list" item="items" open="And 
    (" close=")" separator="or">
    age=#{items} 
    </foreach>
     </where>
 </select>

Mapper接口:

public List<Student> selectStudentByforeach(StudentWrapper studentWrapper) throws Exception;

測試:

@Test
public void getStudentByDnynaicSql() throws Exception {
    SqlSession session = sqlSessionFactory.openSession();
    // 拿到代理對象
    StudentMapper mapper = session.getMapper(StudentMapper.class);
    StudentWrapper studentWrapper = new StudentWrapper();
    List<Integer> list=new ArrayList<>();
    list.add(10);
    list.add(20);
    studentWrapper.setList(list);
     List<Student> selectStudentByforeach = mapper.selectStudentByforeach(studentWrapper);
    System.out.println(selectStudentByforeach);
    session.close();
}

6.mybatis與hibernate的區別及各自應用場景

Mybatis技術特點:

1、 通過直接編寫SQL語句,可以直接對SQL進行性能的優化;

2、 學習門檻低,學習成本低。只要有SQL基礎,就可以學習mybatis,而且很容易上手;

3、 由于直接編寫SQL語句,所以靈活多變,代碼維護性更好。

4、 不能支持數據庫無關性,即數據庫發生變更,要寫多套代碼進行支持,移植性不好。

Hibernate技術特點:

1、 標準的orm框架,程序員不需要編寫SQL語句。

2、 具有良好的數據庫無關性,即數據庫發生變化的話,代碼無需再次編寫。

3、 學習門檻高,需要對數據關系模型有良好的基礎,而且在設置OR映射的時候,需要考慮好性能和對象模型的權衡。

4、 程序員不能自主的去進行SQL性能優化。

Mybatis應用場景:

需求多變的互聯網項目,例如電商項目。

Hibernate應用場景:

需求明確、業務固定的項目,例如OA項目、ERP項目等。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容