MyBatis随笔
前一阵参与了一个项目的搭建,为了快速开发再加上学一些新东西,准备采用React+Spring MVC+MyBatis的架构。
花了一些时间最终把Spring MVC+MyBatis打通。
这里总结下MyBatis的使用过程,方便以后查阅。
参考资料:
1. http://www.mybatis.org/mybatis-3/zh/
2. http://blog.csdn.net/isea533/article/category/2092001
不玩儿虚的,直接上!
环境:Intellij IDEA 12; SQLSERVER;
既然是Spring MVC+MyBatis的架构,分service和persistence层。另外,Intellij IDEA构建多模块结构还是挺方便的,两个模块如下:

整体的运作就是service层调用persistence层的dao来访问数据库,而MyBatis则作为数据库SQLSERVER同service层的桥梁。
MyBatis整体来说,同Hibernate一样,是对JDBC的轻量级封装,完成ORM功能。
从使用MyBatis和Hibernate来说,个人感觉,Hibernate更加偏向于对象化,比如Criteria和Query,创建查询对象;MyBatis则偏向于sql,将sql语句写入mapper文件中。
总体来说,使用Hibernate需要多多少少了解它的HQL语句,而MyBatis则更注重数据库操作的专一化,即只是使用sql语句,对查询结果用resultMap封装,所以难易程度上,个人感觉MyBatis更容易一些。
下面试着打通MyBatis和SQLSERVER......
1. 任何开源框架的使用,肯定是要先进行配置的。
1.1 对MyBatis来说,针对它自己的配置文件是mybatisConfig.xml(默认)。在这个项目里,因为和Spring整合,就只用到日志的配置。
mybatisConfig.xml
<?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>
<settings>
<setting name="logImpl" value="SLF4J"/>
</settings>
</configuration>
这里对应logImpl的value可以从源码里找到(org.apache.ibatis.session.Configuration, 该类配置了很多MyBatis的默认值),如下:
typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class);
typeAliasRegistry.registerAlias("COMMONS_LOGGING", JakartaCommonsLoggingImpl.class);
typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class);
typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class);
typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class);
typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class);
typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class);
1.2 因为同Spring整合,添加mybatis-spring依赖(maven方式)
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
1.3 回到数据库一端,涉及创建数据源以及基于Spring的事务管理
persistence.properties
# jdbc.*
jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://dbhost:dbport;databaseName=db-name;
jdbc.user=aaa
jdbc.password=aaa
jdbc.initialSize=1
jdbc.minIdle=1
jdbc.maxActive=20
jdbc.maxWait=60000
jdbc.tberm=60000
jdbc.meitm=300000
jdbc.vq=SELECT 'x'
jdbc.twi=true
jdbc.tob=false
jdbc.tor=false
persistenceContext.xml (Part I)
<context:property-placeholder location="classpath:persistence.properties"/>
<!-- DataSource related -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
<property name="initialSize" value="${jdbc.initialSize}"/>
<property name="minIdle" value="${jdbc.minIdle}"/>
<property name="maxActive" value="${jdbc.maxActive}"/>
<property name="maxWait" value="${jdbc.maxWait}"/>
<property name="timeBetweenEvictionRunsMillis" value="${jdbc.tberm}"/>
<property name="minEvictableIdleTimeMillis" value="${jdbc.meitm}"/>
<property name="validationQuery" value="${jdbc.vq}"/>
<property name="testWhileIdle" value="${jdbc.twi}"/>
<property name="testOnBorrow" value="${jdbc.tob}"/>
<property name="testOnReturn" value="${jdbc.tor}"/>
</bean>
<!-- 配置Spring的事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
这里的jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver,SQLServerDriver并没有在Maven Repository托管,而且鉴于项目基于Maven构建,将下载到的sqljdbc41.jar(jre7) install到本地,使用如下命令:
mvn install:install-file -Dfile=sqljdbc41.jar -Dpackaging=jar -DgroupId=com.microsoft.sqlserver -DartifactId=sqljdbc -Dversion=4.1
OK, 接下来是mybatis同Spring整合时的核心部分。
1.4 Mybatis同Spring整合
persistenceContext.xml (Part II)
<!-- 配置sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
<property name="configLocation" value="classpath:mybatisConfig.xml"/>
<property name="typeAliasesPackage" value="com.chris.persistence.entity"/>
</bean>
<!-- 配置扫描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.chris.persistence.dao"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
利用Intellij IDEA,可以看到mapperLocations对应的value呈红色,因为在resources包下并没有mapper文件夹和xml文件。
这个时候应该停下来想想MyBatis怎么做到ORM? 总体来说,同Hibernate类似
1. 数据库表中的记录同java bean对应
Record:

