正当我疯狂地学习hibernate的时候,接到新项目的电话面试,说底层用的是Mybatis.因为只是听说过,在学习Hibernate的时候,也接触过一些理论方面的东西,因为都属于ORM框架,对两者进行过简单的比较,但都是偏向于Hibernate的角度。所以说,自己对Mybatis可以说是几乎什么都不知道。
现在还记得那天接到面试电话时的场景,听到Mybatis,很熟悉,但其实是很陌生。关于mybatis,问
的一个问题就是:mybatis的使用方式?因为没有使用过,当然回答的是不知道了。接完面试的电话之
后,自己就开始上网寻找答案。
Mybatis的使用方式包括两种:基于传统方式statementid;基于mapper接口方式调用。答案很具体,但对自己来说,很抽象,因为没有任何接触。
那天,闲着没事,自己又查了查关于Hibernate与Mybatis的比较问题。总结如下:
1. Hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简单很容易上手,但也相对简陋些。
2. Hibernate 与Mybatis都是流行的持久层开发框架,但Hibernate开发社区相对多热闹些,支持的工具也多,更新也快,当前最高版本4.1.8。
而Mybatis相对平静,工具较少,当前最高版本3.2。
3. Hibernate和MyBatis都有相应的代码生成工具。可以生成简单基本的DAO层方法。
4. 针对高级查询,Mybatis需要手动编写SQL语句,以及ResultMap。而Hibernate有良好的映射机
制,开发者无需关心SQL的生成与结果映射,可以更专注于业务流程。
至今,自己仍然记得当时对Mybatis有着很大的一个疑问:居然要将SQL写在配置文件里,这是多么麻
烦的一件事情,要是让我开发,我看都不想看了吧。
而如今,接触底层用mybatis的这个项目近两个月了,我对mybatis有了实践之后,不得不说一句自己很片面呀。下面就简单看看mybatis的使用:
有一个好的开发工具,真的可以节省很多工作量。使用mybatis的代码生成工具,
mybatis generator,
Dao层的代码都不用我们写了,并且很大程度上都能满足我们的开发需要。
每个表生成对应的文件包括:~Mapper.java文件/~.java文件/~Example.java文件以及~Mapper.xml文件。下面是某数据库表生成的对应的四个文件代码如下:
- //广告地区实体,与数据库表对应
- package com.gac.adv.entity;
- import com.gac.core.entity.BaseEntity;
- import javax.validation.constraints.*;
- public class AdvertRegion extends BaseEntity {
- /**
- * 广告id
- */
- private Long advId;
- /**
- * 地区id
- */
- private Long regionId;
- /**
- * 是否删除0-否;1-是
- */
- private Boolean isDeleted;
- /**
- * nullable:false,length:19
- */
- @NotNull
- public Long getAdvId() {
- return advId;
- }
- public void setAdvId(Long advId) {
- this.advId = advId;
- }
- /**
- * nullable:false,length:19
- */
- @NotNull
- public Long getRegionId() {
- return regionId;
- }
- public void setRegionId(Long regionId) {
- this.regionId = regionId;
- }
- /**
- * nullable:false,length:0
- */
- @NotNull
- public Boolean getIsDeleted() {
- return isDeleted;
- }
- public void setIsDeleted(Boolean isDeleted) {
- this.isDeleted = isDeleted;
- }
- }
- //广告地区实体对应的Example
- package com.gac.adv.entity.example;
- import com.gac.core.entity.example.AbstractExample;
- import com.gac.core.entity.example.GeneratedCriteria;
- import java.util.List;
- public class AdvertRegionExample extends AbstractExample {
- @Override
- public Criteria or() {
- return (Criteria)super.or();
- }
- @Override
- public Criteria createCriteria() {
- return (Criteria)super.createCriteria();
- }
- @Override
- protected Criteria createCriteriaInternal() {
- return new Criteria();
- }
- public class Criteria extends GeneratedCriteria {
- protected Criteria() {
- super();
- }
- public Criteria andAdvIdIsNull() {
- addCriterion("adv_id is null");
- return (Criteria) this;
- }
- public Criteria andAdvIdIsNotNull() {
- addCriterion("adv_id is not null");
- return (Criteria) this;
- }
- public Criteria andAdvIdEqualTo(Long value) {
- addCriterion("adv_id =", value, "advId");
- return (Criteria) this;
- }
- public Criteria andAdvIdNotEqualTo(Long value) {
- addCriterion("adv_id <>", value, "advId");
- return (Criteria) this;
- }
- public Criteria andAdvIdGreaterThan(Long value) {
- addCriterion("adv_id >", value, "advId");
- return (Criteria) this;
- }
- public Criteria andAdvIdGreaterThanOrEqualTo(Long value) {
- addCriterion("adv_id >=", value, "advId");
- return (Criteria) this;
- }
- public Criteria andAdvIdLessThan(Long value) {
- addCriterion("adv_id <", value, "advId");
- return (Criteria) this;
- }
- public Criteria andAdvIdLessThanOrEqualTo(Long value) {
- addCriterion("adv_id <=", value, "advId");
- return (Criteria) this;
- }
- public Criteria andAdvIdIn(List<Long> values) {
- addCriterion("adv_id in", values, "advId");
- return (Criteria) this;
- }
- public Criteria andAdvIdNotIn(List<Long> values) {
- addCriterion("adv_id not in", values, "advId");
- return (Criteria) this;
- }
- public Criteria andAdvIdBetween(Long value1, Long value2) {
- addCriterion("adv_id between", value1, value2, "advId");
- return (Criteria) this;
- }
- public Criteria andAdvIdNotBetween(Long value1, Long value2) {
- addCriterion("adv_id not between", value1, value2, "advId");
- return (Criteria) this;
- }
- public Criteria andRegionIdIsNull() {
- addCriterion("region_id is null");
- return (Criteria) this;
- }
- public Criteria andRegionIdIsNotNull() {
- addCriterion("region_id is not null");
- return (Criteria) this;
- }
- public Criteria andRegionIdEqualTo(Long value) {
- addCriterion("region_id =", value, "regionId");
- return (Criteria) this;
- }
- public Criteria andRegionIdNotEqualTo(Long value) {
- addCriterion("region_id <>", value, "regionId");
- return (Criteria) this;
- }
- public Criteria andRegionIdGreaterThan(Long value) {
- addCriterion("region_id >", value, "regionId");
- return (Criteria) this;
- }
- public Criteria andRegionIdGreaterThanOrEqualTo(Long value) {
- addCriterion("region_id >=", value, "regionId");
- return (Criteria) this;
- }
- public Criteria andRegionIdLessThan(Long value) {
- addCriterion("region_id <", value, "regionId");
- return (Criteria) this;
- }
- public Criteria andRegionIdLessThanOrEqualTo(Long value) {
- addCriterion("region_id <=", value, "regionId");
- return (Criteria) this;
- }
- public Criteria andRegionIdIn(List<Long> values) {
- addCriterion("region_id in", values, "regionId");
- return (Criteria) this;
- }
- public Criteria andRegionIdNotIn(List<Long> values) {
- addCriterion("region_id not in", values, "regionId");
- return (Criteria) this;
- }
- public Criteria andRegionIdBetween(Long value1, Long value2) {
- addCriterion("region_id between", value1, value2, "regionId");
- return (Criteria) this;
- }
- public Criteria andRegionIdNotBetween(Long value1, Long value2) {
- addCriterion("region_id not between", value1, value2, "regionId");
- return (Criteria) this;
- }
- public Criteria andIsDeletedIsNull() {
- addCriterion("is_deleted is null");
- return (Criteria) this;
- }
- public Criteria andIsDeletedIsNotNull() {
- addCriterion("is_deleted is not null");
- return (Criteria) this;
- }
- public Criteria andIsDeletedEqualTo(Boolean value) {
- addCriterion("is_deleted =", value, "isDeleted");
- return (Criteria) this;
- }
- public Criteria andIsDeletedNotEqualTo(Boolean value) {
- addCriterion("is_deleted <>", value, "isDeleted");
- return (Criteria) this;
- }
- public Criteria andIsDeletedGreaterThan(Boolean value) {
- addCriterion("is_deleted >", value, "isDeleted");
- return (Criteria) this;
- }
- public Criteria andIsDeletedGreaterThanOrEqualTo(Boolean value) {
- addCriterion("is_deleted >=", value, "isDeleted");
- return (Criteria) this;
- }
- public Criteria andIsDeletedLessThan(Boolean value) {
- addCriterion("is_deleted <", value, "isDeleted");
- return (Criteria) this;
- }
- public Criteria andIsDeletedLessThanOrEqualTo(Boolean value) {
- addCriterion("is_deleted <=", value, "isDeleted");
- return (Criteria) this;
- }
- public Criteria andIsDeletedIn(List<Boolean> values) {
- addCriterion("is_deleted in", values, "isDeleted");
- return (Criteria) this;
- }
- public Criteria andIsDeletedNotIn(List<Boolean> values) {
- addCriterion("is_deleted not in", values, "isDeleted");
- return (Criteria) this;
- }
- public Criteria andIsDeletedBetween(Boolean value1, Boolean value2) {
- addCriterion("is_deleted between", value1, value2, "isDeleted");
- return (Criteria) this;
- }
- public Criteria andIsDeletedNotBetween(Boolean value1, Boolean value2) {
- addCriterion("is_deleted not between", value1, value2, "isDeleted");
- return (Criteria) this;
- }
- }
- }
- //广告地区Mapper
- package com.gac.adv.dao;
- import java.util.List;
- import com.gac.adv.entity.AdvertRegion;
- import com.gac.adv.entity.example.AdvertRegionExample;
- import com.gac.core.dao.BaseMapper;
- public interface AdvertRegionMapper extends BaseMapper<AdvertRegion, AdvertRegionExample> {
- //自定义的批量插入方法
- void insertBatch(List<AdvertRegion> advertRegion);
- }
- <!-- 广告地区表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.gac.adv.dao.AdvertRegionMapper" >
- <resultMap id="BaseResultMap" type="com.gac.adv.entity.AdvertRegion" >
- <id column="id" property="id" jdbcType="BIGINT" />
- <result column="adv_id" property="advId" jdbcType="BIGINT" />
- <result column="region_id" property="regionId" jdbcType="BIGINT" />
- <result column="is_deleted" property="isDeleted" jdbcType="BIT" />
- <result column="create_by" property="createBy" jdbcType="BIGINT" />
- <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
- <result column="update_by" property="updateBy" jdbcType="BIGINT" />
- <result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
- </resultMap>
- <sql id="Example_Where_Clause" >
- <where >
- <foreach collection="oredCriteria" item="criteria" separator="or" >
- <if test="criteria.valid" >
- <trim prefix="(" suffix=")" prefixOverrides="and" >
- <foreach collection="criteria.criteria" item="criterion" >
- <choose >
- <when test="criterion.noValue" >
- and ${criterion.condition}
- </when>
- <when test="criterion.singleValue" >
- and ${criterion.condition} #{criterion.value}
- </when>
- <when test="criterion.betweenValue" >
- and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
- </when>
- <when test="criterion.listValue" >
- and ${criterion.condition}
- <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
- #{listItem}
- </foreach>
- </when>
- </choose>
- </foreach>
- </trim>
- </if>
- </foreach>
- </where>
- </sql>
- <sql id="Update_By_Example_Where_Clause" >
- <where >
- <foreach collection="example.oredCriteria" item="criteria" separator="or" >
- <if test="criteria.valid" >
- <trim prefix="(" suffix=")" prefixOverrides="and" >
- <foreach collection="criteria.criteria" item="criterion" >
- <choose >
- <when test="criterion.noValue" >
- and ${criterion.condition}
- </when>
- <when test="criterion.singleValue" >
- and ${criterion.condition} #{criterion.value}
- </when>
- <when test="criterion.betweenValue" >
- and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
- </when>
- <when test="criterion.listValue" >
- and ${criterion.condition}
- <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
- #{listItem}
- </foreach>
- </when>
- </choose>
- </foreach>
- </trim>
- </if>
- </foreach>
- </where>
- </sql>
- <sql id="Base_Column_List" >
- id, adv_id, region_id, is_deleted, create_by, create_time, update_by, update_time
- </sql>
- <select id="selectByExample" resultMap="BaseResultMap" parameterType="com.gac.adv.entity.example.AdvertRegionExample" >
- select
- <if test="distinct" >
- distinct
- </if>
- <include refid="Base_Column_List" />
- from cms_adv_region
- <if test="_parameter != null" >
- <include refid="Example_Where_Clause" />
- </if>
- <if test="orderByClause != null" >
- order by ${orderByClause}
- </if>
- <if test="pageStart!=null and pageStart gt -1" >
- limit ${pageStart},${pageSize}
- </if>
- </select>
- <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >
- select
- <include refid="Base_Column_List" />
- from cms_adv_region
- where id = #{id,jdbcType=BIGINT}
- </select>
- <delete id="deleteByPrimaryKey" parameterType="java.lang.Long" >
- delete from cms_adv_region
- where id = #{id,jdbcType=BIGINT}
- </delete>
- <delete id="deleteByExample" parameterType="com.gac.adv.entity.example.AdvertRegionExample" >
- delete from cms_adv_region
- <if test="_parameter != null" >
- <include refid="Example_Where_Clause" />
- </if>
- </delete>
- <insert id="insert" parameterType="com.gac.adv.entity.AdvertRegion">
- insert into cms_adv_region (id, adv_id, region_id,
- is_deleted, create_by, create_time,
- update_by, update_time)
- values (#{id,jdbcType=BIGINT}, #{advId,jdbcType=BIGINT}, #{regionId,jdbcType=BIGINT},
- #{isDeleted,jdbcType=BIT}, #{createBy,jdbcType=BIGINT}, #{createTime,jdbcType=TIMESTAMP},
- #{updateBy,jdbcType=BIGINT}, #{updateTime,jdbcType=TIMESTAMP})
- </insert>
- <insert id="insertSelective" parameterType="com.gac.adv.entity.AdvertRegion" >
- insert into cms_adv_region
- <trim prefix="(" suffix=")" suffixOverrides="," >
- <if test="id != null" >
- id,
- </if>
- <if test="advId != null" >
- adv_id,
- </if>
- <if test="regionId != null" >
- region_id,
- </if>
- <if test="isDeleted != null" >
- is_deleted,
- </if>
- <if test="createBy != null" >
- create_by,
- </if>
- <if test="createTime != null" >
- create_time,
- </if>
- <if test="updateBy != null" >
- update_by,
- </if>
- <if test="updateTime != null" >
- update_time,
- </if>
- </trim>
- <trim prefix="values (" suffix=")" suffixOverrides="," >
- <if test="id != null" >
- #{id,jdbcType=BIGINT},
- </if>
- <if test="advId != null" >
- #{advId,jdbcType=BIGINT},
- </if>
- <if test="regionId != null" >
- #{regionId,jdbcType=BIGINT},
- </if>
- <if test="isDeleted != null" >
- #{isDeleted,jdbcType=BIT},
- </if>
- <if test="createBy != null" >
- #{createBy,jdbcType=BIGINT},
- </if>
- <if test="createTime != null" >
- #{createTime,jdbcType=TIMESTAMP},
- </if>
- <if test="updateBy != null" >
- #{updateBy,jdbcType=BIGINT},
- </if>
- <if test="updateTime != null" >
- #{updateTime,jdbcType=TIMESTAMP},
- </if>
- </trim>
- </insert>
- <insert id="insertBatch" parameterType="java.util.ArrayList" >
- insert into cms_adv_region (adv_id, region_id, is_deleted, create_by, create_time, update_by, update_time)
- values
- <foreach collection="list" index = "index" item = "item" separator="," >
- <trim prefix="(" suffix=")" suffixOverrides="," >
- <choose>
- <when test="item.advId != null" >
- #{item.advId,jdbcType=BIGINT},
- </when>
- <otherwise>
- '',
- </otherwise>
- </choose>
- <choose>
- <when test="item.regionId != null" >
- #{item.regionId,jdbcType=BIGINT},
- </when>
- <otherwise>
- 0,
- </otherwise>
- </choose>
- <choose>
- <when test="item.isDeleted != null" >
- #{item.isDeleted,jdbcType=BIT},
- </when>
- <otherwise>
- 0,
- </otherwise>
- </choose>
- <choose>
- <when test="item.createBy != null" >
- #{item.createBy,jdbcType=BIGINT},
- </when>
- <otherwise>
- 0,
- </otherwise>
- </choose>
- <choose>
- <when test="item.createTime != null" >
- #{item.createTime,jdbcType=TIMESTAMP},
- </when>
- <otherwise>
- now(),
- </otherwise>
- </choose>
- <choose>
- <when test="item.updateBy != null" >
- #{item.updateBy,jdbcType=BIGINT},
- </when>
- <otherwise>
- 0,
- </otherwise>
- </choose>
- <choose>
- <when test="item.updateTime != null" >
- #{item.updateTime,jdbcType=TIMESTAMP},
- </when>
- <otherwise>
- now(),
- </otherwise>
- </choose>
- </trim>
- </foreach>
- </insert>
- <select id="countByExample" parameterType="com.gac.adv.entity.example.AdvertRegionExample" resultType="java.lang.Integer" >
- select count(*) from cms_adv_region
- <if test="_parameter != null" >
- <include refid="Example_Where_Clause" />
- </if>
- </select>
- <update id="updateByExampleSelective" parameterType="map" >
- update cms_adv_region
- <set >
- <if test="record.id != null" >
- id = #{record.id,jdbcType=BIGINT},
- </if>
- <if test="record.advId != null" >
- adv_id = #{record.advId,jdbcType=BIGINT},
- </if>
- <if test="record.regionId != null" >
- region_id = #{record.regionId,jdbcType=BIGINT},
- </if>
- <if test="record.isDeleted != null" >
- is_deleted = #{record.isDeleted,jdbcType=BIT},
- </if>
- <if test="record.createBy != null" >
- create_by = #{record.createBy,jdbcType=BIGINT},
- </if>
- <if test="record.createTime != null" >
- create_time = #{record.createTime,jdbcType=TIMESTAMP},
- </if>
- <if test="record.updateBy != null" >
- update_by = #{record.updateBy,jdbcType=BIGINT},
- </if>
- <if test="record.updateTime != null" >
- update_time = #{record.updateTime,jdbcType=TIMESTAMP},
- </if>
- </set>
- <if test="_parameter != null" >
- <include refid="Update_By_Example_Where_Clause" />
- </if>
- </update>
- <update id="updateByExample" parameterType="map" >
- update cms_adv_region
- set id = #{record.id,jdbcType=BIGINT},
- adv_id = #{record.advId,jdbcType=BIGINT},
- region_id = #{record.regionId,jdbcType=BIGINT},
- is_deleted = #{record.isDeleted,jdbcType=BIT},
- create_by = #{record.createBy,jdbcType=BIGINT},
- create_time = #{record.createTime,jdbcType=TIMESTAMP},
- update_by = #{record.updateBy,jdbcType=BIGINT},
- update_time = #{record.updateTime,jdbcType=TIMESTAMP}
- <if test="_parameter != null" >
- <include refid="Update_By_Example_Where_Clause" />
- </if>
- </update>
- <update id="updateByPrimaryKeySelective" parameterType="com.gac.adv.entity.AdvertRegion" >
- update cms_adv_region
- <set >
- <if test="advId != null" >
- adv_id = #{advId,jdbcType=BIGINT},
- </if>
- <if test="regionId != null" >
- region_id = #{regionId,jdbcType=BIGINT},
- </if>
- <if test="isDeleted != null" >
- is_deleted = #{isDeleted,jdbcType=BIT},
- </if>
- <if test="createBy != null" >
- create_by = #{createBy,jdbcType=BIGINT},
- </if>
- <if test="createTime != null" >
- create_time = #{createTime,jdbcType=TIMESTAMP},
- </if>
- <if test="updateBy != null" >
- update_by = #{updateBy,jdbcType=BIGINT},
- </if>
- <if test="updateTime != null" >
- update_time = #{updateTime,jdbcType=TIMESTAMP},
- </if>
- </set>
- where id = #{id,jdbcType=BIGINT}
- </update>
- <update id="updateByPrimaryKey" parameterType="com.gac.adv.entity.AdvertRegion" >
- update cms_adv_region
- set adv_id = #{advId,jdbcType=BIGINT},
- region_id = #{regionId,jdbcType=BIGINT},
- is_deleted = #{isDeleted,jdbcType=BIT},
- create_by = #{createBy,jdbcType=BIGINT},
- create_time = #{createTime,jdbcType=TIMESTAMP},
- update_by = #{updateBy,jdbcType=BIGINT},
- update_time = #{updateTime,jdbcType=TIMESTAMP}
- where id = #{id,jdbcType=BIGINT}
- </update>
- </mapper>
有了这些代码,我们就可以直接在业务逻辑层直接写增删改查数据表的代码,如新增一条记录:
- /**
- * 增加广告投放城市
- * @param userId
- * @param advId
- * @param regionIds
- */
- @Transactional(rollbackFor = Exception.class)
- public void addAdvertRegion(Long userId,Long advId,List<Long> regionIds){
- List<AdvertRegion> advertRegions=new ArrayList<AdvertRegion>();
- for (Long regionId : regionIds) {
- AdvertRegion advertRegion=new AdvertRegion();
- advertRegion.setCreateBy(userId);
- advertRegion.setCreateTime(new Date());
- advertRegion.setRegionId(regionId);
- advertRegion.setAdvId(advId);
- advertRegion.setUpdateBy(userId);
- advertRegion.setUpdateTime(new Date());
- advertRegions.add(advertRegion);
- }
- advertRegionMapper.insertBatch(advertRegions);
- }
上面生成的代码,可以满足基本的增删改查,如果是比较复杂的一些操作,如批量更新/插入/复杂的sql等,我们可以自己在Xml中定义一个新的方法即可,也是非常方便的。
在项目的使用过程中,也遇到过一些问题,比如想要获取新插入记录的id,想要按某个字段去排序,想要返回分页的数据,这些都可以从mybatis着手去解决,而且非常简单,并不需要繁琐的代码,繁琐的程序。
现在想想,当你不知道某个东西的时候,真的不能妄下定论,因为,你还不知道等到你了解了接触了它之后,会产生怎样的火花。但我们可以怀疑,可以猜想,这样最后你得到的答案也一定会带给自己更深
刻的感受,就好像当初我对Mybatis的怀疑一样。