A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

【合肥中心】极简Mybatis之旅(一):CRUD
  mybatis的配置文件里,主要是config和mapper。config定义了全局参数:数据源类型(POOL, UNPOOLED, JNDI)、事务管理类型(默认为managed)、库url、账户信息和mapper文件路径。
config配置
[Java] 纯文本查看 复制代码
<configuration>
    <environments default="classfly">
        <environment id="classfly">
            <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="yourusername" />
                <property name="password" value="yourpassword" />
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mapper/UserMapper.xml" />
    </mappers>
</configuration>
DBNAME='test',是mybatis默认分配的库:
mapper配置
首先我们要问自己以下三个问题:
为什么要配置mapper文件?
怎么配置mapper文件?
mybatis如何解析mapper文件?
mapper文件的作用
mapper文件提供一种持久化层与应用层的"通信协议",通过mysql关键字resultMap, parameterType等维护应用代码DO对象与持久化存储数据之间的关联关系。
mapper文件里定义了select, insert, update, delete四种常用的DML语句,并定义statement={mapper namespace}.{operation}实现在应用代码层执行调用DB操作。
配置mapper文件
这里先给出测试用例用到的mapper配置文件的关键部分:
[AppleScript] 纯文本查看 复制代码
<!-- 代码清单-1 -->
<mapper namespace="com.classfly.mapper.UserMapper">
    <resultMap id="user" type="pojo.User">
        <result column="user_id" property="userId" />
        <result column="user_name" property="userName" />
        <result column="password" property="password" />
        <result column="age" property="age" />
    </resultMap>

    <select id="query" resultMap="user">
        SELECT * FROM user;
    </select>

    <insert id="insert" parameterType="pojo.User">
        insert into user
          (
            user_id,
            user_name,
            password,
            age)
        values
          (
            #{userId},
            #{userName},
            #{password},
            #{age}
          )
        <selectKey resultType="pojo.User" keyProperty="id" order="AFTER">
            select LAST_INSERT_ID() as id
        </selectKey>
    </insert>

    <update id="update" parameterType="pojo.User">
        UPDATE user
        SET user_name = #{userName}
          , password = #{password}
          , age = #{age}
        WHERE user_id = #{userId}
    </update>

    <delete id="delete">
        DELETE FROM user
        WHERE user_id = #{userId}
    </delete>
</mapper>
mapper namespace定义了DML语句的作用范围,那如果两个不同的mapper文件定义相同的namespace会发生什么?由于mysql保持namespace的全局唯一性,所以在解析mapper文件时mysql会抛异常提示开发者修改mapper文件以保持namespace的全局唯一性。
resultMap
resultMap关键字将代码和持久化层的数据映射抽象出来,用户无需关心两者之间如何映射。
我们可以使用HashMap完成代码和持久化层的数据映射关系,不但缺乏通用型且代码层需要将对象转换成map结构。resultMap接受HashMap结构和JavaBean或者POJO对象,提供轻量级的参数映射方案。
resultMap有"别名"的功能,你无需每个DML都写一大串的映射语句,秉着"仅定义一次"的原则,我们可以这么做:
[AppleScript] 纯文本查看 复制代码
<resultMap id="userResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="username" column="user_name"/>
  <result property="password" column="hashed_password"/>
</resultMap>

<select id="query" resultMap="user">
        SELECT * FROM user
        ORDER BY ${id};
</select>
'#'和'$'
从"代码清单-1"里可以看出,占位符#和分别实现了POJO和DB数据的映射关系以及非转义的串。用′分别实现了POJO和DB数据的映射关系以及非转义的串。用′'关键字接受用户输入的方式可能导致sql注入攻击,不可取!
mybatis如何解析mapper文件
To be continued...
测试用例
[AppleScript] 纯文本查看 复制代码
/**
 * Created by fujianbo on 2018/4/22.
 *
 * @author fujianbo
 * @date 2018/04/22
 */
public class TestMybatis {
    @Test
    public void testQuery() {
        SqlSession sqlSession = buildMySqlEnv("config.xml");
        List<User> userList = sqlSession.selectList("com.classfly.mapper.UserMapper.query");
        for (User p : userList) {
            System.out.println(p);
        }
    }

    @Test
    public void testInsert() {
        SqlSession sqlSession = buildMySqlEnv("config.xml");
        User user = new User();
        user.setUserId(124L);
        user.setAge(26);
        user.setPassword("test_123");
        user.setUserName("芸Rey");
        if (sqlSession.insert("com.classfly.mapper.UserMapper.insert", user) > 0) {
            sqlSession.commit();
        }
    }

    @Test
    public void testUpdate() {
        SqlSession sqlSession = buildMySqlEnv("config.xml");
        User user = new User();
        user.setUserId(124L);
        user.setAge(26);
        user.setUserName("芸Rey");
        user.setPassword("test_modified");
        if (sqlSession.update("com.classfly.mapper.UserMapper.update", user) > 0) {
            sqlSession.commit();
        }
    }

    @Test
    public void testDelete() {
        SqlSession sqlSession = buildMySqlEnv("config.xml");
        User user = new User();
        user.setUserId(123L);
        if (sqlSession.update("com.classfly.mapper.UserMapper.delete", user) > 0) {
            sqlSession.commit();
        }
    }

    private static SqlSession buildMySqlEnv(String resource) {
        try {
            return new SqlSessionFactoryBuilder()
                .build(org.apache.ibatis.io.Resources.getResourceAsStream(resource))
                .openSession();
        } catch (IOException e) {
            System.out.printf("Failed to build mysql environment!");
            return null;
        }
    }
}

11 个回复

倒序浏览
回复 使用道具 举报
回复 使用道具 举报
666
回复 使用道具 举报
回复 使用道具 举报
回复 使用道具 举报
666
回复 使用道具 举报
回复 使用道具 举报
项老师 来自手机 黑马粉丝团 2018-4-26 17:03:09
9#
666666666
回复 使用道具 举报
点赞
回复 使用道具 举报
朱浩 来自手机 黑马粉丝团 2018-4-26 19:01:29
11#
厉害了
回复 使用道具 举报
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马