什么是mybatis?

(MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。)

        Mybatis它是个高轻量级半自动的持久层框架,它更加关注原生sql的编写。所以在实际项目中mybatis可以实现代码和sql的完全解耦。Mybatis还提供了强大的基于OGNL的动态sql语句编写它支持定制化 SQL、存储过程以及高级映射。所以深受广大程序员的喜爱。

 

Mybatis架构图

 

Mybatis学习利器

中文API: https://mybatis.org/mybatis-3/zh/getting-started.html

下载地址:https://github.com/mybatis/mybatis-3/releases

(解压以后导入对应的jar包~不过直接git下载还是比较慢……)

搭建mybatis的环境

新建Maven项目 和前几个项目一样

1、导入相关的依赖

第一项,配置pom文件,需要加入两个maven包,一个是数据库连接驱动,一个是mybatis

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.46</version>
</dependency>
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.5.0</version>
</dependency>  

2、resources目录下面 新建一个配置mybatis.xml文件,对应将自己的数据库放到链接池里面,并且可以设置映射的xml文件,有两种方式,mapper要每个文件都写上,package自动扫描包内的Mapper接口与配置文件。

<?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>
        <!--当返回行的所有列都是空时,MyBatis默认返回null-->
        <setting name="returnInstanceForEmptyRow" value="true"/>
	<!--显示sql语句-->
<setting name="logImpl" value="STDOUT_LOGGING"/>

    </settings>

    <environments default="development">

        <environment id="development">
            <!--使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域-->
            <transactionManager type="JDBC"/>
            <!-- mybatis提供了3种数据源类型,分别是:POOLED,UNPOOLED,JNDI -->
            <!-- POOLED 表示支持JDBC数据源连接池 -->
            <!-- UNPOOLED 表示不支持数据源连接池 -->
            <!-- JNDI 表示支持外部数据源连接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/gxa"/>
                <property name="username" value="root"/>
                <property name="password" value="root1234"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <!-- 映射文件方式1,一个一个的配置
        <mapper resource="com/gxa/mapper/UserMapper.xml"/>-->
        <!-- 映射文件方式2,自动扫描包内的Mapper接口与配置文件 -->
        <package name="com.gxa.mapper"/>
    </mappers>
</configuration>

3、新建pojo对象

package com.gxa.pojo;

import java.math.BigDecimal;
import java.util.Date;

public class Emp {
    private int emp_id;//变量名称与数据库的一致
    private String emp_name;
    private String emp_job;
    private int emp_mgr;
    private Date emp_hiredate;
    private BigDecimal emp_sal;
    private BigDecimal emp_comm;
    private int emp_deptno;

    public int getEmp_id() {
        return emp_id;
    }

    public void setEmp_id(int emp_id) {
        this.emp_id = emp_id;
    }

    public String getEmp_name(String mty) {
        return emp_name;
    }

    public void setEmp_name(String emp_name) {
        this.emp_name = emp_name;
    }

    public String getEmp_job() {
        return emp_job;
    }

    public void setEmp_job(String emp_job) {
        this.emp_job = emp_job;
    }

    public int getEmp_mgr() {
        return emp_mgr;
    }

    public void setEmp_mgr(int emp_mgr) {
        this.emp_mgr = emp_mgr;
    }

    public Date getEmp_hiredate() {
        return emp_hiredate;
    }

    public void setEmp_hiredate(Date emp_hiredate) {
        this.emp_hiredate = emp_hiredate;
    }

    public BigDecimal getEmp_sal() {
        return emp_sal;
    }

    public void setEmp_sal(BigDecimal emp_sal) {
        this.emp_sal = emp_sal;
    }

    public BigDecimal getEmp_comm() {
        return emp_comm;
    }

    public void setEmp_comm(BigDecimal emp_comm) {
        this.emp_comm = emp_comm;
    }

    public int getEmp_deptno() {
        return emp_deptno;
    }

    public void setEmp_deptno(int emp_deptno) {
        this.emp_deptno = emp_deptno;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "emp_id=" + emp_id +
                ", emp_name='" + emp_name + '\'' +
                ", emp_job='" + emp_job + '\'' +
                ", emp_mgr=" + emp_mgr +
                ", emp_hiredate=" + emp_hiredate +
                ", emp_sal=" + emp_sal +
                ", emp_comm=" + emp_comm +
                ", emp_deptno=" + emp_deptno +
                '}';

    }

