Mybatis基础入门

一、Mybatis简介

Mybatis是一款经典的ORM(对象关系映射)框架, Mybatis避免 了传统JDBC操作中设置参数、手动封装结果集等冗余的操作。可以使用简单的XML或注解完成对数据库的操作。相较于其他ORM框架,Mybatis支持定制SQL, 更容易学习。
可以使用Mybatis对数据库进行CRUD操作、结果集映射、动态SQL、缓存、与Spring框架整合以及逆向工程简化开发。

 

二、环境搭建

1、创建maven工程

2、导入jar包

配置pom.xml

    <dependencies>
        <!-- mybatis核心包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!-- mysql驱动包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.29</version>
        </dependency>
        <!-- junit测试包 开发中不用导入-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
        <!--日志包,方便看sql语句-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.1</version>
        </dependency>
    </dependencies>
    <build>
        <resources>
            <!--默认编译resource下的配置文件不会编译java下的,这个配置以后就会执行-->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <!--设置了编译resource下的配置文件不会再编译resource下的,默认配置需要显示写出来-->
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>
        </resources>
    </build>

3、创建实体类

部门类

package pojo;
import java.util.List;

public class Dept {
   
    private Integer id;
    private String name;
    private List<Employee> employees;
    //getter and setter方法略
}

员工类

package pojo;
import java.util.Date;

public class Employee {
   
    private Integer id;//id
    private String name;//姓名
    private Dept dept;//部门
    private String job;//职位
    private Float salary;//薪水
    private Date hireDate;//入职日期
	 //getter and setter方法略
}

4、创建表

部门表并添加数据

CREATE TABLE IF NOT EXISTS dept(id INT PRIMARY KEY,name VARCHAR(30));

INSERT INTO dept VALUES(1,"产品部");
INSERT INTO dept VALUES(2,"设计部");
INSERT INTO dept VALUES(3,"开发部");
INSERT INTO dept VALUES(4,"测试部");
INSERT INTO dept VALUES(5,"运营部");
INSERT INTO dept VALUES(6,"销售部");
INSERT INTO dept VALUES(7,"财务部");
INSERT INTO dept VALUES(8,"人事部");
INSERT INTO dept VALUES(9,"行政部");

员工表并添加数据

CREATE TABLE IF NOT EXISTS employee(
id INT PRIMARY KEY,
name VARCHAR(30),
dept_id INT,
job VARCHAR(30),
salary FLOAT,
hire_date DATE,
CONSTRAINT foreign key(dept_id) references dept(id)
);

INSERT INTO employee VALUES(1,"张三",1,"产品总监",29999,"2000-01-01");
INSERT INTO employee VALUES(2,"李四",3,"开发工程师",16000,"2015-01-01");
INSERT INTO employee VALUES(3,"王五",4,"测试工程师",12000,"2016-07-01");
INSERT INTO employee VALUES(4,"赵六",6,"销售",8000,"2000-01-01");
INSERT INTO employee VALUES(5,"张三",8,"人事经理",15000,"2016-01-01");

5、创建Mapper映射文件

在dao.mapper下面创建实体类映射文件DeptMapper.xml和EmployeeMapper.xml,两个文件只是mapper节点namespace值不一样,一个工程中namespace值要唯一,通常一个Mapper文件对应一张表的增删改查,namespace可以设置成表名。
空的Mapper映射文件如下:

<?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="DEPT">
    <!--<![CDATA[你的注释]]>-->
</mapper>

注意:Mapper文件如果要写中文注释,需要用<![CDATA[]]>将中文注释包起来,否则运行时会报编码错误。或者把工程的文件编码设置成UTF-8。

IDEA设置编码两种方式:
1)、File->Settings->Editor->File Encodings这种方式修改的文件编码方式只对当前project起作用,每次新建了一个工程后还需要重新设置编码方式。
2)、File->Other Settings->Default Settings->Editor->File Encodings,这儿设置的是默认的文件编码方式,所有新建的工程使用的都是默认的文件编码方式。

6、创建配置文件

mybatis配置文件mybatis-config.xml如下:
注意configuration中节点的位置是有先后顺序,写错了会看到提示。

<?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>
    <typeAliases>
    <!-- 类型别名,表示可以使用 Dept 来代替 pojo.Dept -->
    <!-- 类型别名就是可以给类的全路径起一个简称 -->
    <typeAlias type="pojo.Dept" alias="Dept"/>
    <typeAlias type="pojo.Employee" alias="Employee"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 数据库连接信息 -->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!--实体类的映射文件,在dao.mapper包下创建完Mapper文件后在此追加即可-->
    <mappers>
        <mapper resource="dao/mapper/DeptMapper.xml"/>
        <mapper resource="dao/mapper/EmployeeMapper.xml"/>
    </mappers>
</configuration>

7、添加log4j日志文件

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 %p [%c] - %m%n
        
