极简Mybatis之旅(一):CRUD
摘要
最近在研究mybatis框架,作为一个优秀ORM框架,mybatis很多优秀的设计思想值得借鉴。
mybatis的配置文件里,主要是config和mapper。config定义了全局参数:数据源类型(POOL, UNPOOLED, JNDI)、事务管理类型(默认为managed)、库url、账户信息和mapper文件路径。
config配置
// config.xml <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配置文件的关键部分:
<!-- 代码清单-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都写一大串的映射语句,秉着"仅定义一次"的原则,我们可以这么做:
// config.xml <typeAlias type="pojo.User" alias="User"/> // 用typeAlias的User别名替换了resultMap中的user <select id="query" resultType="User"> SELECT * FROM user ORDER BY id DESC </select>
Now if only the world was always that simple!
当POJO类成员变量并未完全和Table列名"对齐"时,可通过定义resultMap的方式来实现mapper:
<resultMap id="user" type="User"> <result property="userId" 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 DESC </select>
'#'和'$'
从"代码清单-1"里可以看出,#和$
均可实现POJO字段和DB表列名的映射关系。#
将参数部分用?
替换,而$
仅根据执行sql时通过POJO对象透传的值进行字符串替换,容易被注入恶意代码,不可取!如:
select * from ${tableName} where name = #{name}
如果tableName='user; delete user; --',最终sql语句变为:
select * from user; delete user; -- where name = #{name}
导致user整张表数据被删除。
mybatis如何解析mapper文件
To be continued...
测试用例
/** * 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; } } }
代码链接实现
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
(一)python初识、变量、注释、模块使用
python初识 移步老男孩武sir文章(python2):http://www.cnblogs.com/wupeiqi/articles/5433925.html 武功sir文章列表(python2):http://www.cnblogs.com/wupeiqi/articles/5433893.html Centos6升级python2至python3:http://www.cnblogs.com/lyy-totoro/p/5603102.html 简单笔记如下: python的特点 可以写网页,也可以写后台功能。执行效率低,开发效率高(相较于java) python的种类 JPython:java开发的python,运行python代码先转换为java代码,然后执行IronPython:.NET和Mono上实现的Python语言,执行方法同上JavaScriptPython:javascript开发的python,执行方法同上RubyPython:类推,同上CPython:Cpython是我们常用的python,它是由C开发的,最稳定、功能最强的pythonpypy:...
- 下一篇
传智播客_风清扬_2015年java基础深入浅出版_刘意老师
传智播客_风清扬_2015年java基础深入浅出版_刘意老师 视频介绍:本套Java视频教程是黑马程序员刘老师精心录制的免费精华版Java基础视频。历经6年推出的一套Java入门教程,该视频专门针对零基础的学员录制,授课讲究通俗易懂、干货。通过该套Java视频教程的学习,相信你能够轻轻松松地入门java语言。注:掌握了该套Java视频教程的知识,就可以具备报读Java就业班的条件。 Java入门教程目录: 1.计算机的基础知识(day01) 2.Java语言基础(day02-day06) 3.Java面向对象(day07-day10) 4.Java开发工具(day11) 5.Java常见对象(day12-day14) 6.Java集合框架(day15-day19) 7.JavaIO流(day20-day22) 8.Java多线程(day23-day24) 9.JavaGUI(day25) 10.Java网络编程(day26) 11.Java反射(day27) 视频概况: ==========================================================...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Mario游戏-低调大师作品
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8编译安装MySQL8.0.19
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7