JavaWeb框架梳理(三)——Mybatis基礎


來源於how2j
github項目入口

Mybatis入門

基本概念

  • MyBatis 是支持定製化 SQL、存儲過程以及高級映射的優秀的持久層框架。
  • MyBatis 避免了幾乎所有的 JDBC 代碼和手動設置參數以及獲取結果集。
  • MyBatis 可以對配置和原生Map使用簡單的 XML 或註解,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄。

簡單Demo

  • 準備實體Pojo類:

    • 代碼:
    package com.how2java.pojo;
     
    public class Category {
        private int id;
        private String name;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
         
    }
    
  • 配置文件mybatis-config.xml

    • 在src目錄下創建mybatis的主配置文件mybatis-config.xml
    • 其作用主要是提供連接數據庫用的驅動,數據庫名稱,編碼方式,賬號密碼
    • 配置別名,及自動掃描om.how2java.pojo下的類型,使得在後續配置文件Category.xml中使用resultType的時候,可以直接使用Category,而不必寫全com.how2java.pojo.Category
      <typeAliases> <package name="com.how2java.pojo"/></typeAliases>
    • 映射Category.xml:
      <mappers> <mapper resource="com/how2java/pojo/Category.xml"/</mappers>
    • 代碼:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
      <package name="com.how2java.pojo"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/how2java?characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="admin"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/how2java/pojo/Category.xml"/>
    </mappers>
</configuration>
  • 配置Category.xml

    • 在包com.how2java.pojo下,新建文件Category.xml namespace="com.how2java.pojo"
    • 表示命名空間是com.how2java.pojo,在後續調用sql語句的時候,會用到它裏面定義了一條sql語句select * from category_
    • 這條sql語句用id: listCategory 進行標示以供後續代碼調用。resultType=“Category” 表示返回的數據和Category關聯起來,這裏本應該使用的是 com.how2java.pojo.Category, 但是因爲上一步配置了別名,所以直接使用Category就行了
    • 代碼:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     
        <mapper namespace="com.how2java.pojo">
            <select id="listCategory" resultType="Category">
                select * from   category_     
            </select>
        </mapper>
    
  • 測試類TestMybatis

    • 代碼:
package com.how2java;
 
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 
import com.how2java.pojo.Category;
 
public class TestMybatis {
 
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session=sqlSessionFactory.openSession();
         
        List<Category> cs=session.selectList("listCategory");
        for (Category c : cs) {
            System.out.println(c.getName());
        }
         
    }
}
  • 解釋:
    • 運行並觀察到如圖所示的結果。
      根據配置文件mybatis-config.xml得到sqlSessionFactory 。
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 
  • 然後再根據sqlSessionFactory 得到session;SqlSession session=sqlSessionFactory.openSession();
  • 最後通過session的selectList方法,調用sql語句listCategory。listCategory這個就是在配置文件Category.xml中那條sql語句設置的id。
    執行完畢之後,得到一個Category集合,遍歷即可看到數據。
List<Category> cs = session.selectList("listCategory");
for (Category c : cs) {
   System.out.println(c.getName());
}
  • 效果
    在這裏插入圖片描述

基本原理

在這裏插入圖片描述

  1. 應用程序找Mybatis要數據
  2. mybatis從數據庫中找來數據
    2.1 通過mybatis-config.xml 定位哪個數據庫
    2.2 通過Category.xml執行對應的select語句
    2.3 基於Category.xml把返回的數據庫記錄封裝在Category對象中
    2.4 把多個Category對象裝在一個Category集合中
  3. 返回一個Category集合

Mybatis CRUD