#begin
#for normal test, delete when online
log4j.logger.com.ibatis=DEBUG
1og4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
1og4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
1og4j.logger.java.sql.Connection=DEBUG
1og4j.logger.java.sql.Statement=DEBUG
1og4j.logger.java.sql.PreparedStatement=DEBUG
1og4j.1ogger.java.sq1.ResultSet=DEBUG
#end

 

三、使用Mybatis进行增删改

使用Mybatis操作数据库,需要将SQL 写在Mapper映射文件中。sql语句封装到标签中,对应增删改查的操作,有四种标签

<insert>用于执行insert插入数据
<delete>用于执行delete删除数据
<update>用于执行update修改数据
<select>用于执行select查询数据

每个标签都有一个id属性, 在同一个Mapper文件中,每条语句的id都是唯一的,在执行语句的时候,通过namespace.id来调用语句。 sql语句中需要传入参数的时候,通过parameterType指定参数的类型,可以是基本数据类型,也可以是封装好的类或集合。通过#属性}或${属性}来得到参数值。
 

1、添加数据

以DEPT表为例。所有的语句都写在XXMapper.xml的节点中。 在Mybatis中,添加数据使用insert标签:

<mapper namespace="DEPT">
    <!--parameterType指定传入参数的类型-->
    <insert id="addDept" parameterType="Dept" keyProperty="id" useGeneratedKeys="true">
        insert into DEPT(name) values (#{name})
    </insert>
</mapper>

此标签对应生成的语句是: insert into DEPT (NAME) values (?)
parameterType="Dept"指定了调用语句时,传入的参数是Dept类型的,#{name}会获取到Dept对象中的name属性值,并在执行时替换掉语句中的?占位。

insert标签属性说明:
1)、 id在同一个Mapper文件中,每条语句的id都是唯一的, 在执行语句的时候,通过namespace.id来调用语句。
2) 、parameterType是指参数类型,sql语句执行的时候需要绑定参数,通常我们将参数封装到实体类中。parameterType的值可以是类的全路径如pojo.Dept,也可以是mybatis-config.xml文件中typeAlias中配置的别名alias。
3) 、keyProperty仅对insert有用,标记一个属性, MyBatis 会通过getGeneratedKeys或者通过insert 语句的selectKey 子元素设置它的值。默认:不设置。当添加完数据后, 如果想获得到刚刚添加的这条数据的主键,同时设置keyProperty和useGeneratedKeys即可。
4)、useGeneratedKeys仅对insert语句有用,告诉MyBatis使用JDBC的getGeneratedKeys方法来取出由数据(比如:像MySQL和sQLServer这样的数据库管理系统的自动递增字段)内部生成的主键。默认值: false。

测试代码:

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 pojo.Dept;

import java.io.IOException;
import java.io.Reader;

public class InsertTest {
   
    @Test
    public void testInsert(){
   
        String resource="mybatis-config.xml";//配置文件名
        Reader reader = null;//读取配置文件的工具
        SqlSession session = null;
        try {
   
            //使用MyBatis提供的Resources类加载配置文件
            reader = Resources.getResourceAsReader(resource);
            //创建sqlSession的工厂对象
            SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
            //创建能执行映射文件中sql的sqlSession对象
            session = sessionFactory.openSession();
            //创建要insert到数据库中的实体类对象
            Dept dept = new Dept();
            dept.setName("新媒体");
            //使用session的insert方法执行添加操作
            //第一个参数是Mapper文件的namespace和语句的id
            //第二个参数的类型和语句的parameterType一致
            session.insert("DEPT.addDept",dept);
            session.commit();//增删改要提交事务
            System.out.println(dept.getId());//获取主键
        } catch (IOException e) {
   
            e.printStackTrace();
            session.rollback();//有异常事务回滚
        } finally {
   //关闭资源
            if(session!=null){
   
                session.close();
            }
            try {
   
                if (reader!=null) {
   
                    reader.close();
                }
            } catch (IOException e) {
   
                e.printStackTrace();
            }
        }
    }
}

运行结果:
在这里插入图片描述
为了简化代码,把打开连接和关闭连接封装到@Before@After

    String resource="mybatis-config.xml";//配置文件名
    Reader reader = null;//读取配置文件的工具
    SqlSession session = null;

    @Before
    public void open(){
   
        try {
   
            //使用MyBatis提供的Resources类加载配置文件
            reader = Resources.getResourceAsReader(resource);
            //创建sqlSession的工厂对象
            SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
            //创建能执行映射文件中sql的sqlSession对象
            session = sessionFactory.openSession();
        } catch (IOException e) {
   
            e.printStackTrace();
        }
    }
    @After
    public void close(){
   
            if(session!=null){
   
                session.close();
            }
            try {
   
                if (reader!=null) {
   
                    reader.close();
                }
            } catch (IOException e) {
   
                e.printStackTrace();
            }
        }