Java Bean:
import java.util.Date;
public class Report {
private Integer id;
private String name;
private String description;
private String owner;
private String customer;
private Date created;
private String createdby;
private Date updated;
private String updatedby;
private Integer version;
private Integer clientversion;
public Report(Integer id, String name, String description, String owner, String customer, Date created, String createdby, Date updated, String updatedby, Integer version, Integer clientversion) {
this.id = id;
this.name = name;
this.description = description;
this.owner = owner;
this.customer = customer;
this.created = created;
this.createdby = createdby;
this.updated = updated;
this.updatedby = updatedby;
this.version = version;
this.clientversion = clientversion;
}
public Report() {
super();
}
setter; getter...
2. 程序调用接口方法并根据mapper文件执行sql语句
dao层:
import com.chris.persistence.entity.Report;
import com.chris.persistence.entity.SubReport; import java.util.List; public interface ReportMapper {
int deleteByPrimaryKey(Integer id);
int insert(Report record);
int insertSelective(Report record);
Report selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(Report record);
int updateByPrimaryKey(Report record);
List<SubReport> selectReportListByPWID(String pwid); }
mapper.xml
<?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="com.chris.persistence.dao.ReportMapper">
<resultMap id="BaseResultMap" type="com.chris.persistence.entity.Report">
<constructor>
<idArg column="Id" jdbcType="INTEGER" javaType="java.lang.Integer"/>
<arg column="Name" jdbcType="VARCHAR" javaType="java.lang.String"/>
<arg column="Description" jdbcType="VARCHAR" javaType="java.lang.String"/>
<arg column="Owner" jdbcType="CHAR" javaType="java.lang.String"/>
<arg column="Customer" jdbcType="VARCHAR" javaType="java.lang.String"/>
<arg column="Created" jdbcType="TIMESTAMP" javaType="java.util.Date"/>
<arg column="CreatedBy" jdbcType="VARCHAR" javaType="java.lang.String"/>
<arg column="Updated" jdbcType="TIMESTAMP" javaType="java.util.Date"/>
<arg column="UpdatedBy" jdbcType="VARCHAR" javaType="java.lang.String"/>
<arg column="Version" jdbcType="INTEGER" javaType="java.lang.Integer"/>
<arg column="ClientVersion" jdbcType="INTEGER" javaType="java.lang.Integer"/>
</constructor>
</resultMap>
<resultMap id="ReportListResultMap" type="SubReport">
<result column="Id" property="id"/>
<result column="Name" property="name"/>
<result column="Description" property="description"/>
</resultMap>
<sql id="Base_Column_List">
Id, Name, Description, Owner, Customer, Created, CreatedBy, Updated, UpdatedBy, Version,
ClientVersion
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">
select
<include refid="Base_Column_List"/>
from [Report]
where Id = #{id,jdbcType=INTEGER}
</select>
<select id="selectReportListByPWID" parameterType="String" resultMap="ReportListResultMap">
select r.[Id], r.[Name], r.[Description]
from [Report] as r left join [Report_Access] as ra on r.[Id]=ra.[ReportId]
left join [User] as u on u.[Id]=ra.[UserId]
where u.[PWID] = #{pwid}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from [Report]
where Id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.chris.persistence.entity.Report">
insert into [Report] (Id, Name, Description,
Owner, Customer, Created,
CreatedBy, Updated, UpdatedBy,
Version, ClientVersion)
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR},
#{owner,jdbcType=CHAR}, #{customer,jdbcType=VARCHAR}, #{created,jdbcType=TIMESTAMP},
#{createdby,jdbcType=VARCHAR}, #{updated,jdbcType=TIMESTAMP}, #{updatedby,jdbcType=VARCHAR},
#{version,jdbcType=INTEGER}, #{clientversion,jdbcType=INTEGER})
</insert>
<insert id="insertSelective" parameterType="com.chris.persistence.entity.Report">
insert into [Report]
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
Id,
</if>
<if test="name != null">
Name,
</if>
<if test="description != null">
Description,
</if>
<if test="owner != null">
Owner,
</if>
<if test="customer != null">
Customer,
</if>
<if test="created != null">
Created,
</if>
<if test="createdby != null">
CreatedBy,
</if>
<if test="updated != null">
Updated,
</if>
<if test="updatedby != null">
UpdatedBy,
</if>
<if test="version != null">
Version,
</if>
<if test="clientversion != null">
ClientVersion,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=INTEGER},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
<if test="description != null">
#{description,jdbcType=VARCHAR},
</if>
<if test="owner != null">
#{owner,jdbcType=CHAR},
</if>
<if test="customer != null">
#{customer,jdbcType=VARCHAR},
</if>
<if test="created != null">
#{created,jdbcType=TIMESTAMP},
</if>
<if test="createdby != null">
#{createdby,jdbcType=VARCHAR},
</if>
<if test="updated != null">
#{updated,jdbcType=TIMESTAMP},
</if>
<if test="updatedby != null">
#{updatedby,jdbcType=VARCHAR},
</if>
<if test="version != null">
#{version,jdbcType=INTEGER},
</if>
<if test="clientversion != null">
#{clientversion,jdbcType=INTEGER},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.chris.persistence.entity.Report">
update [Report]
<set>
<if test="name != null">
Name = #{name,jdbcType=VARCHAR},
</if>
<if test="description != null">
Description = #{description,jdbcType=VARCHAR},
</if>
<if test="owner != null">
Owner = #{owner,jdbcType=CHAR},
</if>
<if test="customer != null">
Customer = #{customer,jdbcType=VARCHAR},
</if>
<if test="created != null">
Created = #{created,jdbcType=TIMESTAMP},
</if>
<if test="createdby != null">
CreatedBy = #{createdby,jdbcType=VARCHAR},
</if>
<if test="updated != null">
Updated = #{updated,jdbcType=TIMESTAMP},
</if>
<if test="updatedby != null">
UpdatedBy = #{updatedby,jdbcType=VARCHAR},
</if>
<if test="version != null">
Version = #{version,jdbcType=INTEGER},
</if>
<if test="clientversion != null">
ClientVersion = #{clientversion,jdbcType=INTEGER},
</if>
</set>
where Id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.chris.persistence.entity.Report">
update [Report]
set Name = #{name,jdbcType=VARCHAR},
Description = #{description,jdbcType=VARCHAR},
Owner = #{owner,jdbcType=CHAR},
Customer = #{customer,jdbcType=VARCHAR},
Created = #{created,jdbcType=TIMESTAMP},
CreatedBy = #{createdby,jdbcType=VARCHAR},
Updated = #{updated,jdbcType=TIMESTAMP},
UpdatedBy = #{updatedby,jdbcType=VARCHAR},
Version = #{version,jdbcType=INTEGER},
ClientVersion = #{clientversion,jdbcType=INTEGER}
where Id = #{id,jdbcType=INTEGER}
</update>
</mapper>
OK, 写到这里应该明白MyBatis的最核心部分是mapper.xml。
对接触MyBatis时间不长的人来说,最快的办法是有个现成的mapper.xml在那可供参考,然后慢慢熟悉mapper.xml的语法和写法,而不是详细的阅读mapper.xml如何写。
有个mybatis generator工具,可以用来帮助生成mapper.xml。
添加maven依赖:
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>
添加对应的配置文件generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<properties resource="persistence.properties"/>
<context id="default" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressDate" value="true"/>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<jdbcConnection
driverClass="${jdbc.driverClassName}"
connectionURL="${jdbc.url}"
userId="${jdbc.user}"
password="${jdbc.password}">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<javaModelGenerator targetPackage="com.chris.persistence.entity"
targetProject="src/main/java">
<property name="enableSubPackages" value="false"/>
<property name="constructorBased" value="true"/>
<property name="trimStrings" value="true"/>
<property name="immutable" value="false"/>
</javaModelGenerator>
<sqlMapGenerator targetPackage="mapper"
targetProject="src/main/resources">
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<javaClientGenerator targetPackage="com.chris.persistence.dao"
targetProject="src/main/java" type="XMLMAPPER">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator> <table tableName="User" domainObjectName="User"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<table tableName="Resource" domainObjectName="Resource"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<table tableName="Version" domainObjectName="Version"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<table tableName="Report" domainObjectName="Report"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<table tableName="Report_Access" domainObjectName="Report_Access"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
</context>
</generatorConfiguration>
用maven build, mybatis-generator:generate -e

