• Mybatis3详解(二)----Mybatis的第一个入门实例


    1、本章前言

    在上一章简单介绍了什么是Mybatis,它封装的有哪些重要的组件以及它的使用步骤,所以这一章就来编写一个Mybatis的入门实例。首先说明一点:MyBatis 的使用分为三个版本:

    • 基于原生接口的XML版本。
    • 基于Mapper接口的XML版本。
    • 基于Java 注解版本。

    一般推荐基于 Mapper 接口和基于 Java 注解的方式,因为这两种方式在实际开发中我们更加常用。但是现在这里只是刚刚入门,所以就用原生接口的XML版本来创建一个Mybatis的入门实例。看看如何实现对数据库的基本操作,其步骤如下。

    2、创建一个数据库

    由于Mybatis是对数据库的操作,所以首先得先创建一个数据库和一个表,数据库命名为mybatis,表命名为t_user。这里针对MySQL数据库。SQL脚本如下:

    DROP TABLE IF EXISTS `t_user`;
    CREATE TABLE `t_user`  (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `age` int(11) NULL DEFAULT NULL,
      `sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Records of t_user
    -- ----------------------------
    INSERT INTO `t_user` VALUES (1, '奥利给', 18, '男', '上海');
    INSERT INTO `t_user` VALUES (2, '蔡徐坤', 18, '男', '北京');
    INSERT INTO `t_user` VALUES (3, '黄飞鸿', 42, '男', '大清');
    INSERT INTO `t_user` VALUES (4, '十三姨', 18, '女', '大清');
    INSERT INTO `t_user` VALUES (5, '梁宽', 42, '男', '大清');
    INSERT INTO `t_user` VALUES (6, '马保国', 33, '男', '深圳');
    INSERT INTO `t_user` VALUES (7, '纳兰元述', 42, '男', '大清');
    

    3、创建Maven工程

    在Eclipse或IDEA中创建一个Maven项目。

    image

    然后导入pom依赖,如下:

    <dependencies>
        <!-- Mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>
        <!-- 日志处理 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- 单元测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
    

    4、编写User实体类

    创建一个User实体类,这里省略了getter、setter和toString方法,需自己加上。

    /**
     * 用户实体类
     */
    public class User {
        private Integer id;
        private String username;
        private Integer age;
        private String sex;
        private String address;
    
        //getter、setter、toString方法省略......
    }
    

    5、创建Mybatis全局配置文件

    然后在resources目录中,创建Mybatis的全局配置文件mybatis-config.xml。它是mybatis核心配置文件,配置文件内容为数据源、事务管理和指定映射配置文件的位置。代码如下:

    <?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="development">
            <!-- id属性必须和上面的default一致 -->
            <environment id="development">
                <!--配置事务的类型-->
                <transactionManager type="JDBC"></transactionManager>
                <!--dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象源 -->
                <dataSource type="POOLED">
                    <!--配置连接数据库的4个基本信息-->
                    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/user?serverTimezone=GMT%2B8&amp;useUnicode=true&amp;characterEncoding=utf-8"/>
                    <property name="username" value="root"/>
                    <property name="password" value="root"/>
                </dataSource>
            </environment>
        </environments>
    </configuration>
    

    对mybatis-config.xml中配置项的简单说明:

    • environments:配置当前的环境,default属性有development和work两种选择,默认是development开发模式,work是工作模式。
    • environment:配置每个environment定义的环境,可以配置多个运行环境,但是每个SqlSessionFactory实例只能选择一个运行环境。其id属性也有development和work两种选择,并且必须和上面的default属性一致。如果配置了两个相同的environment,Mybatis会用后面的覆盖掉前面的。
    • transactionManager:配置事务管理器类型,type属性中有JDBC和MANAGED两种,一次只能配置一个。
      • JDBC使用JdbcTransactionFactory工厂生成的JdbcTransaction对象实现,以JDBC的方式进行数据库的提交、回滚等操作,它依赖于从数据源得到的连接来管理事务范围。
      • MANAGED使用ManagedTransactionFactory工厂生成的ManagedTransaction对象实现,它的提交和回滚不需要任何操作,而是把事务交给容器进行处理,默认情况下会关闭连接,如果不希望默认关闭,只要将其中的closeConnection属性设置为false即可。
    • dataSource:配置数据源类型,type属性有UNPOOLED、POOLED和JNDI三种选择:
      • UNPOOLED(UnpooledDataSourceFactory):采用非数据库池的管理方式,每次请求都会新建一个连接,并用完后关闭它,所以性能不是很高。该方式适用于只有小规模数量并发用户的简单应用程序上。
      • POOLED(PooledDataSourceFactory):采用连接池的概念将数据库链接对象Connection组织起来,可以在初始化时创建多个连接,使用时直接从连接池获取,避免了重复创建连接所需的初始化和认证时间,从而提升了效率,所以这种方式比较适合对性能要求高的应用中。在开发或测试环境中经常用到此方式。
      • JNDI(JndiDataSourceFactory):数据源JNDI的实现是为了能在如EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用。在生产环境中优先考虑这种方式。
    • property:dataSource中的property元素就是数据库相关的配置信息。

    6、编写SQL映射配置文件(重要)

    我们在目录resources--->mapper(mapper目录自行创建)下创建一个UserMapper.xml文件。Mybatis中所有数据库的操作都会基于该映射文件配置的SQL语句,在这个配置文件中可以配置任何类型的SQL语句。框架会根据配置文件中的参数配置,完成对SQL语句输入输出参数的映射配置。

    注意事项 (非常重要!非常重要!非常重要!):

    相关属性
    描述
    namespace 表示命名空间,用来设定当前Mapper配置文件的唯一标识,将来在Java程序中通过namespace属性的值来定位到这个配置文件,namespace属性值设置的方式:名字可以随便取,但是推荐以相对应的Mapper接口的全类名,例如com.thr.mapper.UserMapper
    id SQL映射语句的唯一标识,称为statement的id,将SQL语句封装到mappedStatement对象中,所以将id称为statement的id
    parameterType 指定输入参数的类型
    resultType 指定输出结果类型。Mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到List容器中,后面会还会介绍resultMap,推荐使用它
    #{value} #{value}表示SQL语句的占位符,相当于JDBC中的”?”它会自动进行java类型和jdbc类型转换, #{value}里面参数写啥都可以,但是不要空着,如#{Id}#{name}#{value}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。#{value}可以有效防止SQL注入
    ${value} ${value}表示拼接SQL字符串,将接收到的参数在不进行jdbc类型转换的情况下拼接在SQL语句中,${value}里面必须要写参数,不然会报错。${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。使用${value}会造成 SQL注入,所以尽量不要使用它

    文件代码如下所示:

    <?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属性:表示命名空间,用来设定当前Mapper配置文件的唯一标识,将来在Java程序中通过namespace属性的值来定位到这个配置文件 -->
    <!-- namespace属性值设置的方式:名字可以随便取,但是推荐以相对应的Mapper接口的全类名,例如com.thr.mapper.UserMapper -->
    <mapper namespace="com.thr.mapper.UserMapper">
        <!-- 查询所有用户 -->
        <select id="selectAllUser" resultType="com.thr.entity.User">
            select * from t_user;
        </select>
        <!-- 通过Id查询一个用户 -->
        <select id="selectUserById" parameterType="int" resultType="com.thr.entity.User">
            select * from t_user where id = #{id};
        </select>
        <!-- 模糊查询,根据username字段查询用户-->
        <select id="selectUserByName" parameterType="int" resultType="com.thr.entity.User">
            select * from t_user where username like '%${value}%';
        </select>
        <!-- 添加用户-->
        <insert id="insertUser" parameterType="com.thr.entity.User">
            insert into t_user(username, age, sex, address)
            values (#{username}, #{age}, #{sex}, #{address});
        </insert>
        <!-- 根据Id更新用户 -->
        <update id="updateUser" parameterType="com.thr.entity.User">
            update t_user set username = #{username},
                age = #{age},sex = #{sex},address = #{address} where id = #{id}
        </update>
        <!-- 根据Id删除用户 -->
        <delete id="deleteUser" parameterType="int">
            delete from t_user where id = #{id}
        </delete>
    </mapper>
    

    7、加载映射文件

    将上面创建的UserMapper.xml文件添加至全局配置文件mybatis-config.xml下。

    image

    <!--指定映射配置文件的位置,这个映射配置文件指的是每个业务独立的配置文件-->
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
    

    8、导入日志文件

    导入日志文件,在resources目录中创建log4j.properties文件,并且导入如下配置(如果log报错则以管理员的方式启动Eclipse或IDEA)。

    # 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
    
    

    9、编写测试代码

    最后创建一个MybatisTest的测试类,其源代码如下所示:

    注意:使用JDBC的事务管理在进行增删改操作时,需要进行提交事务,也就是sqlSession.commit(),否则数据不会操作成功。

    /**
     * Mybatis的测试
     */
    public class MybatisTest {
        //定义 SqlSession
        SqlSession sqlSession = null;
    
        @Before
        public void getSqlSession() {
            //加载 mybatis 全局配置文件
            InputStream is = MybatisTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
            //创建 SqlSessionFactory 对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            //根据 sqlSessionFactory 产生 session
            sqlSession = sqlSessionFactory.openSession();
        }
    
        //查询所有用户数据
        @Test
        public void testSelectAllUser() {
            /**
             * 注意:这个字符串由 UserMapper.xml 文件中的两个部分构成(namespace + id)
             * <mapper namespace="com.thr.mapper.UserMapper">中 namespace 的值
             * <select id="selectAllUser" > 中的 id 值
             * 这样Mybatis才能找到需要的SQL
             */
            String statement = "com.thr.mapper.UserMapper.selectAllUser";
            List<User> listUser = sqlSession.selectList(statement);
            for (User user : listUser) {
                System.out.println(user);
            }
            sqlSession.close();
        }
    
        //根据Id查询一个用户数据
        @Test
        public void testSelectUserById() {
            String statement = "com.thr.mapper.UserMapper.selectUserById";
            User user = sqlSession.selectOne(statement, 1);
            System.out.println(user);
            sqlSession.close();
        }
    
        //模糊查询:根据 user 表的username字段
        @Test
        public void testSelectUserByName() {
            String statement = "com.thr.mapper.UserMapper.selectUserByName";
            List<User> listUser = sqlSession.selectList(statement, "三");
            for (User user : listUser) {
                System.out.println(user);
            }
            sqlSession.close();
        }
    
        //添加一个用户数据
        @Test
        public void testInsertUser() {
            String statement = "com.thr.mapper.UserMapper.insertUser";
            User user = new User();
            user.setUsername("张三");
            user.setAge(34);
            user.setSex("男");
            user.setAddress("中国深圳");
            int i = sqlSession.insert(statement, user);
            System.out.println( (i>0)? "添加成功!":"添加失败!");
            //提交插入的数据
            sqlSession.commit();
            sqlSession.close();
        }
    
        //根据Id修改用户数据
        @Test
        public void testUpdateUser(){
            //如果设置的 id不存在,那么数据库没有数据更改
            String statement = "com.thr.mapper.UserMapper.updateUser";
            User user = new User();
            user.setId(3);
            user.setUsername("王红");
            user.setAge(26);
            user.setSex("女");
            user.setAddress("中国上海");
            int i = sqlSession.update(statement, user);
            System.out.println( (i>0)? "修改成功!":"修改失败!");
            //提交数据
            sqlSession.commit();
            sqlSession.close();
        }
    
        //根据Id删除用户数据
        @Test
        public void testDeleteUser(){
            String statement = "com.thr.mapper.UserMapper.deleteUser";
            int i = sqlSession.delete(statement, 4);
            System.out.println( (i>0)? "删除成功!":"删除失败!");
            sqlSession.commit();
            sqlSession.close();
        }
    }
    
    作者: 唐浩荣
    本文版权归作者和博客园共有,欢迎转载,但是转载需在博客的合适位置给出原文链接,否则保留追究法律责任的权利。
  • 相关阅读:
    【前端】原生event对象和jquery event对象的区别
    【前端】js代码模拟用户键盘鼠标输入
    【前端】回到顶部
    【前端】Three.js
    【前端】三种复制数组的方法
    【Python】Django
    【前端】CommonJS的模块加载机制
    注释声明:TODO HACK XXX FIXME REVIEW
    【Python】Python3中的str和bytes
    【前端】iterable类型的 forEach方法
  • 原文地址:https://www.cnblogs.com/tanghaorong/p/13915812.html
Copyright © 2020-2023  润新知