MyBatis就是这么简单(一)

文件的目录结构如下(下面的代码可以直接复制到你idea上运行,我的详细解释都在代码注释中)

在这里插入图片描述

第一步: 配置pom依赖

<?xml version="1.0" encoding="UTF-8"?>
<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.zuoyueer</groupId>
    <artifactId>Mybatis_day_01</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <!--单元测试坐标-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
            <scope>runtime</scope>
        </dependency>
        <!--myBatis坐标-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <!--日志的坐标-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
    </dependencies>
</project>

第二步:创建javaBean和初始化数据库

javaBean如下

package com.zuoyueer.domain;

import java.io.Serializable;

/**
 * @author Zuoyueer
 * Date: 2019/11/15
 * Time: 21:47
 * @projectName Framework
 * @description: javabean
 */
public class User implements Serializable {
    private int uid;
    private String username;
    private String sex;
    private String birthday;
    private String address;

   //为了篇幅考虑,省略了get/set方法以及toString方法
}
package com.zuoyueer.domain;

import java.io.Serializable;

/**
 * @author Zuoyueer
 * Date: 2019/11/16
 * Time: 10:56
 * @projectName Framework
 * @description: 条件搜索的javabean封装搜索条件,属性中包含其他javaBean的引用
 */
public class QueryVo implements Serializable {
    private int id;
    private User user;
    private String  other;

 	//为了篇幅考虑,省略了get/set方法以及toString方法
}

数据库脚本如下

CREATE DATABASE mybatis;
USE mybatis;
CREATE TABLE t_user(
		uid INT PRIMARY KEY AUTO_INCREMENT,
		username VARCHAR(40),
	 	sex VARCHAR(10),
		birthday DATE,
		address VARCHAR(40)
);
INSERT INTO `t_user` VALUES (NULL, '张三', '男', '2018-08-08', '北京');
INSERT INTO `t_user` VALUES (NULL, '李四', '女', '2018-08-30', '武汉');
INSERT INTO `t_user` VALUES (NULL, '王五', '男', '2018-08-08', '北京');

## t_user_表是为了测试表的列名和jopo的属性名不一致的情况下怎么处理,所以才创建了t_user_这个表
CREATE TABLE t_user_(
		uid_ INT PRIMARY KEY AUTO_INCREMENT,
		username_ VARCHAR(40),
	 	sex_ VARCHAR(10),
		birthday_ DATE,
		address_ VARCHAR(40)
);
INSERT INTO `t_user_` VALUES (NULL, '张三', '男', '2018-08-08', '北京');
INSERT INTO `t_user_` VALUES (NULL, '李四', '女', '2018-08-30', '武汉');
INSERT INTO `t_user_` VALUES (NULL, '王五', '男', '2018-08-08', '北京');

第三步: 写DAO的接口,接口中声明方法

package com.zuoyueer.dao;

import com.zuoyueer.domain.QueryVo;
import com.zuoyueer.domain.User;

import java.util.List;

/**
 * @author Zuoyueer
 * Date: 2019/11/15
 * Time: 21:56
 * @projectName Framework
 * @description: dao的接口
 */
public interface UserMapper {
    /**
     * 查询全部用户
     */
    List<User> findAll();

    /**
     * 添加用户
     */
    void insert(User user);

    /**
     * 修改用户
     */
    void update(User user);

    /**
     * 删除用户
     */
    void delete(int uid);

    /**
     * 模糊查询,名字的模糊查询
     */
    List<User> findByName(String username);

    /**
     * 多条件查询 ,复杂条件,条件可选
     */
    List<User> findByQueryVo(QueryVo queryVo);

    /**
     * 获取记录的总数
     */
    int countOfAllUser();

    /**
     * 根据uid条件查询总数
     *
     * @return
     */
    int countOfUserByUid(int uid);

    /**
     * 根据id和名字查询用户
     */
    User findUserByIdAndName(User user);

    /**
     * 根据id和名字查询,但是数据库中的字段和pojo的属性名不一致
     */
    User findUserById(User user);
}

第四步:写配置文件和映射文件

