Mybatis框架

九尾。發表於2021-08-12

Mybatis實現的是JDBC部分的功能

Mybatis入門程式

1、需求

·根據使用者id查詢一個使用者資訊
·根據使用者名稱稱模糊查詢使用者資訊列表
·新增使用者
·更新使用者
·刪除使用者

2、環境

java 環境 :jdk1.8.0_77

開發工具 : IDEA 2016.1

資料庫 : MySQL 5.7

Mybatis 執行環境( jar 包)

MySQL 驅動包

其他依賴包

3、log4j.properties

在工程裡建一個config資料夾,轉成資源目錄,建立一個log4j.properties文字,寫以下內容:

# Global logging configuration
#在開發環境日誌級別要設定為DEBUG、生產環境要設定為INFO或者ERROR
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

Mybatis預設使用log4j作為輸出日誌資訊。
4.bd.properties
jdbc.url=jdbc:mysql:///資料庫名

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///mybatis
jdbc.username=root
jdbc.password=root

5、SqlMapConfig.xml

配置 Mybatis 的執行環境、資料來源、事務等

<?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>
    <properties resource="db.properties"></properties>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <package name="com.mapper"></package>
    </mappers>
</configuration>

6、建立domain對映類

先建立一個com.company.domain包,然後建立一個User類,對應資料庫裡面的User表

package com.company.domain;

import java.util.Date;

/**
 * Created by Administrator on 2017/10/21.
 */
