MyBatis入门

MyBatis入门

MyBatis是一个第一类持久性框架,支持自定义SQL,存储过程和高级映射。MyBatis几乎消除了所有JDBC代码和手动设置参数以及检索结果。MyBatis可以使用简单的XML或Annotations来配置和映射基元,Map接口和Java POJO(Plain Old Java Objects)到数据库记录。

优势
  1. 简化了JDBC的开发

  2. 能够更好的完成ORM(对象关系映射)

    1.Mybatis原理图

MyBatis.png
#### 2.准备环境
(1)创建mybatisdb数据库,创建user表
   Create database mybatisdb;
   Use mybatisdb;
   Create table user(
   id int primary key auto_increment,
   name varchar(100),
   addr varchar(100),
   age int);
   Insert into user values(null,'guangtouqiang','北京',28);
   Insert into user values(null,'xiongda','上海',30);
   Insert into user values(null,'xiaonger','上海',19);
(2)编译器引入dtd文件

作为xml的约束文件,没连网的情况下也可以在编写xml时可以出现提示信息。

dtd2.jpg
引入dtd.png

3.MyBatis入门案例( 从XML构建SqlSessionFactory)

(1)需求

利用MyBatis框架查询user表中的所有数据

(2)创建mybatisDemo的Java工程,并导入jar包
(3)创建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>
     <!-- 配置MyBatis开发环境 -->
     <environments default="test">
          <!-- 测试环境 -->  
         <environment id="test">
             <!-- MyBatis事务交给JDBC管理 -->
             <transactionManager type="JDBC"></transactionManager>
             <!-- 配置数据源(连接池) -->
             <dataSource type="POOLED">
             <property name="driver" value="com.mysql.jdbc.Driver"/>
             <property name="url" value="jdbc:mysql://localhost:3306/mybatisdb"/>
             <property name="username" value="root"/>
             <property name="password" value="root"/>
             </dataSource>
         </environment>
​
    <!-- 开发环境 -->
​
     </environments>
​
     <!-- 引入映射文件 -->
     <mappers>
         <!-- 引入UserMapper.xml -->
         <mapper resource="com/znonline/pojo/UserMapper.xml"/>
     </mappers>
 </configuration>
(4)创建log4j.properties

用来打印日志文件(SQL语句),可以很清楚的看到执行的sql和执行sql使用的参数。

# Global logging configuration
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
(5)创建pojo对象

POJO对象的属性名字要和数据库表字段的名字保持一致否则无法封装结果集

package com.znonline.pojo;
/**
 * User表
 */
public class User {

    // id
    private int id;
    // 用户名
    private String name;
    // 地址
    private String addr;
    // 年龄
    private int age;

    public User() {
    }

    public User(int id, String name, String addr, int age) {
        this.id = id;
        this.name = name;
        this.addr = addr;
        this.age = age;
    }

    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 String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    public int getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", addr=" + addr + ", age=" + age + "]";
    }

}
(6) 创建映射文件UserMapper.xml

在User类的同级包下,创建UserMapper.xml,代表这个文件是User对象的映射文件

  <?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">
<!-- 映射文件
namespace是该文件的唯一标识
 -->    
 <mapper namespace="userns">
     <!-- 用来查询的SQL,
          id是该SQL的唯一标识 ,resultType是结果集要封装的实体(类的全路径)-->
     <select id="all" resultType="com.znonline.pojo.User">
     select * from user
     </select>
 </mapper>
(7) sqlMapConfig.xml中引入UserMapper.xml

上面已引入

(8)创建UserTest类
package com.znonline.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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 org.junit.Test;

import com.znonline.pojo.User;

/**
 * 测试User
 * @author zn
 */
public class UserTest {

    @Test
    public void FindUserAll() throws IOException {
        //1.创建会话工厂
        InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(in);

        //2.创建Sqlsession,执行SQL
        SqlSession session = ssf.openSession();
        //定位SQL位置  (namespace值.id值)
        List list = session.selectList("userns.all");

        //3.处理结果集
        for(User u:list) {
            System.out.println(u);
        }

        //4.释放资源
        session.close();
    }
}
mybatisDemo演示.png

4.综合案例 - Maven工程

实现User表的CRUD