    public Emp(int emp_id, String emp_name, String emp_job, int emp_mgr, Date emp_hiredate, BigDecimal emp_sal, BigDecimal emp_comm, int emp_deptno) {
        this.emp_id = emp_id;
        this.emp_name = emp_name;
        this.emp_job = emp_job;
        this.emp_mgr = emp_mgr;
        this.emp_hiredate = emp_hiredate;
        this.emp_sal = emp_sal;
        this.emp_comm = emp_comm;
        this.emp_deptno = emp_deptno;
    }
    public Emp() {
        super();
        // TODO Auto-generated constructor stub
    }
}

4、在java文件夹下,新建mapper->EmpMapper.xml的数据库映射文件,里面放置sql查询的语句。除了select还有insert等等语句都可以建。注意当调用参数的时候有些要注意传参数的格式,参数类型设置通过parameterType

<?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="com.gxa.mapper.EmpMapper">
    <select id="queryEmpList " resultType="com.gxa.pojo.Emp">
        select * from emp;
    </select>

</mapper>

6、新建EmpMapper.java,一定注意这里的查询时候的参数名称要和实体类Emp.java和数据库对应的名称一致,这样可以替代dao的功能

package com.gxa.mapper;

import com.gxa.pojo.Emp;
import org.apache.ibatis.annotations.Param;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;


public interface EmpMapper {
    List<Emp> queryEmpList();

    /**
     * 根据雇员编号查询雇员信息
     * @param
     * @return
     */
    List<Emp> queryEmpListByEmpno(int emp_id,int emp_mgr);
    List<Emp> queryEmpListByEmpno(String emp_name,String emp_job);
    List<Emp> queryEmpListByEmpno(int emp_id,String emp_name);
    List<Emp> queryEmpListByEmpno(Map map);
    List<Emp> queryEmpListByEmpno(Emp emp);

    List<Emp>  queryEmpByEnameAndComm(@Param("emp_name") String emp_name,@Param("emp_comm") BigDecimal comm);
    int insertEmp();
}

7、编写测试代码,新建一个Test文件夹里面(直接在项目文件夹下面)

public class MybatisTest {

