zoukankan      html  css  js  c++  java
  • MyBatis学习(二)

    前言

      昨天的博客简单的记录了MyBatis的起源、作用、配置以及一个简单的查询例子。写到一半的时候,觉得已经学会了MyBatis,可是全写完的时候才发现,如果多个参数查询,如何表的名字与类字段名不一样,该如何处理。还有数据的增删改如何操作....还是有很多需要处理的,这篇博客就是对这些方面的学习和记录。

    正文

    1.表字段与类属性不一致的情况

      在数据库中新建了一张person表:

      但是我创建的Person不是这样,按照Java的命名风格,我属性名字不可能采用这种格式,内容如下:

    package org.tonny.entity;
    
    public class Person
    {
        private int id;
        
        private int age;
        
        private String name;
        
        public int getId()
        {
            return id;
        }
        
        public void setId(int id)
        {
            this.id = id;
        }
        
        public int getAge()
        {
            return age;
        }
        
        public void setAge(int age)
        {
            this.age = age;
        }
        
        public String getName()
        {
            return name;
        }
        
        public void setName(String name)
        {
            this.name = name;
        }
        
        @Override
        public String toString()
        {
            return "Person [id=" + id + ", age=" + age + ", name=" + name + "]";
        }
        
    }

    如果直接采用上篇文章中的方法,那么查出来就会是空的。因为MyBatis查询出来结果后,找不到对象中的person_name属性。同理对象中name没有被赋值,自然就是空的。MyBatis提供了解决方案:

    <?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:映射文件的命名空间 命名规则是映射文件所在的Package名 + 文件名 -->
    <mapper namespace="org.tonny.mapper.PersonMapper">
        <!-- parameterType:传入参数的类型; resultType:结果的数据类型,这里 -->
        <select id="getPersonById" parameterType="int" resultMap="personMap">
            SELECT *
            FROM person WHERE person_id=#{id}
        </select>
        <!-- resultMap组装从数据库查询的数据 -->
        <resultMap id="personMap" type="org.tonny.entity.Person">
            <result column="person_id" property="id"></result>
            <result column="person_name" property="name"></result>
            <result column="person_age" property="age"></result>
        </resultMap>
    </mapper>

    就是我预先定义好映射,如表字段person_id与类属性id对应,同理person_name对应name,person_age对应age。同时要个这个映射一个id,方面在其他地方引用。上面的xml代码中,就使用到了。

    JUnit测试代码如下:

    /**
         * desc:测试表字段与类属性对应关系 authour: Tonny Chien 2017年1月6日
         */
        @Test
        public void getPersonById()
        {
            SqlSession sqlSession = sqlSessionFactory.openSession();
            // 映射sql的标识字符串
            String sql = "org.tonny.mapper.PersonMapper.getPersonById";
            int param = 1;
            Person person = sqlSession.selectOne(sql, param);
            sqlSession.close();
            System.out.println(person);
        }

    2.多参数查询

      在sql语句查询的时候,有个多条件是很正常的。如下users表:

      我想查name中包含Chien且id为1的记录,则sql语句为:select * from users where name like '%Chien%' and id=1;

    这样即可。

    那么这条语句反映到映射文件的话,内容就如下:

    SELECT *
            FROM users WHERE id=#{id} and name like #{name}

    这里面需要传入id和name,之前传的时候,都是一个单独的参数...这确实是个难题。还好MyBatis给我们提供了方案,有两种,一是通过封装类的方式,一是通过Map集合形式。

    2.1类封装传参

    通过类封装,就是将要查询的条件为类的成员,那我们的User类就可以直接拿过来使用。那xml文件内容如下:

    <select id="getUserByObj" parameterType="org.tonny.entity.User" resultType="org.tonny.entity.User">
            SELECT *
            FROM users WHERE id=#{id} and name like #{name}
        </select>

    可以看出我传输的参数是User,输出结果当然也是User类型,Java测试代码如下:

    /**
         * desc:测试多参数,通过传入对象形式 authour: Tonny Chien 2017年1月7日
         */
        @Test
        public void getUserByObj()
        {
            SqlSession sqlSession = sqlSessionFactory.openSession();
            // 映射sql的标识字符串
            String sql = "org.tonny.mapper.UsersMapper.getUserByObj";
            User user = new User();
            user.setId(1);
            user.setName("%Chien%");
            List<User> userList = sqlSession.selectList(sql, user);
            sqlSession.close();
            System.out.println(userList);
        }

    2.2Map集合传参

      还有一种就是通过Map来传入参数,个人认为这种方法比较通用,也比较轻便,因为不需要去单独创建类,所以我更喜欢这种方式。在工作中,我也是使用map形式居多。那么配置用的xml需要改变一下:

    <select id="getUserByMap" parameterType="java.util.Map" resultType="org.tonny.entity.User">
            SELECT *
            FROM users WHERE id=#{id} and name like #{name}
        </select>

      注意,传入的参数改成了java.util.Map,返回值当然还是不变,Java测试代码如下:

    /**
         * desc:测试多参数,通过Map形式 authour: Tonny Chien 2017年1月7日
         */
        @Test
        public void getUserByMap()
        {
            SqlSession sqlSession = sqlSessionFactory.openSession();
            // 映射sql的标识字符串
            String sql = "org.tonny.mapper.UsersMapper.getUserByMap";
            Map<String, Object> param = new HashMap<String, Object>();
            param.put("id", 1);
            param.put("name", "%Chien%");
            List<User> userList = sqlSession.selectList(sql, param);
            sqlSession.close();
            System.out.println(userList);
        }

    3.增删改

      在操作过程中,我这里介绍的插入操作,修改操作都是以对象为单位,删除操作简单的介绍根据条件来删除,直接上代码吧,没什么好说的

    <insert id="addUser" parameterType="org.tonny.entity.User">
            INSERT INTO users(name,age)
            VALUES(#{name},#{age})
        </insert>
    
        <update id="editUser" parameterType="org.tonny.entity.User">
            UPDATE users 
            SET name=#{name}, age=#{age}
            WHERE id=#{id}
        </update>
    
        <delete id="delUser" parameterType="int">
            DELETE FROM users
            WHERE id=#{id}
        </delete>

      虽然没有什么好说,但还是要提醒一下,请注意标签的使用insert、update以及delete。Java测试代码也很简单:

     /**
         * desc:向表中插入一条记录 authour: Tonny Chien 2017年1月7日
         */
        @Test
        public void addUser()
        {
            SqlSession sqlSession = sqlSessionFactory.openSession();
            // 映射sql的标识字符串
            String sql = "org.tonny.mapper.UsersMapper.addUser";// 映射sql的标识字符串
            
            User user = new User();
            user.setName("Jerry Chien");
            user.setAge(-2);
            int result = sqlSession.insert(sql, user);
            sqlSession.commit();
            sqlSession.close();
            System.out.println("执行结果:" + result);
        }
        
        @Test
        public void editUser()
        {
            SqlSession sqlSession = sqlSessionFactory.openSession();
            // 映射sql的标识字符串
            String sql = "org.tonny.mapper.UsersMapper.editUser";// 映射sql的标识字符串
            User user = new User();
            user.setId(1);
            user.setName("Jerry Chien");
            user.setAge(-1);
            int result = sqlSession.update(sql, user);
            sqlSession.commit();
            sqlSession.close();
            System.out.println("执行结果:" + result);
        }
        
        @Test
        public void delUser()
        {
            SqlSession sqlSession = sqlSessionFactory.openSession();
            // 映射sql的标识字符串
            String sql = "org.tonny.mapper.UsersMapper.delUser";// 映射sql的标识字符串
            int result = sqlSession.delete(sql, 1);
            sqlSession.commit();
            sqlSession.close();
            System.out.println("执行结果:" + result);
        }

      这里需要注意一下,在更新操作中,MyBatis其实是根据id去寻找记录的,也就是更新的是id为1的那条记录。

    后记

      好了今天就到这里,基本说是走了一个完整的流程了。但还是有很多东西待研究,如我现在操作的只是一张表,表之间有关联的时候如何操作?MyBatis肯定不止这么点内容,一定还有一些高级特性,以及后面如何与spring整合,都需要学习。明天加油!

  • 相关阅读:
    Unix UTC时间转化为本地时间的一个MFC实现
    不规则按钮Button修正版
    不规则按钮,支持普通Button,Radio Button, Check Button
    Kimi ga Suki da to Sakebitai
    将adb for visual studio 从26升级29版本
    直到世界的尽头
    Your Song
    Win32创建后台进程
    全金属外壳的歌词
    C#获取本机IP(排除IPV6,仅获取IPV4)的方法转载
  • 原文地址:https://www.cnblogs.com/supertonny/p/6260443.html
Copyright © 2011-2022 走看看