Mybatis && Mybatia-plus 注 解

参考网址 :
mybatis中文网
mybatis 多表查询 @Select 注解

mapper接口

public interface UserMapper extends BaseMapper<User> {
	。。。。
}

service 实现 IService 接口 ,impl继承 ServiceImpl 实现 service 接口

public interface 自定义Service extends IService<自定义实体bean> {
	。。。
}

/** 
public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
	。。。。
}
*/

public class 自定义ServiceImpl extends ServiceImpl<自定义Mapper, 自定义实体bean> implements 自定义Service {
	。。。。
}
@Select 注解

@Select 动态参数

    @Select({"<script> SELECT dir.* FROM GE_DIRECTORY dir INNER JOIN GE_PRODUCT_CORRELATION co ON dir.eid=co.RECOMMENDPRODUCT " +
            "<when test='businessarea!=null and businessarea!=\"\" '>"+
            " and dir.BUSINESSAREA=#{businessarea} " +
            "</when>" +
            "<when test='businessarea!=null and businessarea!=\"\" '>"+
            " and dir.language=#{language} " +
            "</when>" +
            "<when test='productEid!=null and productEid!=\"\" '>"+
            " and co.RECOMMENDPRODUCT=#{productEid} " +
            "</when>" +
            "  </script>"})
    List<GeDirectory> findAllRecommend(@Param("language") String language,@Param("businessarea") String businessarea,@Param("productEid") String productEid);

xml 动态sql

where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:

<where>
        <if test="clausecode!=null and clausecode != '' and clausecode.length > 0" >
         and clausecode=#{clausecode}
        </if>
        <if test="validind!=null and validind != '' and validind.length > 0" >
         and validind=#{validind}
        </if>
        <if test="language!=null and language != '' and language.length > 0">
         and language=#{language}
        </if>
    </where>
select
    <include refid="Base_Column_List" />
    from ge_clause
      <trim prefix="where" suffixOverrides="and">
        <if test="clausecode!=null and clausecode != '' and clausecode.length > 0" >
          clausecode=#{clausecode} and
        </if>
        <if test="validind!=null and validind != '' and validind.length > 0" >
          validind=#{validind} and
        </if>
        <if test="language!=null and language != '' and language.length > 0">
          language=#{language}
        </if>
      </trim>
<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
</trim>

prefixOverrides 属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。上述例子会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 属性中指定的内容。

用于动态更新语句的类似解决方案叫做 set。set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。比如:

<update id="updateAuthorIfNecessary">
  update Author
    <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="bio != null">bio=#{bio}</if>
    </set>
  where id=#{id}
</update>

在这里插入图片描述
foreach
动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。比如:

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE ID in
  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>
</select>

foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!

提示 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。

Insert 语句

单个插入

  <insert id="insert" parameterType="类名" >
    insert into 数据库名 (数据库列字段)
    values (#{对象属性}。。。。)
  </insert>

批量插入

在foreach循环中一定要加上 item的变量名,在foreach标签中一定要使用 变量.属性

 <!--批量插入-->
  <insert id="batchInsert" parameterType="java.util.List">
    insert into 数据库名 (数据库列字段)
    values
    <foreach collection="list" item="变量" index="index" separator=",">
    (#{变量.属性)  <!--一定要加上 item 中的 变量-->
    </foreach>
  </insert>
Delete 语句
@Delete("delete from ge_authority where authorityid='${authorityid}'")
    boolean deleteAuthorityById(@Param("authorityid")String authorityid);

@Delete("delete from ge_role where roleid='${roleid}'")
    void deleteRole(@Param("roleid")String roleid);
Update 语句
@Update("update ge_authority set authorityname = #{authorityname},authoritytype = #{authoritytype} , authoritydesp = #{authoritydesp}, authoritylink = #{authoritylink},authorityorder =#{authorityorder},  " +
            "ismenu = #{ismenu},opentype =#{opentype},authoritytname=#{authoritytname},authorityename=#{authorityename} where authorityid = #{authorityid}")
    void updateAuthority(GeAuthority geAuthority);

@Update("update `ge_webflowpageelement` set `STATUS`=1 WHERE COREPRODUCTCODE=#{coreproductcode} and ELEMENTCODE=#{productInfo} ")
    void updateByElement(@Param("coreproductcode") String coreproductcode, @Param("productInfo") String productInfo);
1、在已有类中添加新属性,需添加注解@TableField(exist = false),否则mybatis-plus封装的方法会报错

在传统的crud中,我们查询的结果可能并不是我们需要传递给前端的数据,我们可能需要添加一些属性,再将结果返回给前端页面。比如我们再查询的时候需要查询关联子表,但是与数据库相对应的bean对象并没有这种children或者list属性承接对象,再这种时候要么新建一个类,要么再原有的bean对象上进行修改

在原有bean对象上进行修改,关联查询自定义字段,需要使用注解@TableField(exist=false),即该条属性表示数据库表中不存在的,即mybatis-plus封装方法中sql语句不会使用此字段。自定义中可以使用。

2、自动填充

项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。
我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作:

(1)数据库表中添加自动填充字段
                 在User表中添加datetime类型的新的字段 create_time、update_time

(2)实体上添加注解

@Data
public class User {
    ......

    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    //@TableField(fill = FieldFill.UPDATE)
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}

(3)实现元对象处理器接口
                 注意:不要忘记添加 @Component 注解

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyMetaObjectHandler.class);
    
    @Override
    public void insertFill(MetaObject metaObject) {
        LOGGER.info("start insert fill ....");
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }
    
    @Override
    public void updateFill(MetaObject metaObject) {
        LOGGER.info("start update fill ....");
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }
}
3、错误 Duplicate entry ‘’ for key ‘PRIMARY’
### Error updating database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '' for key 'PRIMARY'
### The error occurred while setting parameters
  。。。。。。。。。。。。。。。
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '' for key 'PRIMARY'
; Duplicate entry '' for key 'PRIMARY'; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '' for key 'PRIMARY'
	at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:243)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)