之后生成dao和entity

在使用mybatis generator工具时,每次运行mybatis-generator:generate -e,dao和entity会被覆盖,但mapper.xml则是追加的方式被修改,所以注意在mybatis-generator之前删除mapper.xml文件。
OK, 总的来说,在使用MyBatis做ORM框架时,dao作为entity和DB record的桥梁,而关于java bean和database row的mapping信息则通过mapper.xml获得。

在MyBatis中,sql写在mapper.xml文件中,而且重点在于如何利用好resultMap和动态sql。
内容总结:
(1) MyBatis配置; (2) MyBatis与Spring整合; (3) Mybatis generator使用
Done!
MyBatis随笔的更多相关文章
- mybatis随笔二之SqlSessionFactory
在上一篇文章我们已经得到了DefaultSqlSessionFactory @Override public SqlSession openSession() { return openSession ...
- mybatis随笔一之SqlSessionFactoryBuilder
SqlSessionFactoryBuilder是构建sqlSessionFactory的入口类 从该类的方法可知,它是通过不同的入参来构造SqlSessionFactory,除了最后一个config ...
- mybatis随笔三之SqlSession
在上一篇文章我们已经得到了DefaultSqlSession,接下来我们对sqlSession.getMapper(DemoMapper.class)这种语句进行分析 @Override public ...
- mybatis随笔四之MapperProxy
在上一篇文章我们已经得到了mapper的代理对象,接下来我们对demoMapper.getDemo(1)这种语句进行分析.由于返回的mapper是个代理对象,因此会进入invoke方法,接下来我们来看 ...
- mybatis随笔五之Executor
在上一篇文章我们分析到了mapper接口方法的实现实际上是交由代理类来实现的,并最终调用Executor来查询,接下来我们对executor.query(ms, wrapCollection(para ...
- 关于Mybatis的一些随笔
Mapper.xml头文件 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http:/ ...
- 数据缓存Cache
在MyBatis - 随笔分类 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中有关于Mybatis中Cache技术实现及应用介绍.Cache技术实现都是implements Cache ...
- 2018-01-08 学习随笔 SpirngBoot整合Mybatis进行主从数据库的动态切换,以及一些数据库层面和分布式事物的解决方案
先大概介绍一下主从数据库是什么?其实就是两个或N个数据库,一个或几个主负责写(当然也可以读),另一个或几个从只负责读.从数据库要记录主数据库的具体url以及BigLOG(二进制日志文件)的参数.原理就 ...
- springboot学习随笔(四):Springboot整合mybatis(含generator自动生成代码)
这章我们将通过springboot整合mybatis来操作数据库 以下内容分为两部分,一部分主要介绍generator自动生成代码,生成model.dao层接口.dao接口对应的sql配置文件 第一部 ...
随机推荐
- Jmeter插件之PerfMon监控插件使用说明
PerfMon是Jmeter用来监控系统资源的一款插件,可以用来监控系统的cpu.内存.I/O等性能指标. 首先是Jmeter的插件安装,需要先下载JMeter Plugins Manager这个插件 ...
- Qt如何学习(参考官方文档)
Designers who are familiar with web development can start with QML 一共有四种安装工具 You have following opti ...
- (转)NSArray类的使用
NSArray的基本应用总结 NSString *string1 = @"two"; NSString *string2 = @"one"; //创建数组 NS ...
- linux下批量更改一个目下的目录和文件的权限
对于网站目录我们一般设置目录的权限是755, 而文件的权限是644 ,上传目录另设 比如我们要设置web目录下的所有目录的权限是755,文件的目录是644,那么我们可以批量修改吗?答案是肯定的, 就 ...
- 【视频】 Linux高级程序设计01.2开发平台及Linux环境限制
[课程笔记] Linux环境限制 遵循规范,使用现有资源,明确系统限制,增量开发. (1)规范问题 编码的规范,让程序更易读.Linux编码规范. “见着如意”:变量,函数命名等能够让人看到名称就知道 ...
- 【Node.js】4.从一个例子切入Node js的规范
在开始之前,需要明确的一点就是, ①Node应用是由模块组成的,每一个文件都是一个模块,有自己的作用域. ②在这个文件里定义的变量,函数,类都是私有的,对其他的文件不可见. ③在一个文件中,也就是在一 ...
- apache2.2 到 2.4后配置文件需要更改的部分
参考: http://www.dotblogs.com.tw/maple ... e24_httpd_conf.aspx 1. 访问控制2.2 的时候Order deny,allowDeny fro ...
- C++之类成员所占内存大小问题总结
1.空类所占字节数为1,可见代码如下 #include <iostream> using namespace std; class Parent { }; class Child:publ ...
- C++中的类所占内存空间+继承中的成员访问控制
C++学习之继承中的成员访问控制 C++中的类所占内存空间总结
- Section Formula
https://brilliant.org/wiki/section-formula/