UserMapper接口的映射文件UserMapper.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="com.zuoyueer.dao.UserMapper">
    <!--
    id: 值必须对应接口中的方法名,也是唯一的,
    resultType: 表示sql语句的返回类型,值必须是返回类型的权限定类名,
                如果是简单数据类型,可以直接写,比如: int, String,Integer等
                如果是集合,那么返回类型是该集合的泛型,也就是集合中存储的数据的类型,也是写权限定类名
    -->
    <!--<select id="findAll"  resultType="com.zuoyueer.domain.User">-->
    <select id="findAll" resultType="User">
        select * from t_user;
    </select>

    <!--
        #{}表示占位符,#{}里面的值是void insert(User user)方法传入参数User对象是属性名
        parameterType:  表示规定了insert方法传入参数的类型,也是写权限定类名,如果取了别名,可以用别名
        parameterType可以省略不写,省略的不写,#{}里面的值就按照传入的参数对象的属性名
    -->
    <insert id="insert" parameterType="com.zuoyueer.domain.User">
        <!--
         下面的整个selectKey表示:将插入数据的主键返回到User对象中的uid属性中

         SELECT_LAST_INSERT_ID(): 表示获取最后插入的记录的ID(主键),是一个函数
         keyProperty: 将得到的主键值,设置到parameterType指定对象的某一个属性里,下面的示例设置到User对象的uid属性里
         resultType: 这个很好理解,就是指定执行函数的返回类型,示例是SELECT_LAST_INSERT_ID()的返回类型
         order: 指定函数的执行顺序,AFTER表示在insert语句之后执行,还有另外一个值是BEFORE表示在insert语句之前执行
         -->
        <selectKey resultType="int" keyProperty="uid" order="AFTER">
            select last_insert_id()
        </selectKey>

        insert into t_user values (null,#{username},#{sex},#{birthday},#{address})
    </insert>
    <!--
        因为一个命名空间中id不能重复,否则包错Mapped Statements collection already contains value,于是,我把第二种方式注释起来了

        返回主键值的第二种方式: 配置这keyProperty="uid" useGeneratedKeys="true"两个属性.
        keyProperty:和上面的意义一样
        useGeneratedKeys:设置是否使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中

        <insert id="insert" parameterType="com.zuoyueer.domain.User" keyProperty="uid" useGeneratedKeys="true">
            insert into t_user values (null,#{username},#{sex},#{birthday},#{address})
        </insert>
    -->

    <update id="update" parameterType="User">
            update t_user set username=#{username},sex=#{sex} where uid=#{uid}
    </update>

    <delete id="delete" parameterType="int">
        <!-- #{xxx} 是没有约束的,就是传递来的一个值,使用随便命名,不能为空#{},里面随便写一个名字就行 -->
        DELETE FROM t_user WHERE uid = #{xxx}
    </delete>


    <!--  <select id="findByName" parameterType="String" resultType="User">
            select * from t_user where username like #{xxx}
       </select>-->

    <!--
    模糊查询的第二种写法: 使用 '${value}'
    注意: '${value}'  是固定写法,{}里不能是其他名字,而且必须用引号引起来,因为mybatis是把这个当字符串处理的
    <select id="findByName" parameterType="String" resultType="User">
          select * from t_user where username like '${value}'
    </select>
    -->
    <!--
    补充一点:  '${value}' 因为是字符串,使用可以在前后拼接,比如下面的拼接了 %, 那么传参数的时候可以不用再写%了
    再补充一点,就是这种写法不安全,因为会引起sql注入漏洞问题
    最后补充一点: #{xxx}个${value}的本质区别是,前置是占位符,后者是字符串,两者的sql语句不同
    <select id="findByName" parameterType="String" resultType="User">
          select * from t_user where username like '%${value}%'
    </select>
    -->

    <select id="findByQueryVo" resultType="User" parameterType="QueryVo">
        <!-- 在条件中,我们使用了QueryVo对象的属性user对象,再是user对象是属性uid,使用方法就是和EL表达式类似,属性一直点点点就可以了  -->
        select * from t_user where uid > #{user.uid};
    </select>

    <select id="countOfAllUser" resultType="int">
        select count(*) from t_user
    </select>

    <select id="countOfUserByUid" resultType="int" parameterType="int">
        select count(1) from t_user where uid > #{xxx}
    </select>

    <select id="findUserByIdAndName" resultType="User" parameterType="User">
        select  * from t_user where uid =#{uid} and username=#{username}
    </select>


    <!--以上的配置,都是基于数据库中的表的列名和JavaBean的属性名是一样的情况下的,如果不一样,怎么办
      我们可以使用resultMap配置
      id: 是resultMap的唯一标志,<select>中的resultMap的值就是id的值,表示引用了这个结果集
      type: 表示数据库中的数据封装到哪个类中,这里使用了别名User
    -->
    <resultMap id="findUserByIdResultMap" type="User">
        <!--这里面的id是: 查询结果的唯一标志,可以理解为表的主键-->
        <id property="uid" column="uid_"/>
        <!-- result表示普通返回结果,也就是pojo的属性映射到哪个字段
          property: 是User类的属性
          column: 是sql查询结果的字段名
        -->
        <result property="username" column="username_"/>
        <result property="sex" column="sex_"/>
        <result property="birthday" column="birthday_"/>
        <result property="address" column="address_"/>
    </resultMap>
    <select id="findUserById" resultMap="findUserByIdResultMap" parameterType="User">
        select * from t_user_  where  uid_ = #{uid} and username_ = #{username}
    </select>
</mapper>

全局配置文件 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 里的配置,是需要按照顺序来的,顺序是:properties,typeAliases,environments,mappers,-->
<configuration>
    <!--(可选配置)引入外部的properties文件,目的是动态获取properties中的值.-->
    <properties resource="jdbc.properties"></properties>

    <!--(可选配置)给类型取别名-->
    <typeAliases>
        <!--定义单个别名, 下面typeAlias的配置表示: 我们在映射文件中,返回类型或参数类型,可以不写权限定类名,而用"user"代替-->
        <typeAlias type="com.zuoyueer.domain.User" alias="User"></typeAlias>
        <!--批量定义别名,下面的package配置表示: 我们在映射文件中,返回类型或参数类型,如果定义在"name"属性值表示的包里,那么全部都能使用别名带她权限定类名-->
        <package name="com.zuoyueer.domain"/>
        <!--
            如果返回类型或参数类型,是简单数据类型(8中基本数据类型+String+包装类型),可以直接写类名,因为mybatis帮我们取好了别名就是对应的类名
        -->
    </typeAliases>

    <!--(必须配置)配置连接的环境,default表示默认使用哪一个环境-->
    <environments default="development">

        <!--(必须配置,最少一个)配置一个开发环境,id是随便起名字但是要在environments里唯一-->
        <environment id="development">
            <!--配置事务,mybatis事务是用jdbc的-->
            <transactionManager type="JDBC"></transactionManager>
            <!--POOLED是mybatis内置的连接池,如果不使用,就写type="UNPOOLED"-->
            <dataSource type="POOLED">
                <!--配置链接数据库的必要信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>

        <!--配置第二个连接环境-->
        <environment id="test">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>

        <!--配置第三个连接环境,我们在这里使用引入的外部properties文件中的属性值-->
        <environment id="deploy">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <!--在数据库连接的基本配置中,我们使用了外部properties文件中的属性值,使用方法类似于EL表达式-->
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--(必须配置,里面可以有多个mapper配置项)-->
    <mappers>
        <!--引入映射文件:这是必须要引入的
         resource:是映射文件的路径,注意必须写成"/"不能使用"."
        -->
       <mapper resource="com/zuoyueer/dao/UserMapper.xml"></mapper>
       <mapper resource="com/zuoyueer/dao/UserMapper2.xml"></mapper>
        <!--映射文件和接口的名字一致,路径一致,就可以直接引入name属性值表示的包下的全部映射文件-->
        <!--<package name="com.zuoyueer.dao"/>-->
        <!--mapper和package使用的时候,映射不能重复,否则报错-->
    </mappers>

</configuration>

外部引入的属性文件jdbc.properties 名字随便,规范就这样写, 这个外部属性文件,写不写看你的配置文件SqlMapConfig.xml中有没有引入.不引入就可以不写

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.user=root
jdbc.password=123456

第五步:写测试类

package com.zuoyueer;

import com.zuoyueer.dao.UserMapper;
import com.zuoyueer.domain.QueryVo;
import com.zuoyueer.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.scripting.xmltags.TextSqlNode;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

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

/**
 * @author Zuoyueer
 * Date: 2019/11/15
 * Time: 22:39
 * @projectName Framework
 * @description: 测试类测试UserMapper.xml映射文件
 */
public class MybatisTest {
    /*
     * mybatis的简单使用步骤:
     *  1. 创建maven工程,引入相关坐标
     *  2. 创建javaBean,记得实现序列化接口
     *  3. 创建UserMapper接口,定义方法,是一些操作数据的方法
     *  4. 创建映射文件,该文件在resources中创建
     *  5. 创建全局的配置文件SqlMapConfig.xml,最重要的是引入映射文件
     *  6. 测试,也就是下面方法里面的内容了
     * */
   

    @Test
    public void testFindAll() throws IOException {
        //读取SqlMapConfig.xml全局配置文件,注意使用了org.apache.ibatis.io.Resources;千万别倒错包了
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建SQLSessionFactory
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = builder.build(is);
        //获取SQLSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取UserMapper代理对象,UserMapper是一个接口,根据接口动态代理获取执行接口的方法
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //使用代理对象调用方法,该方法的具体实现在映射文件UserMapper.xml中.
        List<User> list = userMapper.findAll();
        System.out.println(list);
        //释放资源
        sqlSession.close();
        is.close();
    }

    @Test
    public void testInsert() throws IOException {
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = builder.build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setUsername("zuoyueer");
        user.setSex("男");
        user.setBirthday("1996-02-26");
        user.setAddress("深圳");
        userMapper.insert(user);
        sqlSession.commit();
        sqlSession.close();
        is.close();
        /*
        如果映射文件中没有以下配置
         <selectKey resultType="int" keyProperty="uid" order="AFTER">select last_insert_id()</selectKey>
        输出的结果是User{uid=0, username='zuoyueer', sex='男', birthday='1996-02-26', address='深圳'}
        加了之后的输出结果是:
        User{uid=9, username='zuoyueer', sex='男', birthday='1996-02-26', address='深圳'}
        * */
        System.out.println(user);
        System.out.println(user.getUid());
    }

    @Test
    public void testUpdate() throws IOException {
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = builder.build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setUsername("佐助");
        user.setSex("男");
        user.setUid(11);
        mapper.update(user);
        sqlSession.commit();
        sqlSession.close();
        is.close();
    }

    @Test
    public void testDelete() throws IOException {
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = builder.build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        mapper.delete(5);
        sqlSession.commit();
        sqlSession.close();
        is.close();
    }

    @Test
    public void testFindByName() throws IOException {
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = builder.build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        List<User> list = mapper.findByName("%三%");
        System.out.println(list);
        sqlSession.commit();
        sqlSession.close();
        is.close();
    }

    @Test
    public void testFindByQueryVo() throws IOException {
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = builder.build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setUid(5);
        QueryVo queryVo = new QueryVo();
        queryVo.setUser(user);
        List<User> list = mapper.findByQueryVo(queryVo);
        System.out.println(list);
        sqlSession.commit();
        sqlSession.close();
        is.close();
    }

    @Test
    public void testCountOfAllUser() throws IOException {
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = builder.build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        int count = mapper.countOfAllUser();
        System.out.println(count);
        sqlSession.close();
        is.close();
    }


    @Test
    public void testCountOfUserByUid() throws IOException {
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = builder.build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        int count = mapper.countOfUserByUid(33);
        System.out.println(count);
        sqlSession.close();
        is.close();
    }

    @Test
    public void testFindUserByIdAndName() throws IOException {
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = builder.build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setUid(2);
        user.setUsername("李四");
        User user2 = mapper.findUserByIdAndName(user);
        System.out.println(user2);
        sqlSession.close();
        is.close();
    }


    @Test
    public void testFindUserById() throws IOException {
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = builder.build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setUid(3);
        user.setUsername("王五");
        User user2 = mapper.findUserById(user);
        System.out.println(user2);
        sqlSession.close();
        is.close();
    }

}

测试类中很多重复代码,我是为了锻炼自己,重复写了这么多遍,如果你觉得烦,可以抽取工具类,或者使用@before注解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值