MyBatis學(xué)習(xí)筆記(一):入門介紹

準(zhǔn)備好好學(xué)習(xí)一下SSM框架,首先從最簡單的MyBatis開始荆姆。主要參考《Java EE互聯(lián)網(wǎng)輕量型框架整合開發(fā)》和《Spring MVC+MyBatis開發(fā) 從入門到項(xiàng)目實(shí)戰(zhàn)》這兩本書执桌。本文也可以認(rèn)為是這兩本書的讀書筆記桅狠,

MyBatis特點(diǎn)

MyBatis是采用配置文件動態(tài)管理SQL語句奸笤,并含有輸入映射痕檬、輸出映射機(jī)制以及數(shù)據(jù)庫連接池配置的持久層框架。

MyBatis的核心組組件分成以下4個部分:

  • SqlSessionFactoryBuilder(構(gòu)造器): 它會根據(jù)配置或者代碼來生成SqlSessionFactory,采用的是分步構(gòu)建的Builder模式歹苦。
  • SqlSessionFactory(工廠接口):依賴它來生成SqlSession青伤。
  • SqlSession(會話): 一個既可以發(fā)送SQL執(zhí)行返回結(jié)果,又可以獲取Mapper的接口殴瘦。
  • SQL Mapper(映射器): MyBatis新設(shè)計(jì)存在的組件狠角,它由一個Java接口和XML文件構(gòu)成,需要給出對應(yīng)的的SQL和映射規(guī)則蚪腋。

下面開始搭建項(xiàng)目丰歌。

準(zhǔn)備環(huán)境

準(zhǔn)備數(shù)據(jù)庫

打開MySql數(shù)據(jù)庫,創(chuàng)建一個簡單的數(shù)據(jù)表并插入幾條數(shù)據(jù)屉凯。

  1. 創(chuàng)建數(shù)據(jù)庫mybatis_demo立帖。
create database `mybatis_demo`;
use `mybatis_demo`;
  1. 創(chuàng)建數(shù)據(jù)表t_users。
