记一次数据持久层的问题

霸气de小男生 提交于 2020-03-12 07:39:38

Mapper父类的方法:

/**
 * 根据表名和ID获取对象
 * @param tableName 表名
 * @param id ID
 * @return 对象信息
 */
@Select(value = {"<script>" +
        " Select * from  ${tableName} where id=#{id}"+
        " </script>"})
Map getObjById(@Param("tableName") String tableName, @Param("id") String id);

实体的父类:

   @Data
@Slf4j
@MappedSuperclass
@EqualsAndHashCode(callSuper=false)
public class BaseBean implements Serializable {

    @Id
    @Column(name = "id",length = 36)//主键i
    private String id;

    @Column(name = "name",length = 255 )//名字
    private String name;

    @Column(name = "data",length = 5000 )//配置化参数
    private String data;

    @Column(name = "is_delete",length = 5 )//是否删除(0-不删除,1-删除)
    private Boolean isDelete;

    @Column(name = "create_time" )//创建时间
    private Date createTime;

    @Column(name = "update_time" )//最后修改时间
    private Date updateTime;


    /**
     *
     * 获得表名的方法
     * @return 表名
     * @throws ClassNotFoundException
     */
     public String getTableName(){
         //定义表名
         String tableName=null;

         //获得对象类
         Class<?> clazz =this.getClass();
        try{
            //获得注解类
            Table table=clazz.getAnnotation(Table.class);
            //获取表名
            tableName=table.name();

        }catch (Exception e){
//            log.error("异常{{}}",e);
        }

            return tableName;
     }
}

方法如上。
原先的想法是写一个父类,让其他的Mapper去继承这个父类,那么只要传入相对应}的
表名和id,通过Map进行接收。
而所有的实体又继承了提供获取当前表名方法的父类。这样只需要提供ID和目标类,就可以查询出对应数据。

问题:在MyBatis中,#{Param}是预编译,${Param}是后续编译。
预编译的情况下,实现生成SQL语句,参数则通过占位符代替。可能是出于安全的考虑,表名无法在预编译的情况使用占位符。上文代码只能使用后续编译,但后续编译又容易引起SQL注入,安全隐患极大。

一开始为了提出公共方法,所以编写了这个方法。通过反射机制拿出对应的属性。后面写这突然发现JPA以及Hibernate框架的的用法和我使用这个方法有点像。想起了JPA以及Hibernate框架的原理也是利用反射,这个方法就在自己搭建的服务中保留了。学习使用

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!