配置Category.xml

  • 首先一次性修改配置文件Category.xml,提供CRUD對應的sql語句。
  • 代碼:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
    <mapper namespace="com.how2java.pojo">
        <insert id="addCategory" parameterType="Category" >
            insert into category_ ( name ) values (#{name})   
        </insert>
         
        <delete id="deleteCategory" parameterType="Category" >
            delete from category_ where id= #{id}  
        </delete>
         
        <select id="getCategory" parameterType="_int" resultType="Category">
            select * from   category_  where id= #{id}   
        </select>
 
        <update id="updateCategory" parameterType="Category" >
            update category_ set name=#{name} where id=#{id}   
        </update>
        <select id="listCategory" resultType="Category">
            select * from   category_     
        </select>    
    </mapper>

  • 代碼:
package com.how2java;
 
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 
import com.how2java.pojo.Category;
 
public class TestMybatis {
 
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
 
        Category c = new Category();
        c.setName("新增加的Category");
        session.insert("addCategory",c);
         
        listAll(session);
         
        session.commit();
        session.close();
 
    }
 
    private static void listAll(SqlSession session) {
        List<Category> cs = session.selectList("listCategory");
        for (Category c : cs) {
            System.out.println(c.getName());
        }
    }
}
  • 效果:
  • 在這裏插入圖片描述
  • 通過session.insert調用addCategory對應的SQL語句
    Category c = new Category();c.setName("新增加的Category"); session.insert("addCategory",c);
  • addCategory對應的插入sql語句,#{name}會自動獲取c對象的name屬性值:<insert id="addCategory" parameterType="Category" > insert into category_ ( name ) values (#{name}) </insert>

刪除

  • 刪除id=6的對象:Category c = new Category(); c.setId(6); session.delete("deleteCategory",c);
  • deleteCategory對應刪除的sql語句:<delete id="deleteCategory" parameterType="Category" > delete from category_ where id= #{id} </delete>

獲取

  • Category c= session.selectOne("getCategory",3);

修改

修改id=3的名稱

Category c= session.selectOne("getCategory",3);
        c.setName("修改了的Category名稱");
        session.update("updateCategory",c);

查詢所有

   private static void listAll(SqlSession session) {
        List<Category> cs = session.selectList("listCategory");
        for (Category c : cs) {
            System.out.println(c.getName());
        }
    }

對應xml:

<select id="listCategory" resultType="Category">
    select * from   category_     
</select>

Mybatis其他查詢

模擬查詢

  • Category.xml
<select id="listCategoryByName"  parameterType="string" resultType="Category">
            select * from   category_  where name like concat('%',#{0},'%')
        </select>    
  • 調用:
public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
  
        List<Category> cs = session.selectList("listCategoryByName","1");
        for (Category c : cs) {
            System.out.println(c.getName());
        }
 
        session.commit();
        session.close();
  
    }
  • 效果:在這裏插入圖片描述

多條件查詢

  • Category.xml 準備sql語句
<select id="listCategoryByIdAndName"  parameterType="map" resultType="Category">
    select * from   category_  where id> #{id}  and name like concat('%',#{name},'%')
</select>
  • 測試代碼
    因爲是多個參數,而selectList方法又只接受一個參數對象,所以需要把多個參數放在Map裏,然後把這個Map對象作爲參數傳遞進去

      Map<String,Object> params = new HashMap<>();
      params.put("id", 3);
      params.put("name", "cat");
      List<Category> cs = session.selectList("listCategoryByIdAndName",params);
    
  • res:在這裏插入圖片描述

Mybatis 多對多查詢

一對多

  • 先準備表格:在這裏插入圖片描述
    • product的cid和category的id
  • 引入Product pojo類:
    • 代碼:
package com.how2java.pojo;
 
public class Product {
    private int id;
    private String name;
    private float price;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "Product [id=" + id + ", name=" + name + ", price=" + price + "]";
    }
 
}
  • 修改Category實體類:提供products的集合
    • 代碼:
package com.how2java.pojo;
 
import java.util.List;
 