(1)准备pom.xml
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.znonline</groupId>
    <artifactId>mybatisDemoV2.0</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!--添加mysql驱动程序依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.40</version>
        </dependency>
    <!--整合junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
    <!--整合mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.8</version>
        </dependency>
    <!--整合log4j日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
      <!--配置JDK1.7 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
(2).创建sqlMapConfig.xml
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.znonline</groupId>
    <artifactId>mybatisDemoV2.0</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!--添加mysql驱动程序依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.40</version>
        </dependency>
    <!--整合junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
    <!--整合mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.8</version>
        </dependency>
    <!--整合log4j日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
      <!--配置JDK1.7 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
(3).创建log4j.properties
# Global logging configuration
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
(4).创建pojo对象
(5).主体业务
  • Select

Map:

  <!-- 查询User表中所有数据 -->
    <select id="findAll" resultType="zn.online.pojo.User">
    select * from user
    </select>

    <!-- 查询User表总记录数 -->
    <select id="count" resultType="int">
    select count(*) from user
    </select>

    <!-- 根据id查询User -->
    <select id="findById" resultType="zn.online.pojo.User" parameterType="int">
    select * from user where id=#{userId}
    </select>

Test:

/**
 * User 的CRUD操作
 * @author zn
 */
public class UserTest {

    // 声明会话工厂,线程安全
    SqlSessionFactory ssf = null;

