mapper implementation of mybatis

 Mybatis is often used in projects, and hibernate was slowly abandoned many years ago.I haven't blogged for a long time since iteye was acquired. This year I want to make up for it by writing more.Today, let's talk about the mapper implementation of mybatis.
   @Component

public interface ActivityMapper {
/**

  • Add prize record
  • @param prizeEntity
  • @return
    */
    int addGift(PrizeEntity prizeEntity);
/**
 * Add Reservation Record
 * @param activityPrevueEntity
 * @return
 */
int addActivityPrevue(ActivityPrevueEntity activityPrevueEntity);

/**
 * Get whether the user has made an appointment based on their mobile number and activity id
 * @param phone
 * @param activityId
 * @return
 */
int countPrevueByPhoneAndActivityId(@Param("phone")String phone, @Param("activityId")Integer activityId);

}

This is a more common way to write mapper classes.In xml we need to define an id that is the same as the method name.

<?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"&gt;
<mapper namespace="cn.vcinema.mapper.ActivityMapper">

<insert id="addGift" parameterType="cn.vcinema.model.PrizeEntity">
    insert into pumpkin_ius.activity_prize_record(user_id, activity_id, prize_code, create_time)
    values(#{userIdInt}, #{activityIdInt}, #{prizeCodeStr}, now())
</insert>

<insert id="addActivityPrevue" parameterType="cn.vcinema.model.ActivityPrevueEntity">
    insert into pumpkin_ius.activity_user_enroll(activity_id, user_id, user_phone, user_name, user_email, create_time)
    values(#{activityId}, #{userId}, #{userPhone}, #{userName}, #{userEmail}, now())
</insert>

<select id="countPrevueByPhoneAndActivityId" resultType="java.lang.Integer">
    select count(*) from pumpkin_ius.activity_user_enroll where user_phone = #{phone} and activity_id = #{activityId}
</select>

</mapper>

Within serviceimpl, we can implement sql execution of xml by calling mapper.

Gift gift = Lottery.lottery(giftList, defaultGift.get(0));
PrizeEntity prizeEntity = setPrizeValue(gift, user.getUserId(), activityId);
// Add a lottery record
activityMapper.addGift(prizeEntity);

You need to provide MyBatis with a Mapper interface and a mapping file to match it so that MyBatis can execute to the appropriate SQL according to our requirements The implementation principle here is dynamic proxy

public class MapperProxy<T> implements InvocationHandler, Serializable {
private static final long serialVersionUID = -6424540398559729838L;
private final SqlSession sqlSession;
private final Class<T> mapperInterface;
private final Map<Method, MapperMethod> methodCache;

public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethod> methodCache) {
    this.sqlSession = sqlSession;
    this.mapperInterface = mapperInterface;
    this.methodCache = methodCache;
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if(Object.class.equals(method.getDeclaringClass())) {
        return method.invoke(this, args);
    } else {
        MapperMethod mapperMethod = this.cachedMapperMethod(method);
        return mapperMethod.execute(this.sqlSession, args);
    }
}

private MapperMethod cachedMapperMethod(Method method) {
    MapperMethod mapperMethod = (MapperMethod)this.methodCache.get(method);
    if(mapperMethod == null) {
        mapperMethod = new MapperMethod(this.mapperInterface, method, this.sqlSession.getConfiguration());
        this.methodCache.put(method, mapperMethod);
    }

    return mapperMethod;
}

}

As you can see in the invoke method, if we are calling a method in Object, call it directly without any processing, otherwise execute:
mapperMethod.execute(this.sqlSession, args);

Here, jdk's dynamic proxy is used to implement automatic invocation.

Sometimes during development, instead of writing xml, we implemented calls directly through annotations and looked at examples.

@Component
public interface FeedbackMapper {
int insert(Feedback feedback);

/**
 * Add user feedback
 * @param userFeedback
 */
@Insert("  INSERT INTO `pumpkin_ius`.`user_feedback`(`phone`, `device`, `pc_device`, `pc_os`, `pc_channel`, `pc_ip`, `pc_platform`, `pc_version`, `pc_browser_name`, `pc_browser_version`, `play_feedback`, `program_feedback`, `other_feedback`) VALUES (#{phone},#{device},#{pc_device},#{pc_os},#{pc_channel},#{pc_ip},#{pc_platform},#{pc_version},#{pc_browser_name},#{pc_browser_version},#{play_feedback},#{program_feedback},#{other_feedback});")
void addUserFeedback(UserFeedback userFeedback);

}

Of course, when SQL L is complex, writing xml is easier to maintain and doesn't seem so uncomfortable.

Tags: Java Mybatis xml SQL Hibernate

Posted on Thu, 07 Nov 2019 10:51:56 -0500 by BrianG