简化后的测试方法

    @Test
    public void testInsert(){
   
        try {
   
            Dept dept = new Dept();
            dept.setName("研发部");
            session.insert("DEPT.addDept",dept);
            session.commit();//增删改要提交事务
            System.out.println(dept.getId());//获取主键
        } catch (Exception e) {
   
            e.printStackTrace();
            session.rollback();//有异常事务回滚
        }
    }

 

2、修改数据

    <update id="updateDept" parameterType="Dept">
        update DEPT set name=#{name} where id=#{id}
    </update>

测试代码:

    @Test
    public void testUpdate(){
   
        try {
   
            Dept dept = new Dept();
            dept.setId(13);
            dept.setName("市场部");
            int res = session.update("DEPT.updateDept", dept);
            System.out.println(res);
            session.commit();
        } catch (Exception e) {
   
            e.printStackTrace();
            session.rollback();
        }
    }

 

3、删除数据

    <delete id="deleteDept" parameterType="int">
        delete from dept where id=#{id}
    </delete>

delete根据主键查询,Dept主键 是Integer的。没有必要封装进类里,上面的语句中parameterType="int”,其中int是Integer的别名。
Mybatis默认的对基本数据类型都有起了别名。基本数据类型的参数,直接写类型或者类名小写即可。比如java.lang.Integer别名有Integer、integer、int虽然不是对象类型,但是int可以自动转化成Integer.语句中使用了#{id}获取具体的参数值,但是int类型中并没有一个叫id的属性。可是测试发现语句仍然能执行成功。所以在parameterType=”基本数据类型”的时候,可以通过#任意名称}获得参数值。这里将#{id}写成#{abc}也可以。

测试代码:

    @Test
    public void testDelete(){
   
        try {
   
            int res = session.delete("DEPT.deleteDept", 41);
            System.out.println(res);
            session.commit();
        } catch (Exception e) {
   
            e.printStackTrace();
            session.rollback();
        }
    }

 

四、Mybatis数据查询

 

1、直接查询

属性通过对象属性名映射到实体类,用resultType要求结果集的字段名(有别名以别名为准)和实体类的属性名一致才能映射,否则无法映射。

    <select id="getDeptList" resultType="Dept">
        select id,name from dept
    </select>

测试代码:

    @Test
    public void testGetDeptList(){
   
        List<Dept> Depts = session.selectList("DEPT.getDeptList");
        for(Dept dept:Depts){
   
            System.out.println(dept);
        }
    }

 

2、查询结果的映射

Mybatis通过<select>进行查询。通过<resultMap>将查询结果封装成实体类:

    <resultMap id="empMap" type="Employee">
        <!-- id是主键标签 -->
        <!--  property是类名的属性,column是类名查询出来的字段 -->
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="dept.id" column="dept_id"/>
        <result property="dept.name" column="dname"/>
        <result property="job" column="job"/>
        <result property="salary" column="salary"/>
        <result property="hireDate" column="hire_Date"/>
    </resultMap>
    <select id="getEmpList" resultMap="empMap">
        select id,name,dept_id,job,salary,hire_Date from employee
    </select>

<resultMap>用于封装结果集。一个Mapper中可以有多个<resultMap>,每个<resultMap>的id是唯一-的。 type用于指定结果集对应的实体类类型。type=“Dept” 即将<resultMap>中所有的属性都对应到Dept类中。

我们可以这样理解,一个查询语句,从查询出结果,到封装成实体类,经历如下步骤:
1.当使用<select>查询出结果后,会根据<select>中resultMap="deptMap"找到id="deptMap"的<resultMap>标签
2.根据<resultMap> 的type="Dept"找到Dept对应的类,这里Dept是别名,也可以写成全路径pojo.Dept。
3. <resultMap> 中的<result>标签,将查询结果中的字段与实体类中的属性对应起来,property="name” 是找到Dept类中的name属性,column="NAME”中NAME是SQL语句中NAME字段对应的值,通过setName方法将结果集绑定到name属性上。
需要注意的是column="NAME"中的NAME不是数据库中的字段名,而是select语句中查询出来的字段别名,因为我们可以用as去给字段起别名。如上面改变上面的语句,为查询结果起别名,对应的column也要改变
测试代码:

    @Test
    public void testEmplist(){
   
        List<Employee> list = session.selectList("EMPLOYEE.getEmpList");
        for(Employee employee:list){
   
            System.out.println(employee);
        }
    }

session.selectList适用于查询结果是一个集合的情况,如果实现按主键
查询,则使用session.selectOne方法。 如按主键查询:

<select id="getDeptById" parameterType="int' resultMap= " deptMap">
select ID, NAME from DEPT where ID=#{
   id}
</select>

测试代码:

@Test
public void testSelectOne() {
   
Dept dept = session.selectOne( "DEPT. getDeptById", 21);
System.out.println( dept.getName()) ;

resultMap还支持继承:

    <resultMap id=" deptMap" type="Dept">
        <id column="ID" property="id"/>
        <result column="NAME" property="name"/>
    </resultMap>
    <resultMap id="deptMapChild" type= 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值