2021年8月2日 星期一

建立一個最基本的 mybatis

在 maven 專案下建立 mybatis,並完成對資料庫的新增/查詢/修改/刪除動作

環境

    Intellij IDEA 2021.1。

    已建立好的 springboot 專案。

    Oracle 12c (cdb/pdb模式) 資料庫,建好一張叫 Person 的表,其 schema 如下。


    CREATE TABLE PERSON (

        NAME VARCHAR2(100) NOT null,

        EMAIL VARCHAR2(100),

        AGE INTEGER,

        CONSTRAINT "PERSON_PK" PRIMARY KEY ("NAME")

    );


提示

對 oracle 的連接字串,在版本 12c 前/後似乎不同,之前的似乎是,jdbc:oracle:thin:@192.168.1.113:1521:ORCLPDB1 

之後的是 jdbc:oracle:thin:@192.168.1.113:1521/ORCLPDB1,sid (ORCLPDB1) 前面的是:或是/。這可能是因為 12c 之

後多了 cdb/pdb 的關係,所以即使在 12c 之後如果資料庫是設定非 cdb/pdb 這種格式的話,可能 sid 前也是要用「:」。

如果在 12c 「cdb/pdb模式」下,接連字串是用「:」而不是「/」會報一個 ORA-12505, 

TNS:listener does not currently know of SID given in connect descriptor 的錯誤

推論而己,oracle 還不太熟。

本文


1.目錄結構如下

        App.java:入口的 main 方法和測試的程式碼

        UserDao.java:一個 interface,裡面定義的 method 會和 userMapper.xml 裡所定義的 select/insert/update/delete 的標籤上的 id 屬性對應

        Person.java:與資料表內欄位對應的物件

        mybatis-config.xml:與 oracle 連線用的連接字串、及 mybatis 相關的設定值

        userMapper.xml:定義 sql 指令,與 UserDao.java (interface) 內定義的 method 對應


2.上 MVNRepository (https://mvnrepository.com/) 取得 mybatis 和 oracle jdbc 的 dependency,並複製到 pom.xml 下

pom.xml

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.7</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc8 -->
<dependency>
    <groupId>com.oracle.database.jdbc</groupId>
    <artifactId>ojdbc8</artifactId>
    <version>21.1.0.0</version>
</dependency>


3. 建立 mybatis-config.xml,設定 jdbc 對 oracle 的連線和建立的 mapper 文件

mybatis-config.xml

<?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>
    <!-- 環境,可以配置多個,default:指定採用哪個環境 -->
    <environments default="test">
        <!-- id:唯一標識 -->
        <environment id="test">
            <!-- 事務管理器,使用JDBC型別的事務管理器 -->
            <transactionManager type="JDBC" />
            <!-- 使用連接池方式來獲取連接 -->
            <dataSource type="POOLED">
                <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
                <property name="url" value="jdbc:oracle:thin:@192.168.1.113:1521/ORCLPDB1" />
                <property name="username" value="yu" />
                <property name="password" value="qwe" />
            </dataSource>
        </environment>
    </environments>

    <!--加載 map 文件-->
    <mappers>
        <mapper resource="userMapper.xml" />
    </mappers>
</configuration>


4. 建立 Person.java,對應 oracle 中,資料表 person 的欄位

Person.java

package model;

public class Person {
    private int id;
    private String name;
    private String email;
    private int age;

    public int getId(){
        return this.id;
    }
    public void setId(int id){
        this.id = id;
    }

    public String getName(){
        return this.name;
    }
    public void setName(String name){ this.name = name; }

    public String getEmail(){
        return this.email;
    }
    public void setEmail(String email){
        this.email = email;
    }

    public int getAge(){
        return this.age;
    }
    public void setAge(int age){
        this.age = age;
    }
}


5. 建立 userMapper.xml 與 userDAO,建立一個供叫用的 interface,和實際定義了該執行那些 sql 指令的 xml (mapper) 檔案


UserDao.java

package mappers;

import model.Person;

public interface UserDao {
    Person getPersonById(Integer id);
    void AddPerson(Person person);
    int updatePerson(Person person);
    int deletePerson(Person person);
}


userMapper.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="mappers.UserDao">
    <!--當 db 與程式裡定義的 model 不一致時,可以透過 resultmap 重新對應映射,column:db欄名、property:class欄名-->
    <resultMap id="resultListUser" type="model.Person">
        <id column="id" property="id" />
        <result column="namexx" property="name"/>
        <result column="email" property="email"/>
        <result column="age" property="age"/>
    </resultMap>

    <!--resultmap 是指傳回的物件型態,與 resultMap 標籤互相定義-->
    <!--parameterType 執行這段 sql 時傳入的物件型態-->
    <!--id 會對應至 interface (UserDao.java) 中定義的 method 名稱-->
    <select id="getPersonById" parameterType="Integer" resultMap="resultListUser">
        select id, name as namexx, email, age from person where id = #{id}
    </select>
    <insert id="AddPerson" parameterType="model.Person">
        insert into person(Id, name, email, age) values (#{id}, #{name}, #{email}, #{age})
    </insert>
    <update id="updatePerson" parameterType="model.Person">
        update person set email = #{email} where id=#{id}
    </update>
    <delete id="deletePerson" parameterType="model.Person">
        delete from person where id=#{id}
    </delete>
</mapper>

6. 建立測試用的程式碼

App.java

package basic;

import mappers.UserDao;
import model.Person;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;

public class App {
    public static void main(String[] args) throws Exception {
        // 讀取 mybatis-config.xml 設定檔
        String location = "mybatis-config.xml";
        InputStream stream = App.class.getClassLoader().getResourceAsStream(location);

        // 依讀入的 mybatis-config.xml 設定檔,生成 SqlSessionFactory
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(stream);

        // 生成 SqlSession (完全包含以db為背景的所有執行SQL的方法,底層封裝了 jdbc 連接,可以執行被映射的 SQL 語句(從 UserDao 映射到 userMapper.xml 中定義的 sql)
        // 不是線程安全的,使用完務必要關閉。
        SqlSession session = sessionFactory.openSession();

        UserDao userDao = session.getMapper(UserDao.class);

        // 新增資料
        Person newPerson = new Person();
        newPerson.setId(5);
        newPerson.setName("David");
        newPerson.setEmail("David@gmail.com");
        newPerson.setAge(16);
        userDao.AddPerson(newPerson);
        session.commit();

        // 查詢單筆
        Person person = userDao.getPersonById(5);
        System.out.println(person.getName() + " " + person.getEmail() + " " + person.getAge());

        // 更正資料
        person.setId(5);
        person.setEmail("DDD@gmail.com");
        userDao.updatePerson(person);
        session.commit();

        //刪除資料
        userDao.deletePerson(person);
        session.commit();
    }
}


沒有留言:

張貼留言