public class User {
    private int id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    public int getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

7、Mapper介面
Mybatis 的 mapper 介面

編寫mapper介面(相當於Dao介面,增刪改查操作),定義增刪改查方法,再編寫 mapper.xml 對映檔案,需遵循一些開發規範,mybatis 可以自動生成 mapper 介面類代理物件。

開發規範:

1.在 mapper.xml 中 namespace 等於 mapper 介面地址(所在包名的全路徑)

<mapper namespace="com.mapper.UserMapper"></mapper>

2.在 xxxmapper.java 介面中的方法名要與 xxxMapper.xml 中 >statement 的 id 一致。
3.在 xxxmapper.java 介面中的輸入引數型別要與 xxxMapper.xml >中 statement 的 parameterType 指定的引數型別一致。
4.在 xxxmapper.java 介面中的返回值型別要與 xxxMapper.xml 中 statement 的 resultType 指定的型別一致。
5.介面檔名要與xml對映檔名一致(UserMapper.java和UserMapper.xml)

程式碼實現:
parameterType:指定輸入引數型別,mybatis 從輸入物件中獲取引數值拼接在 sql 中。如果是變數型別,寫包名加類名
resultType:指定輸出結果型別,mybatis 將 sql 查詢結果的一行記錄資料對映為 resultType 指定型別的物件。
建立com.company.mapper包,然後建立UserMapper介面

public interface UserMapper {
    public User findUserById(int id);
}

建立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="com.mapper.UserMapper">
    <select id="findUserById" parameterType="int" resultType="com.domain.User">
        select * from user where id = #{value}
    </select>
</mapper>

主方法測試:

public static void main(String[] args) throws IOException {
        //建立sqlSessionFactory
        //Mybatis 配置檔案
        String resource = "SqlMapConfig.xml";
        //得到配置檔案流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //建立會話工廠,傳入Mybatis的配置檔案資訊
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //建立usermapper物件,mybatis自動生成代理物件
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //呼叫UserMapper的方法
        User user = userMapper.findUserById(1);
        System.out.println(user.getUsername());
    }
1、SqlSessionFactoryBuilder

SqlSessionFactoryBuilder 用於建立 SqlSessionFacoty,SqlSessionFacoty 一旦建立完成就不需要SqlSessionFactoryBuilder 了,因為 SqlSession 是通過 SqlSessionFactory 生產,所以可以將SqlSessionFactoryBuilder 當成一個工具類使用,最佳使用範圍是方法範圍即方法體內區域性變數。

2、SqlSessionFactory

SqlSessionFactory 是一個介面,介面中定義了 openSession 的不同過載方法,SqlSessionFactory 的最佳使用範圍是整個應用執行期間,一旦建立後可以重複使用,通常以單例模式管理 SqlSessionFactory。

3、SqlSession

SqlSession 是一個面向使用者的介面, sqlSession 中定義了資料庫操作,預設使用 DefaultSqlSession 實現類。

8、單例模式的SqlSessionFactory

public class SqlSessionFactoryUtil {
    //首先建立靜態成員變數sqlSessionFactory,靜態變數被所有的物件所共享。
    public static SqlSessionFactory sqlSessionFactory = null;
    public static SqlSessionFactory getSqlSessionFactory() {
        //如果sqlSessionFactory沒有被建立就讀取全域性配置檔案,假如已經被建立過了,就使用已經存在的sqlsessionfactory。
        //這樣就有了單例模式的效果
        if(sqlSessionFactory==null){
            String resource = "SqlMapConfig.xml";
            try {
                Reader reader = Resources.getResourceAsReader(resource);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return sqlSessionFactory;
    }
}

主方法測試變為:

    public static void main(String[] args) throws IOException {
        //建立sqlSessionFactory
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //建立usermapper物件,mybatis自動生成代理物件
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //呼叫UserMapper的方法
        User user = userMapper.findUserById(1);
        System.out.println(user.getUsername());
    }

9、自定義別名:

在 SqlMapConfig.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>
    <properties resource="db.properties"></properties>
    <typeAliases>
        <!-- 批量別名定義,掃描整個包下的類,別名為類名(首字母大寫或小寫都可以) -->
        <package name="com.company.domain"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <package name="com.mapper"></package>
    </mappers>
</configuration>

10、查詢全部使用者

UserMapper.java

public interface UserMapper {
    public User findUserById(int id);

    public List<User> findAllUsers();
    //新增使用者資訊
    public int addUser(User user);

    //刪除使用者資訊
    public int deleteUser(int id);

    public int updateUserById(User user);
}

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="com.mapper.UserMapper">
    <select id="findUserById" parameterType="int" resultType="User">
        select * from user where id = #{id}
    </select>
    <--由於已經設定 批量別名定義,掃描整個包下的類,所以此處只需要寫類名即可以找到   -->
    <select id="findAllUsers" resultType="User">
        select * from user
    </select>
</mapper>

主方法測試

public static void main(String[] args) throws IOException {
        //建立sqlSessionFactory
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //建立usermapper物件,mybatis自動生成代理物件
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //呼叫UserMapper的方法
//        User user = userMapper.findUserById(1);
//        System.out.println(user.getUsername());
        List<User> userList = userMapper.findAllUsers();
        for(User user : userList)
        {
            System.out.println(user.getUsername());
        }
    }

雖然 findAllUsers()的返回值型別是List<User>,xml檔案中resultType="User"即可。

新增使用者

 <insert id="addUser" parameterType="User" >
        <selectKey keyProperty="id" order="AFTER" resultType="int">
            select LAST_INSERT_ID()
        </selectKey>
        insert into user(username, birthday, sex, address)
        values(#{username}, #{birthday}, #{sex}, #{address})
    </insert>

主函式

   User user = new User();
        SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd");
        user.setUsername("田志");
        user.setSex("男");
        user.setBirthday(sdf.parse("2016-11-29"));
        user.setAddress("江西南昌");
        userMapper.addUser(user);
        System.out.println(user.getId());
        sqlSession.commit();

增刪改操作需要 sqlSession.commit();

自增主鍵返回

MySQL 自增主鍵:執行 insert 提交之前自動生成一個自增主鍵,通過 MySQL 函式獲取到剛插入記錄的自增主鍵: LAST_INSERT_ID() ,是在 insert 函式之後呼叫。

刪除使用者

  <delete id="deleteUser" parameterType="int">
        delete from user where user.id = #{id}
    </delete>

     userMapper.deleteUser(1);
        sqlSession.commit();

更新使用者

    <update id="updateUserById" parameterType="User">
        update user set username = #{username}, birthday = #{birthday}, sex = #{sex}, address = #{address} where user.id = #{id}
    </update>

    SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd");

        User user = new User();
        //根據id更新使用者資訊
        user.setId(24);
        user.setUsername("張四風2");
        user.setBirthday(sdf.parse("2015-01-12"));
        user.setSex("女");
        user.setAddress("上海黃埔");

        userMapper.updateUserById(user);

        //提交事務
        sqlSession.commit();

模糊查詢使用者方法1:

    <select id="findUserList" parameterType="User" resultType="User">
        select * from user where user.sex = #{sex} and user.username like #{username}
    </select>

 User user = new User();
        user.setSex("1");
        user.setUsername("%張%");

        //呼叫UserMapper的方法
        List<User> list = userMapper.findUserList(user);

        for(User u : list)
        {
            System.out.println(u.getUsername());
        }

模糊查詢使用者方法2:

    <select id="findUserList" parameterType="User" resultType="User">
        select * from user where user.sex = #{sex} and user.username like ‘${%username%}’
    </select>

 User user = new User();
        user.setSex("1");
        user.setUsername("張");

        //呼叫UserMapper的方法
        List<User> list = userMapper.findUserList(user);

        for(User u : list)
        {
            System.out.println(u.getUsername());
        }

查詢user表記錄數

    <select id="findUserCount" resultType="int">
        select count(*) from user
    </select>

      int count = userMapper.findUserCount();
        System.out.println(count);

動態 SQL

通過mybatis提供的各種標籤方法實現動態拼接sql。

 <select id="findUserList2" parameterType="User" resultType="User">
        select * from user
        <!--where可以自動的去掉條件中的第一個and-->
        <where>

                <if test="sex != null and sex != ''">
                    and user.sex = #{sex}
                </if>
                <if test="username != null">
                    and user.username like  #{username}
                </if>

        </where>
    </select>

測試程式碼:因為設定了動態的sql,如果不設定某個值,那麼條件就不會拼接在sql上

所以我們就註釋掉設定username的語句

        User user = new User();
//        user.setSex("1");
        user.setUsername("%張%");

        //呼叫UserMapper的方法
        List<User> list = userMapper.findUserList2(user);

        for(User u : list)
        {
            System.out.println(u.getUsername());
        }

Sql 片段

通過上面的其實看到在 where sql語句中有很多重複程式碼,我們可以將其抽取出來,組成一個sql片段,其他的statement就可以引用這個sql片段,利於系統的開發。

這裡我們就拿上邊sql 中的where定義一個sq片段如下:

 <sql id="query_user_where">
        <if test="sex != null and sex != ''">
            and user.sex = #{sex}
        </if>
        <if test="username != null">
            and user.username like  #{username}
        </if>
    </sql>

那麼我們該怎樣引用這個sql片段呢?如下:

select * from user
        <where>
        <!--refid: 指定sql片段的id,如果是寫在其他的mapper檔案中,則需要在前面加上namespace-->
            <include refid="query_user_where"/>
        </where>

多表連線

再建立一個訂單資訊表

CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT '下單使用者id',
  `number` varchar(32) NOT NULL COMMENT '訂單號',
  `createtime` datetime NOT NULL COMMENT '建立訂單時間',
  `note` varchar(100) DEFAULT NULL COMMENT '備註',
  PRIMARY KEY (`id`),
  KEY `FK_orders_1` (`user_id`),
  CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of orders
-- ----------------------------
INSERT INTO `orders` VALUES ('3', '1', '1000010', '2015-02-04 13:22:35', null);
INSERT INTO `orders` VALUES ('4', '1', '1000011', '2015-02-03 13:22:41', null);
INSERT INTO `orders` VALUES ('5', '10', '1000012', '2015-02-12 16:13:23', null);

    public List<Map<String,Object>> getAllOrderInfo();

    <select id="getAllOrderInfo" resultType="map">
      select orders.number,user.username from orders
join user on orders.user_id = user.id
    </select>

       List<Map<String,Object>> mapList = userMapper.getAllOrderInfo();
        for(Map<String,Object> map : mapList)
        {
            System.out.println("---------------");
            for(Map.Entry<String,Object> entry : map.entrySet())
            {
                System.out.println(entry.getKey()+" "+entry.getValue());
            }

        }

程式碼

案例程式碼

程式碼自動生成

利用MyBatis生成器自動生成實體類、DAO介面和Mapping對映檔案。這樣可以大大節約開發時間,將生成的程式碼copy到專案工程中即可。

要想實現程式碼的自動生成,首先要下載一個工具:http://download.csdn.net/detail/u010608551/9434523,下載後解壓zip檔案,解壓後的目錄應該是如下的效果:

15063652-c5e4399dc8f76d7c.png
image.png

其中有mybatis框架的jar包,資料庫驅動程式jar包以及MyBatis生成器jar包。其中的generatorConfig.xml是需要我們來配置的檔案,先將檔案用記事本開啟改成utf-8檔案,然後把該檔案拖至Itellijie,修改配置成如下,然後儲存,關閉該檔案,將該檔案改回ANSI格式:

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE generatorConfiguration  
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"  
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">  
<generatorConfiguration>  
<!-- 資料庫驅動-->  
    <classPathEntry  location="mysql-connector-java-5.1.25-bin.jar"/>  
    <context id="DB2Tables"  targetRuntime="MyBatis3">  
        <commentGenerator>  
            <property name="suppressDate" value="true"/>  
            <!-- 是否去除自動生成的註釋 true:是 : false:否 -->  
            <property name="suppressAllComments" value="true"/>  
        </commentGenerator>  
        <!--資料庫連結URL,使用者名稱、密碼 -->  
        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/test" userId="root" password="root">  
        </jdbcConnection>  
        <javaTypeResolver>  
            <property name="forceBigDecimals" value="false"/>  
        </javaTypeResolver>  
        <!-- 生成模型的包名和位置-->  
        <javaModelGenerator targetPackage="test.domain" targetProject="src">  
            <property name="enableSubPackages" value="true"/>  
            <property name="trimStrings" value="true"/>  
        </javaModelGenerator>  
        <!-- 生成對映檔案的包名和位置-->  
        <sqlMapGenerator targetPackage="test.mapping" targetProject="src">  
            <property name="enableSubPackages" value="true"/>  
        </sqlMapGenerator>  
        <!-- 生成DAO的包名和位置-->  
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.company.domain" targetProject="src">  
            <property name="enableSubPackages" value="true"/>  
        </javaClientGenerator>  
        <!-- 要生成的表 tableName是資料庫中的表名或檢視名 domainObjectName是實體類名-->  
        <table tableName="emp" domainObjectName="Emp" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
    </context>  
</generatorConfiguration>

其中的資料庫名稱,使用者名稱,密碼以及表表根據自己的具體情況來修改,配置中的targetProject是目標資料夾,不會自動生成,需要自己建立,然後把路徑配好。

配置檔案寫好以後,開啟cmd,將目錄切換到lib目錄下,執行指令碼:java -jar mybatis-generator-core-1.3.2.jar -configfile generatorConfig.xml -overwrite

然後就可以在src目錄下找到相應的檔案,每個資料庫表都會對應三個檔案(實體類、介面、配置檔案)。

15063652-9dfec23477ce9a1b.png
image.png
15063652-893a1c2627c81042.png
image.png

相關文章