1. 程式人生 > >Mybatis入門學習

Mybatis入門學習

分頁 測試類 welcom erp 號碼 and out open ron

為什麽要學習Mybatis?

其實一句話就夠了,web開發需要框架來提高效率,而Mybatis逐漸替代hibernate成為主流,所以必須掌握。這是從需求來講。

Mybatis與JDBC相比,除了因為框架開銷而導致性能略有下降,其他方面都要好很多。

我體會到的最省事兒的地方就是,把ResultSet循環傳入new的實體類中這部分代碼簡化到了sql配置文件(xml)中。

另外,jdbc的sql都在class中,如果需要改sql語句,還得找到源文件去修改sql,然後編譯成class再放到服務器上,然後重啟生效。而Mybatis只需要在配置文件中修改CRUD標簽中的sql就好了。

下面以一個小項目的實現來學習Mybatis。本文只實現全部查詢的操作,至於動態SQL拼接、分頁、攔截器等,將在以後的 Mybatis進階學習 中總結。

【準備工作】

eclipse、tomcat、navicat等軟件就不說了。

首先,展示一下慕課網上下載的前端頁面:

技術分享

其次,從https://github.com/mybatis/mybatis-3上下載最新的RELEASE版本(mybatis-3.4.5)和相應的資源包(mybatis-3-mybatis-3.4.5),還需要下載mysql驅動包(mysql-connector-java-5.1.42)和JSP標簽庫的兩個jar(jstl.jar和standard.jar)。

導入jar包之後就可以開始項目了。

【項目開發】

一、設計數據庫

我個人的習慣是先設計數據庫,參照前端頁面(其實就是需求)設計好數據庫test_mybatis,其中message表包含字段id(int)、command(varchar)、description(varchar)、content(varchar)。

插入數據的sql代碼如下:

INSERT INTO `message` VALUES (1, 查看, 精彩內容, 精彩內容);
INSERT INTO `message` VALUES (2, 段子, 精彩段子, 如果你的月薪是3000塊錢,請記得分成五份,一份用來買書,一份給家人,一份給女朋友買化妝品和衣服,一份請朋友們吃飯,一份作為同事的各種婚喪嫁娶的份子錢。剩下的2999塊錢藏起來,不要告訴任何人);
INSERT INTO `message` VALUES (3, 新聞, 今日頭條, 7月17日,馬來西亞一架載有298人的777客機在烏克蘭靠近俄羅斯邊界墜毀。另據國際文傳電訊社消息,墜毀機型為一架波音777客機,機載約280名乘客和15個機組人員。\r\n烏克蘭空管部門隨後證實馬航MH17航班墜毀。烏克蘭內政部幕僚表示,這一航班在頓涅茨克地區上空被擊落。馬來西亞航空公司確認,該公司從阿姆斯特丹飛往吉隆坡的MH17航班失聯,並稱最後與該客機取得聯系的地點在烏克蘭上空。圖為馬航客機墜毀現場。
); INSERT INTO `message` VALUES (4, 娛樂, 娛樂新聞, 昨日,鄧超在微博分享了自己和孫儷的書法。夫妻同樣寫幸福,但差距很大。鄧超自己都忍不住感慨字醜:左邊媳婦寫的。右邊是我寫的。看完我再也不幸福了。); INSERT INTO `message` VALUES (5, 電影, 近日上映大片, 《忍者神龜》[2]真人電影由美國派拉蒙影業發行,《洛杉磯之戰》導演喬納森·裏貝斯曼執導。 \r\n片中四只神龜和老鼠老師都基於漫畫和卡通重新繪制,由動作捕捉技術實現。\r\n其中皮特·普勞澤克飾演達芬奇(武器:武士刀),諾爾·費舍飾演米開朗基羅(武器:雙節棍),阿倫·瑞奇森飾演拉斐爾(武器:鐵叉),傑瑞米·霍華德飾演多拉泰羅(武器:武士棍)。\r\n該片計劃於2014年8月8日在北美上映。); INSERT INTO `message` VALUES (6, 彩票, 中獎號碼, 查啥呀查,你不會中獎的!);

