1. 程式人生 > >SSM入門之路(5):使用Mybatis操縱MySQL資料庫

SSM入門之路(5):使用Mybatis操縱MySQL資料庫

先使用,後原理。

一、工具準備

本文執行環境:
JDK 1.8.0
Eclipse Oxygen.3a Release (4.7.3a)
MySQL 8.0.12-standard

二、Mybatis簡介

官網定義: MyBatis 是支援定製化 SQL、儲存過程以及高階對映的優秀的持久層框架。MyBatis 避免了幾乎所有的 JDBC 程式碼和手工設定引數以及抽取結果集。MyBatis 使用簡單的 XML 或註解來配置和對映基本體,將介面和 Java 的 POJOs(Plain Old Java Objects,普通的 Java物件)對映成資料庫中的記錄。
使用上來說,就是幫我們省去了手動寫程式碼來和資料庫建立連線以及從資料庫中抽取資料這些麻煩事,讓程式設計師可以專注於SQL核心程式碼。

三、準備源資料

在mySQL伺服器上建立myjava資料庫,在資料庫中建立table product_(id, name, price)。
使用終端/視覺化介面均可。
MySQL Server常用命令戳:這裡,博主總結得非常詳細。
建表程式碼:

/* 設定id自增,使用MyISAM引擎避免插入記錄時自增id不連續 */
CREATE TABLE product_ (
  id int(11) NOT NULL AUTO_INCREMENT,
  name varchar(32) DEFAULT NULL,
  price float(32,8) NOT NULL,
  PRIMARY
KEY (id) ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

然後插入一些資料:

insert into product_ (name, price) values ('apple',12),('book',35.5),('pen',2.0); 

這張product_表的初始內容:
my_product

四、實現通過Mybatis操縱資料庫

1)新建Java Project,此例命名為mybatis。

2)匯入需要的jar包。
- mybatis-3.4.2.jar
- mysql-connector-java-5.0.8-bin.jar

3)專案檔案目錄如下:
mybatis_directory

4)各檔案內容。

  • mybatis-config.xml:配置連線的資料庫資訊和mapper位置。
<?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配置可以直接使用pojo package中類的名字,不用全名  -->
    <typeAliases>
        <package name="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/myjava?characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="yourpassword"/>
            </dataSource>
        </environment>
    </environments>

    <!-- SQL語句寫在這個檔案裡 -->
    <mappers>
        <mapper resource="pojo/Query.xml"/>
    </mappers>
</configuration>
  • Query.xml:配置對資料庫的操作語句
<?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="pojo">

    <!-- 定義對product_表的增、刪、改操作 -->
    <insert id="addProduct" parameterType="Product">
        insert into product_ (name, price) values (#{name}, #{price})
    </insert>
    <delete id="deleteProduct" parameterType="Product">
        delete from product_ where id=#{id}
    </delete>
    <update id="updateProduct" parameterType="Product">
        update product_ set name=#{name}, price=#{price} where id=#{id}
    </update>
    <!-- 按id返回產品資訊 -->
    <select id="getProductById" parameterType="_int" resultType="Product">
        select * from product_ where id=#{id}
    </select>
    <!-- 獲取全部產品資訊 -->
    <select id="listProduct" resultType="Product">
        select * from product_
    </select>

    <!-- ====================================
        多條件查詢:
        查詢 id大於指定序號,且名稱以#{name}開頭的產品
    ======================================= -->
    <select id="listProductByIdAndName" parameterType="map" resultType="Product">
        select * from product_ where id>#{id} and name like concat(#{name},'%')
    </select>

</mapper>
  • Product.java:product實體類
package 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;
    }

    public String toString() {
        return id+"\t"+name +"\t"+price;
    }
}
  • ProductManager.java:實現對資料庫進行操作的介面函式,供主程式呼叫
package manager;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

import pojo.Product;

public class ProductManager {

    /* 新增記錄 */
    public void addProduct(SqlSession session, String name, float price) {
        Product p = new Product();
        p.setName(name);
        p.setPrice(price);
        session.insert("addProduct", p);
        System.out.println("插入記錄" + p.getName());
    }