    @Test
    public void test01() throws IOException {
        Reader reader = Resources.getResourceAsReader("mybatis.xml");//刚自己建好的xml
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = sqlSessionFactory.openSession();
        EmpMapper empMapper = session.getMapper(EmpMapper.class);
        List<Emp> empList = empMapper.queryEmpList();
        System.out.println(empList);

    }

(这里遇到了Cannot find class: com.mysql.jdbc.Driver的错误 是mybatis的jar包没有配置好的问题,getResourceAsReader一直爆红,依赖引入出问题也可以手动引入jar包)

结果可以现实语句和查询结果

新来的一些文件的结构,要比较注意的就是mybatis在resources目录下面,接口EmpMapper里面放了查询数据库的方法,通过在EmpMapper.xml的映射中id,得到调用,EmpMapper.xml里面放了具体的sql语句。数据库的链接在mybatis.xml里面实现,也要在里面映射到mapper文件夹里面的xml文件(有两种方式)。到此基本文件就搭建好咯。

PS:文件搭建好以后的其他重要内容

1、解决后台提示找不到对应xml文件

Idea默认找不到对应的xml配置路径,在pom文件的build标签中,加入resource标签如下代码:

<resources>
  <resource>
    <directory>src/main/java</directory>
    <includes>
      <include>**/*.xml</include>
    </includes>
  </resource>
</resources>

 

2、Xml配置方式的增删改查

首先配置mapper.xml文件

<!-- namespace一般定义为 包名+文件名 -->
<mapper namespace="com.gxa.mapper.UserMapper">
    <select id="selectUser" resultType="com.gxa.pojo.User">
      select * from user;
   </select>

    <insert id="insertUser" parameterType="com.gxa.pojo.User">
      insert into user values (#{id},#{username},#{password});
   </insert>

   <update id="updateUser" parameterType="com.gxa.pojo.User">
      update user set username=#{username},password=#{password} where id=#{id};
   </update>

   <delete id="deleteUser" parameterType="java.lang.String">
      delete from user where id=#{id};
   </delete>
</mapper>

 

然后再修改接口代码

public interface UserMapper {
    // 方法名、参数类型、返回类型要和mapper.xml文件中的id相同
    List<User> selectUser();
    void insertUser(User user);
    void updateUser(User user);
    void deleteUser(String id);
}

在控制器中调用接口中指定的四个方法,就可以完成基本的增删改查

多参数传递的方式

在项目中,多参数传递更多的是基于pojo对象,或者map结构传递,但是也可能有需要多个形式参数传递,比如下面不用的类型和解解决方式:

  • public List<Emp> queryParamListEmp (String ename,String job);
<select id="queryParamListEmp" parameterType="java.lang.String" resultType="com.gxa.pojo.Emp">
    select * from emp where ename = #{arg0} or job = #{arg1}
</select>

<select id="queryParamListEmp" parameterType="java.lang.String" resultType="com.gxa.pojo.Emp">
    select * from emp where ename = #{param1} or job = #{param2}
</select>
  • public List<Emp> queryParamListEmp (String job,double sal);
public List<Emp> queryParamListEmp (@Param("job ") String job, @Param("sal ") double sal);
//注意:@Param("字段名称 ")   字段的名称必须和sql语句中变量保持一致
  • public List<Emp> queryParamListEmp (Map map);
<select id="queryParamListEmp" parameterType="java.util.Map" resultType="com.gxa.pojo.Emp">
    select * from emp where job=#{job} and sal > #{sal}
</select>
  • public List<Emp> queryParamListEmp (Etity etity);
<select id="queryParamListEmp" parameterType="com.gxa.pojo.Emp" resultType="com.gxa.pojo.Emp">
    select * from emp where job=#{job} and sal > #{sal}
</select>

对应的结果参数的映射

<resultMap id="emp2" type="com.gxa.pojo.Emp2">
     <id property="no" column="empno"></id>
     <id property="name" column="ename"></id>
     <id property="job" column="job"></id>
     <id property="mgr" column="mgr"></id>
     <id property="hiredate" column="hiredate"></id>
     <id property="sal" column="sal"></id>
     <id property="comm" column="comm"></id>
     <id property="deptno" column="deptno"></id>
</resultMap>
<!--当出现表中的字段名和实体中的属性不一致的时候:返回的结果类型就应该用resultMap来进行封装-->
<select id="selectListEmp" resultMap="emp2">
    select * from emp
</select>

 

3、动态SQL的if使用

<select id="selectUser" resultType="com.gxa.pojo.User" parameterType="com.gxa.pojo.User">
      select * from user
   <if test="username != null">
      where username=#{username}
   </if>
</select>

在配置文件中添加动态的if语句,如果传递过来的user对象中,username不等于null,那么追加条件查询

 

4、动态SQLwhere使用

如果我们有多个条件需要添加,但是有可能一个条件都不满足,那么这时候使用上面的方式就会出现问题,所以我们还需要在if外部添加一个where标签

<select id="selectUser" resultType="com.gxa.pojo.User" parameterType="com.gxa.pojo.User">
      select * from user
   <where>
      <if test="username != null">
         username=#{username}
      </if>
      <if test="password != null">
         and password=#{password}
      </if>
   </where>
</select>

可以看到,where包含了两个if,而第一个if中没有and,where标签会自动检查状态,如果标签返回的第一个匹配内容是以 and或or 开头的,则会自动删除and或者or ,然后再追加where

 

5、动态SQLchoose  when otherwise使用

<select id="selectUser" resultType="com.gxa.pojo.User" parameterType="com.gxa.pojo.User">
      select * from user where password='888888'

<where>
   <choose>
      <when test="username != null">
         AND username=#{username}
      </when>
      <when test="password != null">
         AND password=#{password}
      </when>
      <otherwise>
         AND id=#{id}
      </otherwise>
   </choose>

<where>
</select>

Choose when 类似于java中的switch case,任中只会走一个,一般是在有一个条件固定的情况下,需要额外不确定的条件时,使用choose的方式

6、动态SQLset的使用

注意:set是检查去掉参数后的逗号

<update id="updateEmp" parameterType="Emp">
    update emp
    <set>
        <if test="ename != null">
            ename = #{ename},
        </if>
        <if test="job != null">
            job = #{job},
        </if>
    </set>
    where empno=#{empno}
</update>

<select id="selectInEmp" parameterType="java.util.List" resultType="Emp">
    select * from emp where empno in
    <foreach item="item" index="index" collection="list"
             open="(" separator="," close=")">
        #{item}
    </foreach>
</select>

 

7、动态SQLforeach的使用


Reader reader = Resources.getResourceAsReader("mybatis/mybatis.xml");
 //创建一个SqlSessionFactory工厂
 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
 SqlSession sqlSession = sqlSessionFactory.openSession();
 EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
 List<Integer> empnos = new ArrayList<>();
 empnos.add(7566);
 empnos.add(7654);
 empnos.add(7698);
 List<Emp> list = mapper.selectInEmp(empnos);
for (Emp e : list){
    System.out.println(e.getEname());
}

 

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