二、配置Mybatis

1.首先需要寫好Message實體類

public class Message {
    private int id;
    private String command;
    private String description;
    private String content;
    
    public Message(){}

    public int getId() {
        return id;
    }

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

    public String getCommand() {
        return command;
    }

    public void setCommand(String command) {
        this.command = command;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

2.接下來配置Configuration.xml和Message.xml

前者是Mybatis的核心配置文件,主要用來連接MySQL數據庫和映射Message.xml。

後者用來編寫sql語句和把查詢的結果集與實體類各屬性(4個字段)映射。

沒必要自己把這兩個xml敲出來,可以在資源包mybatis-3-mybatis-3.4.5\src\test\java\org\apache\ibatis\submitted\complex_property中得到Configuration.xml和User.xml,把相應代碼修改後就可以使用了。

Configuration.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>
  <!-- <settings>
    <setting name="useGeneratedKeys" value="false"/>
    <setting name="useColumnLabel" value="true"/>
  </settings>

  <typeAliases>
    <typeAlias alias="UserAlias" type="org.apache.ibatis.submitted.complex_property.User"/>
  </typeAliases> -->

  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC">
        <property name="" value=""/>
      </transactionManager>
      <dataSource type="UNPOOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/test_mybatis"/>
        <property name="username" value="root"/>
        <property name="password" value="[email protected]#$"/>
      </dataSource>
    </environment>
  </environments>

  <mappers>
    <mapper resource="config/sqlxml/Message.xml"/>
  </mappers>

</configuration>

Message.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="Message">

  <resultMap type="javabean.Message" id="MessageResult">
    <id column="id" jdbcType="INTEGER" property="id"/>
    <result column="command" jdbcType="VARCHAR" property="command"/>
    <result column="description" jdbcType="VARCHAR" property="description"/>
    <result column="content" jdbcType="VARCHAR" property="content"/>
  </resultMap>

  <select id="getByName" resultMap="MessageResult">
    select id,command,description,content from message where 1=1 
  </select>

</mapper>

三、實現數據庫操作

編寫DBUtil類和MessageDAO類(由於項目簡單,沒有寫service層和dao與service的Impl層)。前者連接MySQL並返回SqlSession對象,後者實現查詢操作。

註意要在dao中處理異常,並在finally中關閉SqlSession。

這一步完成後,可以寫一個測試類,檢驗代碼是否正確。

public class DBUtil {
    public SqlSession getSqlSession() throws IOException{
        //通過配置文件Configuration.xml獲取數據庫連接信息
        Reader reader = Resources.getResourceAsReader("config/Configuration.xml");
        //通過配置信息構建一個SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        //通過sqlSessionFactory打開一個數據庫會話
        SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSession;
    }
}
public class MessageDAO {
    /**
     * 查詢列表信息(方法名是為多選擇查詢起的,會在以後的文章中實現)
     */
    public List<Message> getByName(String command, String description){
        DBUtil dbUtil = new DBUtil();
        SqlSession sqlSession = null;
        List<Message> messageList = new ArrayList<Message>();
        try {
            sqlSession = dbUtil.getSqlSession();
            //通過sqlSession執行SQL語句,需要sql的配置文件Message.xml
            messageList = sqlSession.selectList("Message.getByName");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if(sqlSession!=null){
                sqlSession.close();
            }
        }
        return messageList;
    }
    
}

四、編寫servlet和JSP相應代碼

1.servlet類和web.xml中的配置

@SuppressWarnings("serial")
public class ListServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //編碼一律用utf-8
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        
        //接收頁面參數的值
        String command = req.getParameter("command");
        String description = req.getParameter("description");
        /*一開始總打印null,原來是name放錯位置了,應該放到input裏!!!
        System.out.println(command);
        System.out.println(description);*/
        
        //按command和description查詢列表信息
        MessageDAO messageDAO = new MessageDAO();
        List<Message> messageList = messageDAO.getByName(command, description);
        
        //向頁面傳值
        req.setAttribute("command", command);
        req.setAttribute("description", description);
        req.setAttribute("messageList", messageList);
        
        //頁面跳轉
        /*因為要傳遞參數,而不用重定向*/
        req.getRequestDispatcher("/jsp/back/list.jsp").forward(req, resp);
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>testMybatis</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
      <servlet-name>ListServlet</servlet-name>
      <servlet-class>servlet.ListServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>ListServlet</servlet-name>
      <url-pattern>/list.action</url-pattern>
  </servlet-mapping>
</web-app>

2.JSP頁面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <base href="<%=basePath%>">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta http-equiv="X-UA-Compatible"content="IE=9; IE=8; IE=7; IE=EDGE" />
        <title>內容列表頁面</title>
        <link href="css/all.css" rel="stylesheet" type="text/css" />
    </head>
    <body style="background: #e1e9eb;">
        <form action="list.action" id="mainForm" method="post">
            <div class="right">
                <div class="current">當前位置:<a href="javascript:void(0)" style="color:#6E6E6E;">內容管理</a> &gt; 內容列表</div>
                <div class="rightCont">
                    <p class="g_title fix">內容列表 <a class="btn03" href="#">新 增</a>&nbsp;&nbsp;&nbsp;&nbsp;<a class="btn03" href="#">刪 除</a></p>
                    <table class="tab1">
                        <tbody>
                            <tr>
                                <td width="90" align="right">指令名稱:</td>
                                <td>
                                    <input name="command" type="text" class="allInput" value="${command}"/>
                                </td>
                                <td width="90" align="right">描述:</td>
                                <td>
                                    <input name="description" type="text" class="allInput" value="${description}"/>
                                </td>
                                <td width="85" align="right"><input type="submit" class="tabSub" value="查 詢" /></td>
                               </tr>
                        </tbody>
                    </table>
                    <div class="zixun fix">
                        <table class="tab2" width="100%">
                            <tbody>
                                <tr>
                                    <th><input type="checkbox" id="all" onclick="#"/></th>
                                    <th>序號</th>
                                    <th>指令名稱</th>
                                    <th>描述</th>
                                    <th>操作</th>
                                </tr>
                                <c:forEach items="${messageList}" var="message" varStatus="status">
                                    <tr <c:if test="${status.index % 2 !=0}">style="background-color:#ECF6EE;"</c:if>>
                                        <td><input type="checkbox" /></td>
                                        <td>${status.index + 1}</td>
                                        <td>${message.command }</td>
                                        <td>${message.description }</td>
                                        <td>
                                            <a href="#">修改</a>&nbsp;&nbsp;&nbsp;
                                            <a href="#">刪除</a>
                                        </td>
                                    </tr>
                                </c:forEach>
                            </tbody>
                        </table>
                        <div class=‘page fix‘><b>4</b><a href=‘###‘ class=‘first‘>首頁</a>
                            <a href=‘###‘ class=‘pre‘>上一頁</a>
                            當前第<span>1/1</span><a href=‘###‘ class=‘next‘>下一頁</a>
                            <a href=‘###‘ class=‘last‘>末頁</a>
                            跳至&nbsp;<input type=‘text‘ value=‘1‘ class=‘allInput w28‘ />&nbsp;&nbsp;
                            <a href=‘###‘ class=‘go‘>GO</a>
                        </div>
                    </div>
                </div>
            </div>
        </form>
    </body>
</html>

【總結】

本文主要用來記錄和復習大致過程,因此很多細節沒有過多說明。

且由於個人水平有限,很多地方都只有最簡單的講解,而且難免有錯,在深入學習之後會做出修改和說明。

PS:寫博客真的似乎有點兒浪費時間啊,可能我太不老練吧,感覺有這一個多小時可以學更多東西或者復習所做的項目了。。

Mybatis入門學習