【Java EE 學習 79 上】【mybatis 基本使用方法】

1、簡介

  mybatis相似於hibernate,都是簡化對數據庫操做的框架,可是和hibernate不一樣的是,mybatis更加靈活,總體來講框架更小,這體如今它須要咱們手寫SQL語句,而hibernate則將對數據庫的操做對程序員徹底透明瞭,程序員只須要按照面向對象的思想編寫代碼便可,想要看sql語句,就必須在配置文件中聲明java

<property name="show_sql">true</property>

  hibernate對數據庫的操做封裝的很是完全,所以靈活性不高,mybatis可以實現相似於hibernate的功能,可是須要本身寫sql語句,這並不表示使用mybatis更加繁瑣,相反的,我的認爲mybatis框架很小,配置起來也很是簡單,mybatis真正優秀的地方在哪裏,爲何它會愈來愈火?mysql

  mybatis官方給出的mybatics 3.1.1文檔中有這麼一段話說出了爲什麼mybatis這麼火的緣由:git

  

  其中文意思大概就是:Mybatis提供的完整功能集可以經過使用基於「映射語言」的XML來實現,這正是Mybatis流行這麼多年的緣由。程序員

  以上內容是mybatis中的「映射文件」相關的內容,從這段話中不難看出。Mybatis的核心是「映射文件」,經過該映射文件可以實現Mybatis的全部功能。其形式如上所示。github

2、Mybatis的基本使用方法

   練習項目源代碼:https://github.com/kdyzm/day79_1_mybatisdemospring

  1.總的配置文件

    和hibernate有些類似,Mybatis中也有兩種配置文件,一種配置文件是「總的配置文件」,相似於hibernate中的hibernate.cfg.xml,名字隨意,可是最好起一個比較規範的名字,可以見名知意,我習慣使用mybatis-config.xml命名。在mybatis 3.1.1文檔中有詳細的使用說明,其提供了最簡單的使用形式:sql

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration
 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4 "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <configuration>
 6     <environments default="development">
 7         <environment id="development">
 8             <transactionManager type="JDBC" />
 9             <dataSource type="POOLED">
10                 <property name="driver" value="${driver}" />
11                 <property name="url" value="${url}" />
12                 <property name="username" value="${username}" />
13                 <property name="password" value="${password}" />
14             </dataSource>
15         </environment>
16     </environments>
17     <mappers>
18         <mapper resource="org/mybatis/example/BlogMapper.xml" />
19     </mappers>
20 </configuration>

  配置文件的位置任意,可是推薦放到classpath路徑下,文檔中說明該文件能夠放到任意位置,在windows下可使用file:///協議直接訪問,可是我沒試過。數據庫

  以上內容很是簡單,將對應的變量替換掉,接下來就是配置所謂的「映射文件」BlogMapper.xml。apache

  2.映射文件

  映射文件的寫法和形式以下:windows

1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE mapper
3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5 <mapper namespace="org.mybatis.example.BlogMapper">
6     <select id="selectBlog" parameterType="int" resultType="Blog">
7         select * from Blog where id = #{id}
8     </select>
9 </mapper>

  一樣這也是文檔中給出的例子,固然,這是最簡單的例子,可是全部的配置文件中都須要對其進行配置,能夠說是最核心並且是最基礎的配置方式了。

  說明:

    namespace屬性:命名空間,該命名空間的值任意,可是必須保證在整個項目中惟一,對應一個實體如Student,必定要有一個惟一的命名空間,因此這裏直接取該實體的類名便可。

    mapper標籤中的內容是全部對數據庫操做的sql語句。這裏的select標籤表示裏面的呃sql語句是查詢語句,若是是update標籤,表示是更新語句......

    id屬性:該屬性表示惟一,這天然沒必要說,可是該屬性只是在當前Mapper標籤中惟一便可。在引用該sql語句的時候,直接使用namespace+.+id來表示。

    parameterType:參數類型,這裏表示的是#{id}中的id對應的參數類型。

    resultType:結果集類型,若是是Student,則不該當直接寫上Student,而應當寫上com.kdyzm.domain.Student,這裏可以直接寫上Blog是由於該Blog是已經聲明瞭的「引用類型」。引用的寫法以後再說。