    /**
     * 测试前初始化步骤
     */
    @Before
    public void init() {
        InputStream in;
        try {
            //
            in = Resources.getResourceAsStream("sqlMapConfig.xml");
            ssf = new SqlSessionFactoryBuilder().build(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 查询User表中所有数据
     */
    @Test
    public void findAll() {
        SqlSession session = ssf.openSession();
        List list = session.selectList("userns.findAll");
        // 3.处理结果集
        for (User u : list) {
            System.out.println(u);
        }
        session.close();
    }

    /**
     * 查询User表总记录数
     */
    @Test
    public void count() {
        SqlSession session = ssf.openSession();
        int count = session.selectOne("userns.count");
        System.out.println("User_Table count:"+count);
        session.close();
    }

    /**
     * 根据id查询User
     */
    @Test
    public void findById() {
        SqlSession session = ssf.openSession();
        int userId = 3;
        User user = session.selectOne("userns.findById", userId);
        System.out.println(user);
        session.close();
    }
}

show:


findAll.png
Usercount.png

UserfindById.png
  • Insert

Map:

<!-- 在User中新增一条记录 -->
    <insert id="save" parameterType="zn.online.pojo.User">
        insert into user values(null,#{name},#{addr},#{age})
    </insert>

Test:

  /**
     * 在User中新增一条记录
     */
    @Test
    public void save() {
        SqlSession session = ssf.openSession();

        User user = new User();
        user.setName("lisi");
        user.setAddr("上海");
        user.setAge(21);
        session.insert("userns.save", user);

        // MyBatis需要手动提交事务
        session.commit();
        session.close();
    }

Log/show:
UserInsert.png
  • Update

Map:

<!-- 修改指定的记录 
    动态取值: #{age} age是User中对应的属性
    -->
    <update id="updateAgeByName" parameterType="zn.online.pojo.User">
        update user set age=#{age}
            where name=#{name}
    </update>

Test:

/**
     * 修改指定User名字的年龄
     */
    @Test
    public void updateAgeByName() {
        SqlSession session = ssf.openSession();

        User user = new User();
        user.setAge(25);
        user.setName("zhangsan");
        session.update("userns.updateAgeByName", user);
        session.commit();
        session.close();
    }

Log/Show:
UserUpdateAgeByName.png
  • Delete

Map:

<!-- 按id删除指定User表中的数据 -->
    <delete id="deleteById">
        delete from user where id=#{id}
    </delete>

Test:

  /**
     * 按id删除指定User表中数据
     */
    @Test
    public void deleteById() {
        SqlSession session = ssf.openSession();

        int id = 3;
        session.delete("userns.deleteById", id);
        session.commit();
        session.close();
    }

Log/Show:

5.mybatis入门总结

MyBatis的真正力量在于Mapped Statements。这就是魔术发生的地方。尽管功能强大,但Mapper XML文件相对简单。当然,如果您将它们与等效的JDBC代码进行比较,您会立即看到节省了95%的代码。MyBatis专注于SQL,并尽力避开您的方式。

Mapper XML文件只有几个第一类元素(按照它们应该被定义的顺序):

  • cache- 为给定命名空间配置缓存。

  • cache-ref- 从另一个命名空间引用缓存配置。

  • resultMap- 描述如何从数据库结果集加载对象的最复杂和最强大的元素。

  • parameterMap~~~~- 已弃用!老派的方式来映射参数。内联参数是首选,将来可能会删除此元素。这里没有记录。

  • sql- 可重用的SQL块,可以被其他语句引用。

  • insert- 映射的INSERT语句。

  • update- 映射的UPDATE语句。

  • delete- 映射的DELETE语句。

  • select- 映射的SELECT语句。

接下来的部分将详细描述每个元素,从语句本身开始。

1.查询(select)

<figure id="ag-204" class="ag-paragraph">

Map标签 相关描述
id 作为该SQL的唯一标志
paramentType 代表要执行这个select语句需要传入一个类型为long的参数,即User对象的id
resultType 完成ORM的映射关系所在
返回的预期类型的​​完全限定类名或别名
对于集合,这应该是集合包含的类型,而不是集合本身的类型

</figure>

<figure id="ag-232" class="ag-paragraph">

Test查询可以使用的方法 相关描述
selectList 代表这次调用的select语句查询的结果集会有一条以上的数据
selectOne 返回一条数据,也可以用selectList方法,返回一个指定的数据

</figure>

2.新增(Insert)

<figure id="ag-259" class="ag-paragraph">

Map标签 相关描述
id 作为这条SQL的唯一标志
ParameterType 指定参数类型,通常制定一个对象类型
flushCache 将此设置为true将导致在调用此语句时刷新第2级和本地缓存。
默认值:对于insert,update和delete语句为true。
timeout 这将设置驱动程序在抛出异常之前等待数据库从请求返回的最大秒数。
默认为未设置(取决于驱动程序)
statementType STATEMENT,PREPARED或CALLABLE中的任何一个
默认值:PREPARED。

</figure>

<figure id="ag-296" class="ag-paragraph">

Test查询可以使用的方法 相关描述
Insert(String statement) 没有参数的话,直接执行查询的sql即可
Insert(Stringstatement,Objectparam) 需要参数的话,可以传入

</figure>

3.修改(update)

4.删除(delete)

6.扩展

1.别名

在sqlMapConfig.xml中,可以使用typeAliases元素来简化开发的操作

2.SQL中有特殊字符

当SQL中有特殊字符<,mybatis不能正常解析时,用<![CDATA[??]]>括起来就解决了

``

3. #和$取值的区别

两种方式都可以获取参数的值。

推荐能用#不用$:

  • {}(推荐!)

    1.相当于JDBC中的PreparedStatement,是经过预编译的,是安全的。

    2.会为参数自动拼接引号。

    3.执行SQL效果:select * from user whereuserId=”1”andpwd=”2”

  • ${}:

    1.相当于JDBC中的Statement ,未经过预编译,仅仅是取变量的值,是非安全的,存在SQL注入。

    2.执行SQL效果:select * from user whereuserId=1andpwd=2

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,717评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,501评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,311评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,417评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,500评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,538评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,557评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,310评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,759评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,065评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,233评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,909评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,548评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,172评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,420评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,103评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,098评论 2 352

推荐阅读更多精彩内容

  • 1 Mybatis入门 1.1 单独使用jdbc编程问题总结 1.1.1 jdbc程序 上边使...
    哇哈哈E阅读 3,300评论 0 38
  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,494评论 0 4
  • 什么是mybatis MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis...
    seadragonnj阅读 2,329评论 0 7
  • 悄悄地 在夏的晨 开成一道风景 只为等你 从第一缕熹微中 寻觅关于你的消息 在最后一抹夕阳里 想你姗姗地来 午夜的...
    潇潇雨疏阅读 1,461评论 50 101
  • 侄儿问:面对杂牌军,王阳明又是如何做到纪律严明的呢? 伯父答:在集结部队,发动攻打南昌之前,在南昌城郊20里的南昌...
    元学_陈一元阅读 6,708评论 0 0