public class Category {
    private int id;
    private String name;
    List<Product> products;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Product> getProducts() {
        return products;
    }
    public void setProducts(List<Product> products) {
        this.products = products;
    }
    @Override
    public String toString() {
        return "Category [id=" + id + ", name=" + name + "]";
    }
     
}
  • 修改Category.xml:
    • 通過left join關聯查詢,對Category和Product表進行關聯查詢。
    • 與前面的有所區別,這裏不是用的resultType, 而是resultMap,通過resultMap把數據取出來放在對應的 對象屬性裏
    • 注: Category的id 字段 和Product的id字段同名,Mybatis不知道誰是誰的,所以需要通過取別名cid,pid來區分。
      name字段同理。
    • 代碼:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.how2java.pojo">
        <resultMap type="Category" id="categoryBean">
            <id column="cid" property="id" />
            <result column="cname" property="name" />
     
            <!-- 一對多的關係 -->
            <!-- property: 指的是集合屬性的值, ofType:指的是集合中元素的類型 -->
            <collection property="products" ofType="Product">
                <id column="pid" property="id" />
                <result column="pname" property="name" />
                <result column="price" property="price" />
            </collection>
        </resultMap>
     
        <!-- 關聯查詢分類和產品表 -->
        <select id="listCategory" resultMap="categoryBean">
            select c.*, p.*, c.id 'cid', p.id 'pid', c.name 'cname', p.name 'pname' from category_ c left join product_ p on c.id = p.cid
        </select>   
    </mapper>
  • 測試類:
    • 代碼:
package com.how2java;
  
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 
import com.how2java.pojo.Category;
import com.how2java.pojo.Product;
  
public class TestMybatis {
  
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
  
        List<Category> cs = session.selectList("listCategory");
        for (Category c : cs) {
            System.out.println(c);
            List<Product> ps = c.getProducts();
            for (Product p : ps) {
                System.out.println("\t"+p);
            }
        }
 
        session.commit();
        session.close();
  
    }
}
  • 效果:在這裏插入圖片描述

多對一查詢

  • 修改Product.java:
    • 爲Product增加category屬性
    • 代碼:
package com.how2java.pojo;
 
public class Product {
    private int id;
    private String name;
    private float price;
    private Category category;
     
    public Category getCategory() {
        return category;
    }
    public void setCategory(Category category) {
        this.category = category;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "Product [id=" + id + ", name=" + name + ", price=" + price + "]";
    }
 
}
  • Product.xml
    • 提供Product.xml,通過listProduct配置關聯查詢的sql語句。
    • 然後通過resultMap ,進行字段和屬性的對應。
    • 使用association 進行多對一關係關聯,指定表字段名稱與對象屬性名稱的一一對應關係
    • 代碼:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.how2java.pojo">
        <resultMap type="Product" id="productBean">
            <id column="pid" property="id" />
            <result column="pname" property="name" />
            <result column="price" property="price" />
     
            <!-- 多對一的關係 -->
            <!-- property: 指的是屬性名稱, javaType:指的是屬性的類型 -->
            <association property="category" javaType="Category">
                <id column="cid" property="id"/>
                <result column="cname" property="name"/>
            </association>
        </resultMap>
     
        <!-- 根據id查詢Product, 關聯將Orders查詢出來 -->
        <select id="listProduct" resultMap="productBean">
            select c.*, p.*, c.id 'cid', p.id 'pid', c.name 'cname', p.name 'pname' from category_ c left join product_ p on c.id = p.cid
        </select>   
    </mapper>
  • mybatis-config.xml

    • 在mybatis-config.xml中增加對於Product.xml的映射
    <mappers>
            <mapper resource="com/how2java/pojo/Category.xml"/>
            <mapper resource="com/how2java/pojo/Product.xml"/>
        </mappers>
    
  • 測試:

package com.how2java;
  
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 
import com.how2java.pojo.Product;
  
public class TestMybatis {
  
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
  
        List<Product> ps = session.selectList("listProduct");
        for (Product p : ps) {
            System.out.println(p+" 對應的分類是 \t "+ p.getCategory());
        }
 
        session.commit();
        session.close();
  
    }
}

在這裏插入圖片描述

多對多

https://how2j.cn/k/mybatis/mybatis-many-to-many/1091.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章