MyBatis 注解和Provider注解(动态构建SQL)使用

      MyBatis 是一个 XML 驱动的框架。配置信息是基于 XML 的,到了MyBatis 3  有了基于注解配置,Java 注解的的表达力和灵活性十分有限,项目中有看到使用注解,简单记录下

      参考文档:https://mybatis.org/mybatis-3/zh/java-api.html#

注解可以简化Mapper映射文件,但是动态Sql依然使用mapper文件。注意:

     1)使用注解时,mybatis-config.xml中元素使用或者

          
        
        
    

     2)Mapper映射文件和注解是可以共同存在的。但是对于接口中的一个方法,注解和xml只能选择使用一个

一、注解CRUD实例

        MyBatis入门CRUD和全局配置文件 之前的这篇文章基础上改用注解

    MyBatis 注解和Provider注解(动态构建SQL)使用_第1张图片

    1、UserMapper接口:

import cn.jq.jqmybatis.model.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface UserMapper {
    @Select("select id, username, reg_date from t_user where id = #{id}")
    @Results(id = "userResultMap", value = {
            @Result(column = "id", property = "id"),
            @Result(column = "username", property = "username"),
            @Result(column = "reg_date", property = "regDate"),
    })
    User getUser(Long id);

    @Select("select * from t_user")
    List listAll();

    @Select("select * from t_user where id >= #{id} order by ${orderby}")
    List listByParam(@Param("id") Long id, @Param("orderby") String orderby);

    @Insert("insert into t_user(username, pazzword, salary, reg_date) value (#{username}, #{pazzword}, #{salary}, #{regDate})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(User user);

    @Update("update t_user set username = #{username}, reg_date = #{regDate} where id = #{id}")
    int update(User user);

    @Delete("delete from t_user where id = #{id}")
    int delete(@Param("id") Long id);
}

    UserMapper.xml 删除接口中方法对应的 id 操作

    2、测试类:OK

public class App {

    @Test
    public void testGet() throws Exception {
        SqlSession session = MyBatisUtil.getSession();
        UserMapper userMapper = session.getMapper(UserMapper.class);
        User user = userMapper.getUser(3L);
        System.out.println(user);
        session.close();
    }

    @Test
    public void testListAll() throws Exception {
        SqlSession session = MyBatisUtil.getSession();
        UserMapper userMapper = session.getMapper(UserMapper.class);
        List list = userMapper.listAll();
        list.forEach(user -> {
            System.out.println(user);
        });
        session.close();
    }

    @Test
    public void testListByParam() throws Exception {
        SqlSession session = MyBatisUtil.getSession();
        UserMapper userMapper = session.getMapper(UserMapper.class);
        List list = userMapper.listByParam(1L, "id desc");
        list.forEach(user -> {
            System.out.println(user);
        });
        session.close();
    }

    @Test
    public void testInsert() throws Exception {
        SqlSession session = MyBatisUtil.getSession();
        User user = new User();
        user.setUsername("asda");
        user.setPazzword("123456");
        user.setSalary(new BigDecimal(99.99));
        user.setRegDate(new Date());
        UserMapper userMapper = session.getMapper(UserMapper.class);
        userMapper.insert(user);
        // 提交事务
        session.commit();
        System.out.println(user.getId()); // 7
        session.close();
    }

    @Test
    public void testUpdate() throws Exception {
        SqlSession session = MyBatisUtil.getSession();
        User user = new User();
        user.setId(6L);
        user.setUsername("asda@");
        user.setRegDate(new Date());
        UserMapper userMapper = session.getMapper(UserMapper.class);
        userMapper.update(user);
        // 提交事务
        session.commit();
        session.close();
    }

    @Test
    public void testDelete() throws Exception {
        SqlSession session = MyBatisUtil.getSession();
        UserMapper userMapper = session.getMapper(UserMapper.class);
        userMapper.delete(7L);
        // 提交事务
        session.commit();
        session.close();
    }
}

二、Provider注解,构建动态 SQL

       用自定义的XxxProvider类构造SQL语句,该类无需继承实现其他类

Provider注解中提供了两个必填属性 type和method.

     type 属性用于指定构建SQL语句的类

     method 属性用于指定类中要执行构建SQL语句的方法,方法返回值(执行的SQL语句)必须是String类型。

    MyBatis 注解和Provider注解(动态构建SQL)使用_第2张图片

1、BaseDao接口:通用的,其他XxxMapper接口可继承它

import cn.jq.jqmybatis.model.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

public interface BaseDao {
    @SelectProvider(type = BaseDaoSqlProvider.class, method = "get")
    User get(Class clazz, @Param("id") Long id);

    @SelectProvider(type = BaseDaoSqlProvider.class, method = "listAll")
    List listAll(Class clazz);

    // 传参的话必须使用 Map类型
    @SelectProvider(type = BaseDaoSqlProvider.class, method = "listByParam")
    List listByParam(Class clazz, Map paramCon);

    @InsertProvider(type = BaseDaoSqlProvider.class, method = "insert")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(T entity);

    @UpdateProvider(type = BaseDaoSqlProvider.class, method = "update")
    int update(T entity);

    @DeleteProvider(type = BaseDaoSqlProvider.class, method = "delete")
    int delete(Class clazz, @Param("id") Long id);
}

2、UserMapper接口继承BaseDao接口,可以写自己的复杂方法

public interface UserMapper extends BaseDao{
}

3、自定义的XxxProvider类:BaseDaoSqlProvider类

import org.apache.ibatis.jdbc.SQL;

import java.lang.reflect.Field;
import java.util.Map;

/**
 * 只管构建动态SQL语句(占位符?),可以使用反射来实现,达到BaseDao通用的简单CRUD
 * MyBatis中底层通过 OGNL表达式实现参数与占位符?的完成
 */
public class BaseDaoSqlProvider {

    /**
     * 有特殊需求的可以使用自定义注解完成,比如:@Tabel @Id @GenerationType @Column @Transient等
     * 这里 简单处理下
     *
     * @param bean
     * @return 构建动态SQL语句
     */
    public String insert(Object bean) {
        Class clazz = bean.getClass();
        System.out.println("insert=" + clazz); // insert=class cn.jq.jqmybatis.model.User
        String tablename = "t_" + clazz.getSimpleName();

        SQL sql = new SQL();
        sql.INSERT_INTO(tablename);

        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            String propertyName = field.getName();
            String columnName = field.getName();
            if ("regDate".equals(propertyName)) {
                columnName = "reg_date";
            }
            try {
                // 属性都没有值时会报错:SQL语法错误
                if (field.get(bean) != null && !"".equals(field.get(bean))) {
                    sql.VALUES(columnName, "#{" + propertyName + "}");
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return sql.toString();
    }

    public String update(Object bean) {
        Class clazz = bean.getClass();
        System.out.println("update=" + clazz); //

        String tablename = "t_" + clazz.getSimpleName();

        SQL sql = new SQL();
        sql.UPDATE(tablename);

        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            String propertyName = field.getName();
            String columnName = field.getName();
            if ("regDate".equals(propertyName)) {
                columnName = "reg_date";
            }
            if ("id".equals(propertyName)) {
                sql.WHERE(columnName + " = #{" + propertyName + "}");
            } else {
                // 修改所有属性值
                sql.SET(columnName + " = #{" + propertyName + "}");
            }
        }
        return sql.toString();
    }

    public String delete(Class clazz) {
        String tablename = "t_" + clazz.getSimpleName();

        SQL sql = new SQL();
        sql.DELETE_FROM(tablename);

        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            String propertyName = field.getName();
            String columnName = field.getName();
            if ("id".equals(propertyName)) {
                sql.WHERE(columnName + " = #{" + propertyName + "}");
            }
        }
        return sql.toString();
    }

    public String get(Class clazz) {
        String tablename = "t_" + clazz.getSimpleName();

        SQL sql = new SQL();
        // 简单处理,用 * 代替列名
        sql.SELECT("*").FROM(tablename);
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            String propertyName = field.getName();
            String columnName = field.getName();
            if ("id".equals(propertyName)) {
                sql.WHERE(columnName + " = #{" + propertyName + "}");
            }
        }
        return sql.toString();
    }

    public String listAll(Class clazz) {
        String tablename = "t_" + clazz.getSimpleName();

        SQL sql = new SQL();
        // 简单处理,用 * 代替列名
        sql.SELECT("*").FROM(tablename);
        return sql.toString();
    }

    public String listByParam(Class clazz, Map paramCon) {
        String tablename = "t_" + clazz.getSimpleName();

        SQL sql = new SQL();
        // 简单处理,用 * 代替列名
        sql.SELECT("*").FROM(tablename);

        // 这里对Map 简单处理,Map的key规定:条件_属性名
        paramCon.forEach((key, value) -> {
            String param = this.paramCon(key, value);
            if (param != null) {
                sql.WHERE(param);
            }
        });
        return sql.toString();
    }

    // 处理Map集合条件sql
    public String paramCon(String key, String value) {
        String[] s = key.split("_");
        if ("LIKES".equals(s[0])) {
            return s[1] + " like '%" + value + "%' ";
        }
        if ("EQS".equals(s[0])) {
            return s[1] + " = '" + value + "' ";
        }
        if ("EQL".equals(s[0])) {
            return s[1] + " = " + value + " ";
        }
        if ("LTL".equals(s[0])) {
            return s[1] + " <= " + value + " ";
        }
        if ("GTL".equals(s[0])) {
            return s[1] + " >= " + value + " ";
        }
        return null;
    }
}