drop table if exists `t_users`;
create table `t_users` (
   `id` INT(11) NOT NULL AUTO_INCREMENT,
   `username` VARCHAR(120) COLLATE utf8_bin DEFAULT NULL,
   `password` VARCHAR(50) COLLATE utf8_bin DEFAULT NULL,
   `gender` VARCHAR(5) COLLATE utf8_bin DEFAULT NULL,
   `email` VARCHAR(100) COLLATE utf8_bin DEFAULT NULL,
   `province` VARCHAR(50) COLLATE utf8_bin DEFAULT NULL,
   `city` VARCHAR(120) COLLATE utf8_bin DEFAULT NULL,
   `birthday` DATE DEFAULT NULL,
   PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
  1. 插入幾條數(shù)據(jù)悠砚。
insert into `t_users` (`id`, `username`, `password`, `gender`, `email`, `province`, `city`, `birthday`)
values
(1, '張三','111','男','111@126.com','河北省','衡水市','1990-01-01'),
(2, '李四','222','男','222@126.com','河南省','洛陽市','1992-08-08'),
(3, '王五','333','男','333@126.com','湖南省','長沙市','1978-03-15'),
(4, '趙麗','444','女','444@126.com','湖北省','武漢市','1999-12-01');

一個需要注意的地方是引號和反引號的使用晓勇。在插入列的時候必須使用引號,其它地方大部分使用反引號灌旧。

搭建工程

使用Eclipse創(chuàng)建一個Maven Web項(xiàng)目绑咱。打開pom.xml,添加依賴包。分別是MyBatis依賴包枢泰、MySql數(shù)據(jù)庫連接jar包 和日志包描融。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.wyk</groupId>
  <artifactId>mybatisDemo</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>mybatisDemo Maven Webapp</name>
  <url>http://maven.apache.org</url>
  
  <properties>
    <!-- MyBatis版本號 -->
    <mybatis.version>3.2.6</mybatis.version>
    <log4j.version>1.2.17</log4j.version>
  </properties>
  <dependencies>
    <!-- 導(dǎo)入Mysql數(shù)據(jù)庫連接jar包 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.30</version>
    </dependency>
    <!-- MyBatis核心包 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>${mybatis.version}</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>${log4j.version}</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <finalName>mybatisDemo</finalName>
  </build>
</project>

進(jìn)行開發(fā)

下面編寫小項(xiàng)目的代碼并添加配置文件。

添加實(shí)體類

創(chuàng)建com.wyk.mybatisDemo.pojo包并在其中添加Java實(shí)體類User宗苍,用來和數(shù)據(jù)表相對應(yīng)稼稿。

package com.wyk.mybatisDemo.pojo;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable {

    private int id;
    private String username;
    private String password;
    private String gender;
    private String email;
    private String province;
    private String city;
    private Date birthday;
    
    public User() {}
    
    public User(int id, String username, String password, String gender,
            String email, String province, String city, Date birthday) {
        super();
        this.id = id;
        this.username = username;
        this.password = password;
        this.gender = gender;
        this.email = email;
        this.province = province;
        this.city = city;
        this.birthday = birthday;
    }

    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 String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getEmail() {
        return email;
    }

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

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public Date getBirthday() {
        return birthday;
    }

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

在該實(shí)體中,創(chuàng)建了User的所有屬性信息和他們的get讳窟、set方法让歼,并且創(chuàng)建了一個無參構(gòu)造函數(shù)和一個有參構(gòu)造函數(shù)。

配置日志

在resources目錄下創(chuàng)建文件log4j.properties丽啡,為log4j日志輸出環(huán)境配置參數(shù)谋右。

#Global logging configuration
#
log4j.rootLogger=DEBUG, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern==%d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n

配置數(shù)據(jù)庫連接池

在resources下創(chuàng)建文件SqlMapConfig.xml,添加數(shù)據(jù)庫連接相關(guān)的配置补箍。

<?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="logImpl" value="LOG4J" />
    </settings>
    <environments default="development">
        <environment id="development">
            <!-- 使用JDBC事務(wù)管理 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 數(shù)據(jù)庫連接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo?characterEncoding=utf-8"/>
                <property name="username" value="root" />
                <property name="password" value="123" />
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/wyk/mybatisDemo/mapper/userMapper.xml" />
    </mappers>
</configuration>

注意開頭的DTD不能寫錯梧税。

配置SQL映射

前面注意到拂蝎,SqlMapConfig.xml的mappers標(biāo)簽下已經(jīng)添加了一個引用,這就是我們要創(chuàng)建的文件。創(chuàng)建com.wyk.mybatisDemo.mapper包并添加xml文件usserMapper.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.wyk.mybatisDemo.tests" >
    <select id="findUserById" parameterType="int" resultType="com.wyk.mybatisDemo.pojo.User">
        SELECT * FROM T_USERS WHERE id=#{id}
    </select>
</mapper>

創(chuàng)建數(shù)據(jù)庫交互類

創(chuàng)建包c(diǎn)om.wyk.mybatisDemo.datasource,并在其中創(chuàng)建一個可以獲取sqlSession的類DataConnection幌绍,采用了單例模式邑贴。

package com.wyk.mybatisDemo.datasource;

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;

public class DataConnection {

    private final static Class<DataConnection> LOCK = DataConnection.class;
    private static String resource = "SqlMapConfig.xml";
    private static SqlSessionFactory sqlSessionFactory = null;
    
    private DataConnection() {}
    
    public static SqlSessionFactory getSqlSessionFactory() {
        //加鎖恬吕,防止多次實(shí)例化
        synchronized(LOCK) {
            if(sqlSessionFactory != null) {
                return sqlSessionFactory;
            }
            
            InputStream inputStream;
            try {
                inputStream = Resources.getResourceAsStream(resource);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
            return sqlSessionFactory;
        }
    }
    
    public static SqlSession openSqlSession() {
        if(sqlSessionFactory == null) {
            getSqlSessionFactory();
        }
        return sqlSessionFactory.openSession();
    }   
}

其中類的構(gòu)造參數(shù)加入了private關(guān)鍵字,使其他代碼無法創(chuàng)建它。

進(jìn)行測試

在com.wyk.mybatisDemo.tests包下添加JUnit測試用例MyBatisTest拇泣。

package com.wyk.mybatisDemo.tests;

import java.io.IOException;
import java.text.SimpleDateFormat;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.wyk.mybatisDemo.datasource.DataConnection;
import com.wyk.mybatisDemo.pojo.User;

import junit.framework.TestCase;

public class MyBatisTest extends TestCase {
    
    @Test
    public void TestSelect() throws IOException {
        SqlSession sqlSession = DataConnection.openSqlSession();
        //statement的格是當(dāng)前類名+SQL語句的ID
        User user = sqlSession.selectOne("com.wyk.mybatisDemo.tests.findUserById", 1);
        System.out.println("姓名:" + user.getUsername());
        System.out.println("性別:" + user.getGender());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        System.out.println("生日:" + sdf.format(user.getBirthday()));
        System.out.println("所在地:" + user.getProvince() + user.getCity());
        sqlSession.close();
    }
}

右鍵該類選擇Run As->Run Configuration,在Test中選擇要測試的方法噪叙,并修改Test Runner為JUint3。


測試配置.png

運(yùn)行測試用例霉翔,查看測試結(jié)果睁蕾。


測試結(jié)果.png

補(bǔ)充

補(bǔ)充2個小知識點(diǎn)。

"#{}"和"${}"的區(qū)別

"#{}"是占位符债朵,類似傳統(tǒng)JDBC里面的"?"; "${"}將傳入的數(shù)據(jù)直接顯示生成在sql之中子眶。

"#{}"可以防止SQL注入,原則上是可以使用"#{}"的地方全用"#{}"序芦。

一些地方必須使用"${}":字符需要進(jìn)行拼接的時候(比如兩側(cè)有%)壹店;排序使用order byd動態(tài)參數(shù);傳入數(shù)據(jù)庫對象(例如表名)芝加。

PS:前面寫道字符需要進(jìn)行拼接的時候必須使用"${}"。后面發(fā)現(xiàn)其實(shí)使用concat函數(shù)可以達(dá)到同樣的效果射窒,特此記錄藏杖。

下例中的兩個SQL效果是一樣的:

<select id="findUserByUsername" resultType="user" >
    SELECT * FROM T_USERS WHERE username LIKE '%${value}%'
</select>

<select id="findUserByUsername2" resultType="user" >
    SELECT * FROM T_USERS WHERE username LIKE CONCAT('%', #{value}, '%')
</select>

"selectOne"和"selectList"

這個比較簡單,前者返回一條記錄脉顿,后者返回多條記錄蝌麸。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市艾疟,隨后出現(xiàn)的幾起案子来吩,更是在濱河造成了極大的恐慌,老刑警劉巖蔽莱,帶你破解...
    沈念sama閱讀 222,946評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弟疆,死亡現(xiàn)場離奇詭異,居然都是意外死亡盗冷,警方通過查閱死者的電腦和手機(jī)怠苔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仪糖,“玉大人柑司,你說我怎么就攤上這事」埃” “怎么了攒驰?”我有些...
    開封第一講書人閱讀 169,716評論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長故爵。 經(jīng)常有香客問我玻粪,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,222評論 1 300
  • 正文 為了忘掉前任奶段,我火速辦了婚禮饥瓷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘痹籍。我一直安慰自己呢铆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,223評論 6 398
  • 文/花漫 我一把揭開白布蹲缠。 她就那樣靜靜地躺著棺克,像睡著了一般。 火紅的嫁衣襯著肌膚如雪线定。 梳的紋絲不亂的頭發(fā)上娜谊,一...
    開封第一講書人閱讀 52,807評論 1 314
  • 那天,我揣著相機(jī)與錄音斤讥,去河邊找鬼纱皆。 笑死,一個胖子當(dāng)著我的面吹牛芭商,可吹牛的內(nèi)容都是我干的派草。 我是一名探鬼主播,決...
    沈念sama閱讀 41,235評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼铛楣,長吁一口氣:“原來是場噩夢啊……” “哼近迁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起簸州,我...
    開封第一講書人閱讀 40,189評論 0 277
  • 序言:老撾萬榮一對情侶失蹤鉴竭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后岸浑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體搏存,經(jīng)...
    沈念sama閱讀 46,712評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,775評論 3 343
  • 正文 我和宋清朗相戀三年矢洲,在試婚紗的時候發(fā)現(xiàn)自己被綠了祭埂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,926評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡兵钮,死狀恐怖蛆橡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情掘譬,我是刑警寧澤泰演,帶...
    沈念sama閱讀 36,580評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站葱轩,受9級特大地震影響睦焕,放射性物質(zhì)發(fā)生泄漏藐握。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,259評論 3 336
  • 文/蒙蒙 一垃喊、第九天 我趴在偏房一處隱蔽的房頂上張望猾普。 院中可真熱鬧,春花似錦本谜、人聲如沸初家。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,750評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽溜在。三九已至,卻和暖如春他托,著一層夾襖步出監(jiān)牢的瞬間掖肋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,867評論 1 274
  • 我被黑心中介騙來泰國打工赏参, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留志笼,地道東北人。 一個月前我還...
    沈念sama閱讀 49,368評論 3 379
  • 正文 我出身青樓把篓,卻偏偏與公主長得像籽腕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子纸俭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,930評論 2 361

推薦閱讀更多精彩內(nèi)容