mybatis入门教程

本着一切以官方文档为准的原则,快速入门参考了官方文档给的例子
mybatis官方文档地址

1 快速入门

目录结构
在这里插入图片描述

1.1 在项目中引入mybatis依赖包

使用maven构建的项目在pom文件中加入mybatis需要的dependency

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.4.6</version>
</dependency>

1.2 mybatis全局配置文件

每一个Mybatis应用是以一个SqlSessionFactory为中心,SqlSessionFactory实例可以由SqlSessionFactoryBuilder解析xml配置文件来初始化。
全局配置mybatis-config.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>
    <!--
    数据库环境配置,如果和spring整合了就不需要配了,完全交给spring管理
    environments 里面可以配置多个environment default:指定采用哪个环境
   -->
    <environments default="development">
        <environment id="development">
            <!--事务管理器  JDBC类型的事务管理器-->
            <transactionManager type="JDBC"/>
            <!--数据源  池类型的数据源-->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--管理每一张表的映射文件 -->
    <mappers>
        <mapper resource="mapper/PersonMapper.xml"/>
    </mappers>
</configuration>

PersonMapper.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">

<!--
 namespace:命名空间,映射文件的命名空间,可以任意取,保证唯一
-->
<mapper namespace="PersonMapper">

    <!--
     id:sql唯一标识
     paramterType : 传递给sql语句的参数
     resultType: 返回数据结果的类型
     #{id} : 用于接收参数的语法,如果是接收一个参数{}里面的内容任意
    -->
    <select id="selectPersonById" parameterType="java.lang.Integer" resultType="com.mybatisDemo.model.Person">
    	select * from person where id = #{id}
    </select>
</mapper>

1.3 测试代码
实体类Person.class

package com.mybatisDemo.model;

public class Person {

    private String name;

    private Integer age;

    private Integer gender;

    private String addr;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender=" + gender +
                ", addr='" + addr + '\'' +
                '}';
    }
}

数据库准备测试数据,新建person表 插入几条测试数据

1.3 测试代码

import com.mybatisDemo.model.Person;
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 java.io.InputStream;

public class MybatisTest {

    public static void main(String[] args) throws Exception {
        //指定配置文件
        String resource = "mybatis-config.xml";
        //读取配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //通过配置文件构建SqlSessionFactory
        SqlSessionFactory sqlSessionFactory =
                new SqlSessionFactoryBuilder().build(inputStream);
        //获取SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            //执行查询操作
            //第一个参数:命名空间+statementId  第二个参数为传入参数 这里为人员id
            Person person = sqlSession.selectOne("PersonMapper.selectPersonById", 1);

            System.out.println(person);
        } finally {
            sqlSession.close();
        }

    }
}

运行结果:
运行结果
以上就完成了使用mybatis实现的简单查询。

2 mybatis的CRUD

2.1 < resultMap > 标签

在上面的例子中,resultType指定为com.mybatisDemo.model.Person,此时Person实体类中的属性名和数据库person表中的字段名完全对应,此时能够将查询结果注入到Person之中。但是实际项目中往往属性名和表字段名不能完全对应,此时就需要使用< resultMap > 标签来定义对应关系。
下面例子中person表字段名变更为person_id,person_name,person_age,gender,addr

Person类属性名采用驼峰命名

package com.mybatisDemo.model;

public class Person {

    private Integer personId;

    private String personName;

    private Integer personAge;

    private Integer gender;

    private String addr;


    @Override
    public String toString() {
        return "Person{" +
                "personId=" + personId +
                ", personName='" + personName + '\'' +
                ", personAge=" + personAge +
                ", gender=" + gender +
                ", addr='" + addr + '\'' +
                '}';
    }
}

修改PersonMapper.xml文件,使用resultMap来对应字段名称

<?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="PersonMapper">
    <!--
         resultMap:组装从数据库表中查询出来的实体
         type:实体的数据类型
         id:唯一标识
     -->
    <resultMap id="BaseResultMap" type="com.mybatisDemo.model.Person">
        <!--
          id列只有一个
          column:表的字段名
          property:实体类属性名
        -->
        <id column="person_id" property="personId"></id>
        <result column="person_name" property="personName"></result>
        <result column="person_age" property="personAge"></result>
        <result column="gender" property="gender"></result>
        <result column="addr" property="addr"></result>
    </resultMap>

    <!--
         id:sql唯一标识
         paramterType : 传递给sql语句的参数
         resultType: 返回数据结果的类型
         #{id} : 用于接收参数的语法,如果是接收一个参数{}里面的内容任意
    -->
    <select id="selectPersonById" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select * from person where person_id = #{id}
  </select>
