mybatis 基础

1.mybatis是什么?

开源的持久层框架。
 jdbc     代码繁琐     sql        性能好
 hibernate  代码简洁   不用写sql   性能不好
 mybatis   代码简洁    要写sql     性能一般

2.mybatis编程步骤:

a.导包,mybatis mysqljdbc junit
b.添加mybatis配置文件
c.写实体类,实体类的属性名与表的字段名要求一致,大小写无所谓
d.写映射文件,修改配置文件,指定映射文件的位置。
e.调用SqlSession提供的方法来访问数据库。

maven 导包

  <dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.46</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.2.8</version>
    </dependency>
  </dependencies>

实例:对Emp表的增删改查

首先是在包entity下建立实体类Emp

package entity;

public class Emp {
    private Integer id;
    private String name;
    private Double age;
}
省略一堆的get/set方法

在entity中建立EmpMapper.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

!-- namespace 的值是 DeptMapper 接口
  每个Mapper 接口对应一个配置文件  -->
<mapper namespace="test">
        id:要求唯一
        resultType:返回结果的类型
        parameterType:参数类型
    <insert id="save" parameterType="entity.Emp">
        INSERT INTO emp(name, age) VALUES(#{name},#{age})
    </insert>
    <select id="findAll" resultType="entity.Emp">
        SELECT * FROM emp
    </select>

    <select id="findById" parameterType="int" resultType="entity.Emp">
        SELECT * FROM emp WHERE id=#{id}
    </select>

    <update id="modify" parameterType="entity.Emp">
        UPDATE emp SET name=#{name}, age=#{age} WHERE id=#{id}
    </update>

    <delete id="delete" parameterType="int">
        DELETE FROM emp WHERE id=#{id}
    </delete>   
</mapper>

在resource文件夹中建立SqlMapConfig.xml文件,作为mybatis的配置文件

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE configuration PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN" 
    "http://ibatis.apache.org/dtd/ibatis-3-config.dtd">
 -- 数据库连接参数配置
<configuration>
    <environments default="environment">
        <environment id="environment">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url"
                    value="jdbc:mysql://localhost:3306/test" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>
    <!-- 映射文件的位置,对应上面的-->
    <mappers>
        <mapper resource="entity/EmpMapper.xml" />
    </mappers>
</configuration> 

测试对数据库的增删改查操作,在test文件夹中建包test,创建类TestCase,mybatis默认不自动提交,需要commit(有些数据库不支持事务)

package test;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import entity.Emp;

public class TestCase {
    private SqlSession session;
    
    @Before
    public void init() {
        SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
        SqlSessionFactory ssf = ssfb.build(TestCase.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml"));
        session = ssf.openSession();
    }
    
    @Test
    public void test1() {
        Emp emp = new Emp();
        emp.setName("wolf");
        emp.setAge(22.0);
        session.insert("test.save", emp);
        session.commit();
        session.close();
    }
    
    @Test
    public void test2() {
        List<Emp> emps = session.selectList("test.findAll");
        System.out.println(emps);
        session.close();
    }
    
    @Test
    public void test3() {
        Emp emp = session.selectOne("test.findById", 4);
        System.out.println(emp);
        session.close();
    }
    
    @Test
    public void test4() {
        Emp emp = session.selectOne("test.findById", 4);
        System.out.println(emp);
        emp.setName("never stop");
        emp.setAge(38.0);
        System.out.println(emp);
        session.update("test.modify", emp);
        session.commit();
        session.close();
    }
    
    @Test
    public void test5() {
        session.delete("test.delete",7);
        session.commit();
        session.close();
    }
}

3.mybatis的基本原理

mybatis基本原理.png

4.返回Map类型的结果

mybatis会将查询结果先封装到一个Map对象里面(以字段名作为key,
以字段值作为vlaue),然后再将Map对象中的数据添加到实体对象里面。

在EmpMapper.xml文件中添加一段(只需要修改返回值类型即可)

    !-- 返回Map类型的结果 -->
    <select id="findById2" parameterType="int" resultType="map">
        SELECT * FROM emp WHERE id=#{id}
    </select>

TestCase测试类中测试代码

    @Test
    public void test6() {
        Map map = session.selectOne("test.findById2", 6);
        System.out.println(map);
        System.out.println(map.get("name"));    
    }

打印:
{name=white wolf, id=6, age=22}
white wolf

5.使用ResultMap,解决实体类的属性名与表的字段名不一致的情况。

    !-- 使用ResultMap解决表的字段名与实体类的属性名不一致的情况 -->
    <select id="findById3" parameterType="int" resultMap="emp2Map">
        SELECT * FROM emp WHERE id=#{id}
    </select>
    
    !-- 处理表的字段名与实体类的属性名的对应关系,列出不一样的即可 -->
    <resultMap type="entity.Emp2" id="emp2Map">
        <result property="eno" column="id"></result>
        <result property="ename" column="name"></result>
    </resultMap>

实体类参数
    private Integer eno;
    private String ename;
    private Double age;

数据库表字段:id,name,age

利用Mapper映射器接口

(1)什么是Mapper映射器?
符合映射文件的接口,mybatis会自动实现一个符合该接口要求的对象。

(2)Mapper映射器的要求:
    a.接口方法的名称与映射文件中的sql的id要一样。
    b.方法的参数类型要与映射文件当中的parameterType一致。
    c.方法的返回类型要与映射文件当中的resultType一致。
    此外,映射文件的namespace必须等于Mapper映射器的权限定名。
    
(3)编程步骤
    a.写一个映射器(即一个接口)
    b.调用SqlSession提供的getMapper方法。
    注:该方法会返回一个符合映射器要求的对象。

使用的还是上面的EmpMapper.xml文件

package dao;

import java.util.List;
import entity.Emp;

 * Mapper映射器
public interface EmpDAO {
    public void save(Emp emp);
    
    public List<Emp> findAll();
    
    public Emp findById(int id);
    
    public void modify(Emp emp);
    
    public void delete(int id); 
}
package test;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import dao.EmpDAO;
import entity.Emp;

public class TestCase {
    private SqlSession session;
    
    @Before
    public void init() {
        SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
        SqlSessionFactory ssf = ssfb.build(TestCase.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml"));
        session = ssf.openSession();
    }
    
    @Test
    public void test1() {

         * getMapper方法返回一个符合Mapper映射器(EmpDAO)要求的对象。
         * 动态代理
        EmpDAO dao = session.getMapper(EmpDAO.class);
        Emp emp = new Emp();
        emp.setName("json");
        emp.setAge(66.0);
        dao.save(emp);
         * 任然需要提交事务
        session.commit();
        session.close();
    }
    
    @Test
    public void test2() {
        EmpDAO dao = session.getMapper(EmpDAO.class);
        List<Emp> emps = dao.findAll();
        System.out.println(emps);
        session.close();
    }
    
    @Test
    public void test3() {
        EmpDAO dao = session.getMapper(EmpDAO.class);
        Emp emp = dao.findById(2);
        System.out.println(emp);
        session.close();
    }
    
    @Test
    public void test4() {
        EmpDAO dao = session.getMapper(EmpDAO.class);
        Emp emp = dao.findById(2);
        emp.setAge(22.0);
        dao.modify(emp);
        session.commit();
        session.close();
    }
    
    @Test
    public void test5() {
        EmpDAO dao = session.getMapper(EmpDAO.class);
        dao.delete(8);
        session.commit();
        session.close();
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,302评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,232评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,337评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,977评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,920评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,194评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,638评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,319评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,455评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,379评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,426评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,106评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,696评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,786评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,996评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,467评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,043评论 2 341