问题分析 :

xml批量插入会导致主键无法生成。

解决办法:这里推荐 —调用 savaBatch()方法

第一种:普通for循环插入

 @Test

public void testInsertBatch2() throws Exception {
    long start = System.currentTimeMillis();

    User user;

    SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(false);

    UserDao mapper = sqlSession.getMapper(UserDao.class);

    for (int i = 0; i < 500; i++) {
        user = new User();

        user.setId("test" + i);

        user.setName("name" + i);

        user.setDelFlag("0");

        mapper.insert(user);

    }

    sqlSession.commit();

    long end = System.currentTimeMillis();

    System.out.println("---------------" + (start - end) + "---------------");

}


<insert id="insert">

    INSERT INTO t_user (id, name, del_flag)

          VALUES(#{id}, #{name}, #{delFlag})

</insert>

第二种:mybatis BATCH模式插入

@Test

public void testInsertBatch2() throws Exception {
    long start = System.currentTimeMillis();

    User user;

    SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);//跟上述sql区别

    UserDao mapper = sqlSession.getMapper(UserDao.class);

    for (int i = 0; i < 500; i++) {
        user = new User();

        user.setId("test" + i);

        user.setName("name" + i);

        user.setDelFlag("0");

		# 因为继承了ServiceImpl ,所以可以调用 savaBatch()方法 
        mapper.insert(user);
    }

    sqlSession.commit();

    long end = System.currentTimeMillis();

    System.out.println("---------------" + (start - end) + "---------------");

}

<insert id="insert">

    INSERT INTO t_user (id, name, del_flag)

          VALUES(#{id}, #{name}, #{delFlag})

</insert>

第三种:foreach方式插入

@Test

public void testInsertBatch() throws Exception {
    long start = System.currentTimeMillis();

    List<User> list = new ArrayList<>();

    User user;

    for (int i = 0; i < 10000; i++) {
        user = new User();

        user.setId("test" + i);

        user.setName("name" + i);

        user.setDelFlag("0");

        list.add(user);

    }
	
	# 因为继承了ServiceImpl ,所以可以调用 savaBatch()方法 
    userService.insertBatch(list);

    long end = System.currentTimeMillis();

    System.out.println("---------------" + (start - end) + "---------------");

}

 

<insert id="insertBatch">

    INSERT INTO t_user

            (id, name, del_flag)

    VALUES

    <foreach collection ="list" item="user" separator =",">

         (#{user.id}, #{user.name}, #{user.delFlag})

    </foreach >

</insert>
主键策略

(1)ID_WORKER
MyBatis-Plus默认的主键策略是:ID_WORKER 全局唯一ID
参考资料:分布式系统唯一ID生成方案汇总:https://www.cnblogs.com/haoxinyue/p/5208136.html

(2)自增策略

  • 要想主键自增需要配置如下主键策略
    • 需要在创建数据表的时候设置主键自增
    • 实体字段中配置 @TableId(type = IdType.AUTO)
@TableId(type = IdType.AUTO)
private Long id;

要想影响所有实体的配置,可以设置全局主键配置

#全局设置主键生成策略
mybatis-plus.global-config.db-config.id-type=auto

其它主键策略:分析 IdType 源码可知

@Getter
public enum IdType {

    /**
     * 数据库ID自增
     */

    AUTO(0),

    /**
     * 该类型为未设置主键类型
     */

    NONE(1),

    /**
     * 用户输入ID
     * 该类型可以通过自己注册自动填充插件进行填充
     */

    INPUT(2),
    
    /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
   
    /**
     * 全局唯一ID (idWorker)
     */
     
    ID_WORKER(3),
    
    /**
     * 全局唯一ID (UUID)
     */

    UUID(4),
    
    /**
     * 字符串全局唯一ID (idWorker 的字符串表示)
     */

    ID_WORKER_STR(5);

    private int key;

    IdType(int key) {
        this.key = key;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值