4、测试类:OK

public class App {

    @Test
    public void testGet() throws Exception {
        SqlSession session = MyBatisUtil.getSession();
        UserMapper userMapper = session.getMapper(UserMapper.class);
        User user = userMapper.get(User.class, 3L);
        System.out.println(user);
        session.close();
    }

    @Test
    public void testListAll() throws Exception {
        SqlSession session = MyBatisUtil.getSession();
        UserMapper userMapper = session.getMapper(UserMapper.class);
        List list = userMapper.listAll(User.class);
        list.forEach(user -> {
            System.out.println(user);
        });
        session.close();
    }

    @Test
    public void testListByParam() throws Exception {
        SqlSession session = MyBatisUtil.getSession();
        UserMapper userMapper = session.getMapper(UserMapper.class);
        Map map = new HashMap<>();
        map.put("GTL_id","3");
        map.put("LIKES_username","@");

        List list = userMapper.listByParam(User.class, map);
        list.forEach(user -> {
            System.out.println(user);
        });
        session.close();
    }

    @Test
    public void testInsert() throws Exception {
        SqlSession session = MyBatisUtil.getSession();
        User user = new User();
        user.setUsername("asda");
        user.setPazzword("123456");
        user.setSalary(new BigDecimal(99.99));
        user.setRegDate(new Date());
        UserMapper userMapper = session.getMapper(UserMapper.class);
        userMapper.insert(user);
        // 提交事务
        session.commit();
        System.out.println(user.getId()); // 12
        session.close();
    }

    @Test
    public void testUpdate() throws Exception {
        SqlSession session = MyBatisUtil.getSession();
        User user = new User();
        user.setId(11L);
        user.setUsername("asda@121");
        user.setSalary(new BigDecimal("98.99"));
        UserMapper userMapper = session.getMapper(UserMapper.class);
        userMapper.update(user);
        // 提交事务
        session.commit();
        session.close();
    }

    @Test
    public void testDelete() throws Exception {
        SqlSession session = MyBatisUtil.getSession();
        UserMapper userMapper = session.getMapper(UserMapper.class);
        userMapper.delete(User.class, 12L);
        // 提交事务
        session.commit();
        session.close();
    }
}

      MyBatis 注解和Provider注解(动态构建SQL)使用_第3张图片 

     MyBatis 注解和Provider注解(动态构建SQL)使用_第4张图片

    站在前辈的肩膀上,每天进步一点点

ends ~

 

你可能感兴趣的:(#,MyBatis,MyBatis)