</mapper>

2.2 查询列表

package com.mybatisDemo.test;

import com.mybatisDemo.model.Person;
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.Before;
import org.junit.Test;

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

public class MybatisTest {

    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void init() {
        //指定配置文件
        String resource = "mybatis-config.xml";
        //读取配置文件
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //通过配置文件构建SqlSessionFactory
        sqlSessionFactory =
                new SqlSessionFactoryBuilder().build(inputStream);
    }


    @Test
    public void selectPersonList() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<Person> personList;
        try {
            //查询列表
            personList = sqlSession.selectList("PersonMapper.selectPersonList", 5);
            for (Person person : personList) {
                System.out.println(person);
            }
            
        } finally {
            sqlSession.close();
        }
    }


}

 	<select id="selectPersonList" resultMap="BaseResultMap">
        select * from person limit #{limit}
    </select>

2.3 多个查询条件

多个查询参数的传递有两种方式:1.传递查询对象 2:传递map集合
1.传递参数对象

	 <!--
         多个参数查询
         第一种方式:传递查询对象
         #{}中的内容为查询对象属性名
     -->
    <select id="selectPersonByCondition" parameterType="com.mybatisDemo.model.Person" resultMap="BaseResultMap">
       <![CDATA[ select * from person p where p.gender = #{gender} and p.person_age < #{personAge}]]>
    </select>
    @Test
    public void selectPersonByCondition() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            Person condition = new Person();
            condition.setGender(1);
            condition.setPersonAge(28);
            List<Person> personList = sqlSession.selectList("PersonMapper.selectPersonByCondition", condition);
            for (Person person : personList) {
                System.out.println(person);
            }

        } finally {
            sqlSession.close();
        }
    }

2.传递map

    <!--
        多个参数查询
        第二种方式:使用map集合
        map.put(key,value) #{}中内容为map的key
    -->
    <select id="selectPersonByMap" parameterType="map" resultMap="BaseResultMap">
       <![CDATA[ select * from person p where p.gender = #{gender} and p.person_age < #{personAge}]]>
    </select>
 	@Test
    public void selectPersonByMap() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("gender", 1);
            map.put("personAge", 25);
            List<Person> personList = sqlSession.selectList("PersonMapper.selectPersonByMap", map);
            for (Person person : personList) {
                System.out.println(person);
            }

        } finally {
            sqlSession.close();
        }
    }

2.4 模糊查询 #{}和${}

    <!--
         模糊查询
         ${}:非预编译,使用直接拼接字符串的方式生成sql  ${}中的内容必须从map或者参数对象中获得
    
     -->
    <select id="selectPersonByLike" parameterType="map" resultMap="BaseResultMap">
        select * from person p where p.person_name like '%${personName}%'
    </select>
  @Test
    public void selectPersonByLike(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("personName", "李");
            List<Person> personList = sqlSession.selectList("PersonMapper.selectPersonByLike", map);
            for (Person person : personList) {
                System.out.println(person);
            }

        } finally {
            sqlSession.close();
        }
    }

2.5 insert

    <insert id="insertPerson" parameterType="com.mybatisDemo.model.Person">
        insert into person (person_name,person_age,gender,addr) values (#{personName},#{personAge},#{gender},#{addr})
    </insert>
    @Test
    public void insertPerson() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            Person person = new Person();
            person.setPersonName("宋祖英");
            person.setPersonAge(29);
            person.setGender(2);
            person.setAddr("湖南");
            sqlSession.insert("PersonMapper.insertPerson", person);
            sqlSession.commit();

        } finally {
            sqlSession.close();
        }
    }

数据变更都需要调用sqlSession.commit()提交事务。
person表中主键person_id是自增的,想要在插入数据之后返回主键id,需修改PersonMapper.xml

	<insert id="insertPerson" parameterType="com.mybatisDemo.model.Person">
      <!--
            selectKey标签用作主键返回
            keyProperty:接收返回的主键的属性
            order:生成主键和insert语句的顺序   mysql是after  orcal 是before
            resultType:返回主键的数据类型
            last_insert_id() 生成主键的sql
      -->
      <selectKey  keyProperty="personId" order="AFTER" resultType="java.lang.Integer">
          select last_insert_id()
      </selectKey>
        insert into person (person_name,person_age,gender,addr) values (#{personName},#{personAge},#{gender},#{addr})
    </insert>

2.6 delete

	 <!--delete sql语句中不能使用别名-->
    <delete id="deletePersonById" parameterType="java.lang.Integer">
        delete from person  where  person_id = #{personId}
    </delete>
	@Test
    public void deletePersonById() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            sqlSession.delete("PersonMapper.deletePersonById", 12);
            sqlSession.commit();

        } finally {
            sqlSession.close();
        }
    }