3、使用Mybatis的CRUD操做。

  和hibernat相同,mybatis的CRUD操做都依賴於一個Session對象,可是該對象在mybatis中有了新名字,名爲SqlSession,並且建立它使用的工廠名字也再也不是SessionFactory,而是SqlSessionFactory,示例代碼以下:

  獲取SqlSessionFactory對象的方式:

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

  獲取SqlSession對象的方式:

SqlSession session = sqlSessionFactory.openSession();

  以後就是使用Session對象的使用問題了。

  1.準備工做

  下載相關jar包並加入classpath,過程略,下載地址:https://github.com/mybatis/mybatis-3/releases

  (1)log4j配置文件

  爲了方便查看控制檯輸出使用的log4j的配置文件:

 1 log4j.rootLogger=DEBUG, Console
 2 #Console
 3 log4j.appender.Console=org.apache.log4j.ConsoleAppender
 4 log4j.appender.Console.layout=org.apache.log4j.PatternLayout
 5 log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
 6 log4j.logger.java.sql.ResultSet=INFO
 7 log4j.logger.org.apache=INFO
 8 log4j.logger.java.sql.Connection=DEBUG
 9 log4j.logger.java.sql.Statement=DEBUG
10 log4j.logger.java.sql.PreparedStatement=DEBUG
log4j.properties

  (2)總的配置文件

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration
 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4 "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <configuration>
 6     <environments default="development">
 7         <environment id="development">
 8             <transactionManager type="JDBC" />
 9             <dataSource type="POOLED">
10                 <property name="driver" value="com.mysql.jdbc.Driver" />
11                 <property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
12                 <property name="username" value="root" />
13                 <property name="password" value="5a6f38" />
14             </dataSource>
15         </environment>
16     </environments>
17     <mappers>
18         <mapper resource="com/kdyzm/domain/Student.xml"/>
19         <mapper resource="com/kdyzm/domain/Person.xml"/>
20         <mapper resource="com/kdyzm/domain/Clazz.xml"/>
21     </mappers>
22 </configuration>
mybatis-config.xml

  總的配置文件中並無什麼實質性的東西,最核心的配置都在「映射文件」中。

  (3)新建3個類:

 1 package com.kdyzm.domain;
 2 
 3 public class Student {
 4     private Integer id;
 5     private String name;
 6     private String password;
 7     private Integer age;
 8     private Clazz clazz;
 9     /*************************** 分割線 ******************************************/
10     public Integer getId() {
11         return id;
12     }
13 
14     public void setId(Integer id) {
15         this.id = id;
16     }
17 
18     public String getName() {
19         return name;
20     }
21 
22     public void setName(String name) {
23         this.name = name;
24     }
25 
26     public String getPassword() {
27         return password;
28     }
29 
30     public void setPassword(String password) {
31         this.password = password;
32     }
33 
34     public Integer getAge() {
35         return age;
36     }
37 
38     public void setAge(Integer age) {
39         this.age = age;
40     }
41     
42     public Clazz getClazz() {
43         return clazz;
44     }
45     
46     public void setClazz(Clazz clazz) {
47         this.clazz = clazz;
48     }
49     
50     @Override
51     public String toString() {
52         return "Student [id=" + id + ", name=" + name + ", password=" + password + ", age=" + age + "]";
53     }
54 }
com.kdyzm.domain.Student
 1 package com.kdyzm.domain;
 2 
 3 public class Person {
 4     private int personId;
 5     private String personName;
 6     private String personAge;
 7 /****************************華麗的分割線***************************************/
 8     public int getPersonId() {
 9         return personId;
10     }
11     public void setPersonId(int personId) {
12         this.personId = personId;
13     }
14     public String getPersonAge() {
15         return personAge;
16     }
17     public void setPersonAge(String personAge) {
18         this.personAge = personAge;
19     }
20     public String getPersonName() {
21         return personName;
22     }
23     public void setPersonName(String personName) {
24         this.personName = personName;
25     }
26     @Override
27     public String toString() {
28         return "Person [personId=" + personId + ", personName=" + personName + ", personAge=" + personAge + "]";
29     }
30 }
com.kdyzm.domain.Person
 1 package com.kdyzm.domain;
 2 
 3 import java.util.List;
 4 
 5 public class Clazz {
 6     private int id;
 7     private String name;
 8     private String desc;
 9     private List<Student> students;
10 /*************************華麗的分割線************************/
11     public int getId() {
12         return id;
13     }
14     public void setId(int id) {
15         this.id = id;
16     }
17     public String getName() {
18         return name;
19     }
20     public void setName(String name) {
21         this.name = name;
22     }
23     public String getDesc() {
24         return desc;
25     }
26     public void setDesc(String desc) {
27         this.desc = desc;
28     }
29     public List<Student> getStudents() {
30         return students;
31     }
32     public void setStudents(List<Student> students) {
33         this.students = students;
34     }
35     @Override
36     public String toString() {
37         return "Clazz [id=" + id + ", name=" + name + ", desc=" + desc + "]";
38     }    
39 }
com.kdyzm.domain.Clazz

  用的最多的兩個類是Student和Clazz,Person類基本上沒用上。

  2.查詢

    com.kdyzm.domain.Student.xml配置文件中的mapper標籤:

<mapper namespace="com.kdyzm.domain.Student"></mapper>

  (1)查詢一個Student對象

<select id="selectUserById" parameterType="int" resultMap="com.kdyzm.domain.Student">
     select s.* ,c.* from student s,clazz c where s.clazz=c.clazzid and s.studentid=#{id};
</select>

    java代碼:

Student student=session.selectOne("com.kdyzm.domain.Student.selectUserById", "1");

  (2)查詢Student的集合

<select id="selectAllStudent" resultType="com.kdyzm.domain.Student">
    select * from Student
</select>

  java代碼:

Collection<Student> students=sqlSession.selectList("com.kdyzm.domain.Student.selectAllStudent");

  3.插入

<insert id="insertIntoStudent" parameterType="com.kdyzm.domain.Student">
        insert into
        student(studentid,name,password,age) values(#{id},#{name},#{password},#{age})
    </insert>

  java代碼:

1 String statement="com.kdyzm.domain.Student.insertIntoStudent";
2 Student student=new Student();
3 student.setId(7);
4 student.setName("張三");
5 student.setAge(13);
6 student.setPassword("xiaozhang");
7 int result=session.insert(statement, student);
8 session.commit();

  這裏必定不要忘了提交的動做:commit();

  4.更新

<update id="updateStudentByStudentObject" parameterType="com.kdyzm.domain.Student">
    update
    student set name=#{name},password=#{password},age=#{age} where
    studentid=#{id}
</update>

  5.刪除

<delete id="deleteUserById" parameterType="string">
    delete from student
    where studentid = #{id}
</delete>

4、注意事項

  1.parameterType屬性和resultType屬性的類型問題

    (1)常用parameterType類型爲string或者int類型做爲id對一個對象進行操做,常常傳入一個對象的類型如com.kdyzm.domain.Student對一個對象進行修改操做,可使用HashMap類型來替換對象類型,這時候類型值就須要寫上hashMap。  

    (2)返回值是一個對象仍是一個對象的集合,返回值類型都是同一種,若是是普通對象類型,那麼以Student爲例就是com.kdyzm.domain.Student,若是是HashMap類型,那麼就是hashMap。

  2.parameterType的類型問題

    若是parameterType類型是基本數據類型或者String類型,那麼在sql中的#{id}中的id名字能夠任意寫,只是起着佔位符的做用,可是若是是對象類型的話,則名字就須要和對象中的屬性名徹底相同才行,由於須要調用對象的get方法獲取字段的值。

5、解決數據庫中表的字段和對象中的屬性字段名字不一致的狀況

  解決方法有兩種:

  1.第一種方式是你們首先可以想到的最通用的方式,那就是起別名,如

select id as studentId,name as studentName from student

  可是使用這種方式有一個很是明顯的缺點,那就是針對每一次查詢都必須這麼寫,顯得很是亂並且書寫起來很是的不方便,還容易出錯,致使的直接後果就是效率低下。

  使用第二種方式可以解決這種麻煩。

  2.第二種解決方式和在hibernate中的配置方式很類似,都是映射表中的字段到對象中的屬性字段的方法。

<!-- 使用ResultMap標籤解決數據庫中表的字段和類中的屬性字段不一致的狀況 -->
<resultMap type="com.kdyzm.domain.Person" id="personMap">
    <id column="id" property="personId"/>
    <result column="name" property="personName"/>
    <result column="age" property="personAge"/>
</resultMap>

  其中column中填寫數據庫表中的列名,property中填寫對應對象中的字段名。

6、多對一關係查詢和一對多關係查詢

  在hibernate中咱們常用關聯關係查詢,好比查到了Student對象以後直接就可以獲取Clazz對象,獲取了Clazz對象以後直接就可以獲得List<Student>對象,一樣,在mybatis中也能歐作到這一點,這裏先不考慮懶加載的事情。

  這裏使用Student和Clazz爲例說明

  1.一對多關係

     Clazz和Student之間是一對多的關係,如今的需求就是根據Clazz對象獲取全部的Student對象。

    能夠利用以前提到的resultMap標籤實現這一點,首先須要在Clazz類中有List<Student>students成員變量,同時提供對應的set/get方法;而後進行映射文件中的XML文件的配置:

 1 <resultMap type="com.kdyzm.domain.Clazz" id="clazzMap">
 2     <id property="id" column="clazzid"></id>
 3     <result property="name" column="name" />
 4     <result column="describtion" property="desc" />
 5     <collection property="students" ofType="com.kdyzm.domain.Student">
 6         <id column="studentid" property="id"></id>
 7         <result column="name" property="name" />
 8         <result column="password" property="password" />
 9         <result column="age" property="age" />
10     </collection>
11 </resultMap>

    和以前不太相同的是添加了黃色背景部分的內容。

    property屬性對應着類中的字段名稱,ofType屬性是集合中的元素類型。collection標籤的子標籤是ofType類型中的全部成員變量,固然雖然Student類中有Clazz類型的成員變量,可是這裏不要寫上,除此以外全部的成員變量都要寫上。

  sql查詢的方式也要修改,這裏必須是兩表聯合查詢才行,同時將resultType改爲resultMap:

1 <select id="selectClazzById" resultMap="clazzMap" parameterType="int">
2     select s.*,c.* from student s,clazz c where c.clazzid =#{id} and s.clazz=c.clazzid
3 </select>

  java代碼:

1 String statement = "com.kdyzm.domain.Clazz.selectClazzById";
2 Clazz clazz = session.selectOne(statement, "1");
3 List<Student> students = clazz.getStudents();
4 for (Student student : students) {
5     System.out.println(student);
6 }

  2.多對一關係的實現

  Student對象和Clazz對象之間是多對一的關係,如今的需求就是須要根據Student對象獲取其對應的Clazz對象。

  這裏仍是須要藉助於resultMap標籤:

 1 <resultMap type="com.kdyzm.domain.Student" id="studentMap">
 2     <id column="studentid" property="id"></id>
 3     <result column="name" property="name"/>
 4     <result column="password" property="password"/>
 5     <result column="age" property="age"/>
 6     <association property="clazz" javaType="com.kdyzm.domain.Clazz">
 7         <id property="id" column="clazzid"></id>
 8         <result property="name" column="name"/>
 9         <result column="describtion" property="desc" />
10     </association>
11 </resultMap>

  固然了,最關鍵的仍是以上黃色背景部分的內容,這裏使用association標籤完成任務。

  property屬性填寫的是對象中的相應字段,javaType對應的是其java類型。而後association標籤內填寫該對象中的全部屬性和表中字段的對應關係,注意,全部的必定都要填寫完整,不然沒有填寫完整的部分對應的字段就會是NULL類型。

  固然,查詢的sql語句也必須改變,改爲兩張表的聯合查詢:

<!-- 根據UserId查詢User對象的查詢方法 -->
<select id="selectUserById" parameterType="int" resultMap="studentMap">
     select s.* ,c.* from student s,clazz c where s.clazz=c.clazzid and s.studentid=#{id};
</select>

  java代碼以下:

String statement = "com.kdyzm.domain.Student.selectUserById";
Student student = session.selectOne(statement, "1");
System.out.println(student.getClazz());

7、mybatics的基礎部份內容就是這麼多,接下來是和spring的整合過程。

相關文章
相關標籤/搜索