zoukankan      html  css  js  c++  java
  • 测试开发进阶——spring boot——MVC——MyBatis初步了解(转载)

    Mybatis介绍#

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

    2013年11月迁移到Github。MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

    Mybatis框架#

    框架介绍

    1、 mybatis配置

    SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。

    mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。

    2、 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂

    3、 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。

    4、 mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。

    5、 Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。

    6、 Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。

    7、 Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

    利用IDEA创建Mybatis的入门案例#

    8个步骤#

    1. 创建maven工程,什么都不选就ok,并导入坐标;
    Copy
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
    
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>
    </dependencies>
    
    1. 编写User实体类
    Copy
    public class User implements Serializable {
        private int id;
        private String username;// 用户姓名
        private String sex;// 性别
        private Date birthday;// 生日
        private String address;// 地址
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public Date getBirthday() {
            return birthday;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        @Override
        public String toString() {
            return "User [id=" + id + ", username=" + username + ", sex=" + sex
                    + ", birthday=" + birthday + ", address=" + address + "]";
        }
    
    }
    
    1. 在resources文件夹中,创建Mybatis的主配置文件SqlMapConfig.xml。它是mybatis核

      心配置文件,配置文件内容为数据源、事务管理。

      配置环境:

      • 配置mysql的环境:
      1. 配置事务的类型;
      2. 配置连接池:配置连接数据库的4个基本信息;
      • 指定映射配置文件的位置:

    代码如下:

    Copy
    <?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>
    <!--   配置环境-->
        <environments default="mysql">
     	    <!--配置mysql的环境-->
            <environment id="mysql">
      		   <!--配置事务的类型-->
                <transactionManager type="JDBC"></transactionManager>
    		   <!--配置连接池-->
                <dataSource type="POOLED">
    				<!--配置连接数据库的4个基本信息-->
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://192.168.214.128:3306/mybatis"/>
                    <property name="username" value="root"/>
                    <property name="password" value="ben123"/>
                </dataSource>
            </environment>
        </environments>
    
    <!--指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件-->
        <mappers>
            <mapper resource="com/ben/dao/IUserDao.xml"/>
        </mappers>
    </configuration>
    
    1. 在resources文件夹中导入log4j.properties文件
    Copy
    # Set root category priority to INFO and its only appender to CONSOLE.
    #log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
    log4j.rootCategory=debug, CONSOLE, LOGFILE
    
    # Set the enterprise logger category to FATAL and its only appender to CONSOLE.
    log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
    
    # CONSOLE is set to be a ConsoleAppender using a PatternLayout.
    log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
    log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
    log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m
    
    
    # LOGFILE is set to be a File appender using a PatternLayout.
    log4j.appender.LOGFILE=org.apache.log4j.FileAppender
    log4j.appender.LOGFILE.File=d:axis.log
    log4j.appender.LOGFILE.Append=true
    log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
    log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m
    
    
    1. 编写映射文件 IUserDao.xml ,位置在目录resource->sqlmap->User.xml
    Copy
    <?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:命名空间,用于隔离sql,还有一个很重要的作用,后面会讲 -->
    <mapper namespace="test">
    </mapper>
    
    1. 加载映射文件,将User.xml添加在SqlMapConfig.xml下
    Copy
    <!--指定映射配置文件的位置-->
    <mappers>
        <mapper resource="sqlmao/User.xml"/>
    </mappers>
    
    1. 编写测试类:在test->java目录下创建测试类com.ben.test.MybatisTest。实现业务需求,共7步,其中2,3步可以合在一起。
    Copy
    1. 加载核心配置文件SqlMapConfig.xml
    2. 创建SqlSessionFactoryBuilder对象
    3. 创建SqlSessionFactory对象(2,3可以写一起)
    4. 创建SqlSession对象
    5. 执行SqlSession对象执行查询,获取结果User
    6. 打印结果
    7. 释放资源
    

    代码如下:

    Copy
    package com.ben.test;
    
    import com.ben.domain.User;
    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 java.io.IOException;
    import java.io.InputStream;
    import java.util.Date;
    import java.util.List;
    
    /**
     * @ClassName: MybatisTest
     * @author: benjamin
     * @version: 1.0
     * @description: TODO
     * @createTime: 2019/07/13/11:50
     */
    
    public class MybatisTest {
        public static void main(String[] args) {
    
    
        }
        //通过Id查询一个用户
        @Test
        public void testSearchById() throws IOException {
            //1.读取配置文件
            InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
            //2.创建SqlSessionFactory工厂
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //3.使用工厂生产SqlSession对象
            SqlSession session = sqlSessionFactory.openSession();
            //4.执行Sql语句
            User user = session.selectOne("test.findUserById", 10);
            //5. 打印结果
            System.out.println(user);
            //6.释放资源
            session.close();
            in.close();
        }
    
        //根据用户名模糊查询用户列表
        @Test
        public void testFindUserByUsername() throws IOException {
            //1.读取配置文件
            InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
            //2.创建SqlSessionFactory工厂
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //3.使用工厂生产SqlSession对象
            SqlSession session = sqlSessionFactory.openSession();
            //4.执行Sql语句
            List<User> list = session.selectList("test.findUserByUsername", "王");
            //5. 打印结果
            for (User user:list) {
                System.out.println(user);
            }
            //6.释放资源
            session.close();
            in.close();
        }
    
        //添加用户
        @Test
        public void testInsertUser() throws IOException {
            //1.读取配置文件
            InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
            //2.创建SqlSessionFactory工厂
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //3.使用工厂生产SqlSession对象
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //4.执行Sql语句
            User user = new User();
            user.setUsername("小强");
            user.setBirthday(new Date());
            user.setAddress("sadfsafsafs");
            user.setSex("2");
            int i = sqlSession.insert("test.insertUser", user);
            sqlSession.commit();
            //5. 打印结果
            // 刚保存用户,此时用户ID需要返回。执行完上面insert程序后,此时就能知道用户的ID是多少
            // 需要在User.xml文件中配置
            System.out.println("插入id:"+user.getId());//插入id:30
    
            //6.释放资源
            sqlSession.close();
            in.close();
        }
        //更新用户
        @Test
        public void testUpdateUserById() throws IOException {
            //1.读取配置文件
            InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
            //2.创建SqlSessionFactory工厂
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //3.使用工厂生产SqlSession对象
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //4.执行Sql语句
            User user = new User();
            user.setId(27);
            user.setUsername("小小");
            user.setBirthday(new Date());
            user.setAddress("西安市");
            user.setSex("1");
            int i = sqlSession.insert("test.updateUserById", user);
            sqlSession.commit();
            //5. 打印结果
            System.out.println(user.getId());
            //6.释放资源
            sqlSession.close();
            in.close();
        }
        //删除用户
        @Test
        public void testDeleteUserById() throws IOException {
            //1.读取配置文件
            InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
            //2.创建SqlSessionFactory工厂
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //3.使用工厂生产SqlSession对象
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //4.执行Sql语句
            int i = sqlSession.insert("test.deleteUserById", 32);
            sqlSession.commit();
            //5. 打印结果
            System.out.println(i);
            //6.释放资源
            sqlSession.close();
            in.close();
        }
    }
    
    1. 配置映射配置文件User.xml
    Copy
    <?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="test">
    
        <!-- 通过Id查询一个用户   -->
        <select id="findUserById" parameterType="Integer" resultType="com.ben.domain.User">
            select * from user where id = #{v}
        </select>
    
        <!-- 根据用户名模糊查询用户列表 -->
        <!--    select * from user where username like '%${value}%'-->
    <!-- select * from user where username like "%"#{value}"%"-->
        <select id="findUserByUsername" parameterType="String" resultType="com.ben.domain.User">
            select * from user where username like #{username}
        </select>
        <!--  添加用户  -->
        <insert id="insertUser" parameterType="com.ben.domain.User">
            <selectKey keyProperty="id" resultType="Integer" order="AFTER">
                select LAST_INSERT_ID()
            </selectKey>
            insert into user (username,birthday,address,sex) values(#{username},#{birthday},#{address},#{sex})
        </insert>
        <!-- 更新用户 -->
        <update id="updateUserById" parameterType="com.ben.domain.User">
    		update user
    		set username = #{username},sex = #{sex},birthday = #{birthday},address = #{address}
    		where id = #{id}
    	</update>
        <!-- 删除用户   -->
        <delete id="deleteUserById" parameterType="Integer">
    		delete from user
    		where id = #{vvvvv}
    	</delete>
    </mapper>
    

    注意事项#

    详解参数#

    Copy
    namespace:用来区别不同的类的名字 
    id:标识映射文件中的sql,称为statement的id将sql语句封装到mappedStatement对象中,所以将id称为statement的id
    parameterType:指定输入参数的类型.
    resultType:指定输出结果类型。mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中
    
    Copy
    #{}:一个占位符。preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
    
    ${}:表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。
    

    解释select语句#

    这一部分参考mybatis官网。详情点击http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html

    Copy
    <select id="findUserById" parameterType="Integer" resultType="com.ben.domain.User">
        select * from user where id = #{v}
    </select>
    

    这个语句被称作findUserById, 接受一个Integer类型的参数,返回一个User对象。#{V} 告诉mybatis创建一个预处理语句参数,在JDBC中,这个的一个参数在Sql中会由一个“ ?”表示,并被传递到新的预处理语句中,如:

    Copy
    //近似的JDBC代码,并非Mybatis代码
    String findUserById = "select * from user where id = ?";
    PreparedStatement ps = conn.prepareStatement(findUserById);
    ps.setInt(1,id);
    

    使用 JDBC 意味着需要更多的代码来提取结果并将它们映射到对象实例中,而这就是 MyBatis 节省你时间的地方.

    注意#

    • 在根据用户名模糊查询中注意:有两种写法。
    Copy
    1.测试类中这样写:
    List<User> list = session.selectList("test.findUserByUsername", "王");
    在User.xml中写:
    select * from user where username like '%${value}%'
    其对应的实际sql操作语句:select * from user where username like'%五%'
    也可以这样写:
    select * from user where username like "%"#{value}"%" # value 可以换成haha
    其对应的sql查询语句是:select * from user where username like"%"'五'"%"
    2.如果测试类中这样写:
    List<User> list = session.selectList("test.findUserByUsername", "%王%");
    User.xml这样写
    select * from user where username like #{username} 
    其中username可以换成haha等其他名称。
    
    • 执行插入操作时,保存成功,但是id=0,需要解决id返回不正常的问题。如果刚保存用户,此时用户ID需要返回。执行完上面insert程序后,此时就能知道用户的ID是多少,需要在插入之前补充语句:
    Copy
    <selectKey keyProperty="id" resultType="Integer" order="AFTER">
        select LAST_INSERT_ID()
    </selectKey>
    
     
  • 相关阅读:
    SpringMVC
    SpringMVC
    SpringMVC
    Spring
    Spring
    值类型和引用类型
    判断字符串的开头和结尾
    二分法(课后)
    验证码
    从1-36中随机出6个不相等的数
  • 原文地址:https://www.cnblogs.com/xiaobaibailongma/p/15115435.html
Copyright © 2011-2022 走看看