2.7 update

	<update id="updatePerson" parameterType="com.mybatisDemo.model.Person">
         update person p set
            p.person_name = #{personName},
            p.person_age = #{personAge},
            p.gender = #{gender},
            p.addr = #{addr}
          where
            p.person_id = #{personId}
    </update>
 	@Test
    public void updatePerson() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            Person person = new Person();
            person.setPersonId(11);
            person.setPersonName("宋祖德");
            person.setPersonAge(30);
            person.setGender(1);
            person.setAddr("南京");
            sqlSession.update("PersonMapper.updatePerson", person);
            sqlSession.commit();
            System.out.println(person);

        } finally {
            sqlSession.close();
        }
    }

这里存在一个问题,如果传入参数person的personName、personAge、gender、addr值为null,即我们只想修改地址信息。若使用上面的sql语句,会在数据库中把person_name、person_age、gender、addr更新为null,达不到我们想要的目的。

为了解决这个问题,我们需要用到动态sql

2.8 动态sql

2.8.1 < set > 标签 动态修改

	<!--
     使用<set>标签动态修改  能处理掉最后一个逗号
    -->
	<update id="dynamicUpdate" parameterType="com.mybatisDemo.model.Person">
        update person p
        <set>
            <if test="personName != null">
              p.person_name = #{personName},
            </if>
            <if test="personAge != null">
                p.person_age = #{personAge},
            </if>
            <if test="gender != null">
                p.gender = #{gender},
            </if>
            <if test="addr != null">
                p.addr = #{addr},
            </if>
        </set>
        where p.person_id = #{personId}
    </update>

2.8.2< where > 动态查询

使用< where >标签进行动态条件组合查询 可以处理掉where后面的第一个and

	<select id="dynamicSelect" parameterType="com.mybatisDemo.model.Person" resultMap="BaseResultMap">
        select * from person p
        <where>
            <if test="personId != null">
                p.person_id = #{personId}
            </if>
            <if test="personName != null">
                and p.person_name = #{personName}
            </if>
            <if test="personAge != null">
                and p.person_age = #{personAge}
            </if>
            <if test="gender != null">
                and p.gender = #{gender}
            </if>
            <if test="addr != null">
                and p.addr = #{addr}
            </if>
        </where>

    </select>

2.9 foreach 遍历组装sql

2.9.1 in条件查询

如果我们有一条sql:SELECT * FROM person where person_id in (1,2,7,8),怎样用mybatis来完成查询?
< foreach > 可以帮助我们完成遍历传入的参数,完成sql组装:

  <!--
       foreach遍历集合来组装sql
       map.put("ids",List or Set or 数组)
       collection:在map中集合的key;
       open:以某种字符开始
       close: 以某种字符结尾
       item: 集合中的元素
       separator:以某种字符分隔
       index:当前所遍历到的索引号
   -->
    <select id="selectPersonByIn" parameterType="map" resultMap="BaseResultMap">
        select * from person p where person_id in
        <foreach collection="ids" open="(" close=")" item="id" separator="," index="index">
            #{id}
        </foreach>
    </select>

在这里插入图片描述

2.9.2 批量insert

例sql语句:insert into person (person_name,person_age,gender,addr) values (‘刘德华’,‘45’,‘1’,‘香港’),(‘周杰伦’,‘38’,‘1’,‘台湾’),(‘邓紫棋’,‘28’,‘2’,‘香港’)

 <!--
      批量插入
      map.put(studentList,List<Student>)
      insert into student (s_name,s_age) valus (aaa,15),(bbb,16),(ccc,20).......
    -->
    <insert id="insertPersonList" parameterType="map">
        insert into person (person_name,person_age,gender,addr) values
        <foreach collection="personList" item="p" separator=",">
            (#{p.personName},#{p.personAge},#{p.gender},#{p.addr})
        </foreach>
    </insert>

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值