    /* 刪除指定id的記錄 
     * 如果該記錄不存在
     * 列印提示資訊,不做刪除*/
    public void deleteProduct(SqlSession session, int id) {
        System.out.println("嘗試刪除id為"+id+"的記錄");
        Product p = getProductById(session, id);
        if(p == null) return;
        session.delete("deleteProduct",id);
        System.out.println("成功刪除第"+id+"條記錄");
    }

    /* 查詢指定id的記錄
     * 如果該記錄不存在
     * 列印提示資訊 */
    public Product getProductById(SqlSession session, int id) {
        Product p = session.selectOne("getProductById",id);
        if(p == null) {
            System.out.println("記錄不存在!");
        }
        return p;
    }

    /* 修改指定id的記錄 
     * 如果該記錄不存在
     * 列印提示資訊,不做修改*/
    public void updateProduct(SqlSession session, int id, String name, float price) {
        System.out.println("嘗試修改id為"+id+"的記錄");
        Product p = getProductById(session, id);
        if(p == null) return;
        p.setName(name);
        p.setPrice(price);
        session.update("updateProduct", p);
        System.out.println("成功修改第"+id+"條記錄");
    }

    /* product_: 多條件查詢
     * 輸出序列號大於id,且名稱以name開頭的產品資訊
     * 返回符合條件的記錄條數
     * 
     * 因為selectList只接受一個引數物件
     * 故將多個引數裝進map裡傳入 */
    public int listProductByIdAndName(SqlSession session, int id, String name) {
        Map<String, Object> params = new HashMap<>();
        params.put("id",id);
        params.put("name", name);
        List<Product> multiSelectResult = session.selectList("listProductByIdAndName", params);
        for(Product p: multiSelectResult) {
            System.out.println(p);
        }
        return multiSelectResult.size();
    }

    /* 列印當前所有產品資訊 */
    public void listAllProduct(SqlSession session) {
        List<Product> pl=session.selectList("listProduct");
        System.out.println("當前產品如下:");
        /*for(int i=0; i < pl.size(); i++) {
            System.out.println((i+1)+"\t"+pl.get(i));
        }*/
        for(Product p: pl) {
            System.out.println(p);
        }
        System.out.println();
    }
}
  • TestMybatis.java:測試類,先與資料庫建立會話(session),然後通過此session物件對資料庫進行操作。
package test;

import java.io.IOException;
import java.io.InputStream;

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 manager.*;

public class TestMybatis {
    public static void main(String[] args) throws IOException {
        //根據配置檔案mybatis-config.xml得到sqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //建立會話
        SqlSession session=sqlSessionFactory.openSession();
        ProductManager m1 = new ProductManager();

        {資料庫操作測試程式碼:詳見步驟5}

        /*使用commit方法將更改提交到資料庫*/
        session.commit();
        session.close();        
    }
}

5)執行結果。

  • 列印當前產品資訊
m1.listAllProduct(session);

pro_initial

  • 插入記錄測試
/* porduct_:插入記錄測試 */
m1.addProduct(session, "beef", 60);
m1.listAllProduct(session);

pro_insert

  • 刪除記錄測試
/* product_: 刪除記錄測試 */
m1.deleteProduct(session, 5);
m1.listAllProduct(session); 

pro_delete

  • 修改記錄測試
/* product_: 修改記錄測試 */
m1.updateProduct(session, 1, "pineapple", 100);
m1.listAllProduct(session);             

pro_update

  • 多條件查詢測試
/* product_: 多條件查詢測試*/
System.out.println("滿足條件的記錄為:");
m1.listProductByIdAndName(session, 0, "b");

pro_multicondition

6)執行操作後資料庫中資料也發生改變。
pro_final

五、問題及解決

問題描述:執行TestMybatis時與資料庫建立連線失敗,出現MySQLNonTransientConnectionException: Client does not support authentication protocol requested by server; consider upgrading MySQL client錯誤。

The current implementation of the authentication protocol uses a password hashing algorithm that is incompatible with that used by older (pre-4.1) clients.

解決方式:在MySQL中修改密碼為舊密碼驗證方式。

SET PASSWORD FOR 'some_user'@'some_host' = OLD_PASSWORD('new_password');