设为首页 收藏本站
查看: 1225|回复: 0

[经验分享] Mybatis使用:Sql Annotation

[复制链接]

尚未签到

发表于 2016-11-25 07:18:43 | 显示全部楼层 |阅读模式
Mybatis使用:Sql Annotation

 

上节我们学习了Mybatis的入门,能够实现简单的CRUD操作,这个算是基本技能了。另外Mybatis提供了SqlAnnotation形式来控制CRUD操作,我们对于数据库的操作也就不外乎这些操作。对于简单的Sql,或者功能简单的Sql来说,将方法和Sql对应起来最为直观,不用根据IdMapper.xml中查找,出问题后还得各种分析。而能够做到这点的就是Annotation操作。
 
下面我们来看下SqlAnnotation操作CRUD
方法还使用上节Mybatis入门时的UserDao操作,将UserDaoMapper.xml中的Sql语句全部删除,只保留基本格式就行。
我们先看下Insert的操作:

@Insert("insert into user(userId,userName,password,comment) values(#{userId},#{userName},#{password},#{comment})")
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
public int insert ( User user );
这个操作有没有和Mapper.xml中的Sql很相似,没错注解@Insert就是干这样的事。
注意@Insert注解中Value的值是个数组,那么下面这个Insert注解也是合法的:

@Insert(value={"insert into user(userId,userName,password,comment) "," values(#{userId},#{userName},#{password},#{comment})"})
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
public int insert ( User user );
mybatis生成Sql语句时,会将数组拼接,生成最终的Sql,不过貌似这个功能不应该这么鸡肋,大家可以仔细思考下这个功能点究竟在什么地方。
@Options注解中的工作就比较有意思,我们在插入记录时,一般是定义主键自增(auto_increment),但是在某些情况下,我们插入一条记录后,还想得到这条记录的自增主键IDuseGeneratedKeys=true就是定义数据库返回主键ID的。
Options中,定义了不少的属性:

  boolean useCache() default true;
boolean flushCache() default false;
ResultSetType resultSetType() default ResultSetType.FORWARD_ONLY;
StatementType statementType() default StatementType.PREPARED;
int fetchSize() default -1;
int timeout() default -1;
boolean useGeneratedKeys() default false;
String keyProperty() default "id";
String keyColumn() default "";
对于这些属性,还是比较好理解的,如useCacheflushCachetimeout等。其中跟主键返回功能相关的属性就是useGeneratedKeyskeyPropertykeyColumn这三个。这个功能在某种情况下还是比较有用的。
对于Options的使用,根据官方文档有个特别重要的注意点:

once you engage the Options annotation, your statement is subject to all of the default values.
如果你使用了这个属性,SQL的执行就会使用Options的默认值,如果你没有重新定义的话。仔细看下keyColumn的默认值是空,这个如果和你数据库设定不一致的话,就会出问题;所以一旦决定使用主键返回功能,推荐同时使用useGeneratedKeyskeyPropertykeyColumn这三个属性,即使是冗余也没有关系。
 
下面看下删除操作:

@Delete("delete from user where userName = #{userName}")
public int delete ( String userName );
这个没有什么特殊的操作,理解了Insert操作之后这个delete操作就比较简单了。
 
更新操作也没有什么问题:

@Update("update user set userId=#{userId},password=#{password},comment=#{comment} where userName=#{userName}")
public int update ( User user );

 

我们现在操作的是对象User,如果User属性比较多,我们只是更新User的单个属性,难道我们再重新生成一个User传进去?
No,我们可以使用下面这种形式的update

@Update("update user set  userName=#{userName} where userId=#{userId}")
public int updateUser(@Param("userName")String userName,@Param("userId")String userId);
我们使用@Param参数,只是传递我们感兴趣的参数即可。
有人可能会有疑问,@Param参数貌似没有什么用,这个参数本身就可以获取的。没错,看下面这种格式的update

@Update("update user set  userName=#{name} where userId=#{Id}")
public int updateUser ( @Param("name") String userName, @Param("Id") String userId );
传入的参数是userName,而在@Param中被重新定义成name,那么在Sql中就可以通过${name}直接使用了,这个实际上是解决函数参数和Sql参数的阻抗不匹配情况。
 
最后我们再看下数据库和POJO阻抗不匹配时的解决方法:

@Select("select * from user order by id asc")
// @Results(value = {
// @Result(property="userId",column="userId",javaType=Integer.class,jdbcType=JdbcType.VARCHAR,typeHandler=UnknownTypeHandler.class),
// @Result(property="name", column="userName"),
// @Result(property="psword", column="password"),
// @Result(property="comment", column="comment")
// })
public List<User> selectAll ();
@Results能够重新定义数据库和POJO之间字段的对应关系,其中每一个属性对应都由Result重新定义,和上面代码中注掉的地方一样。
那么Result能够重新定义哪些字段呢?注意上文代码中注掉的代码仅供演示使用,并无真正实际映射的必要。如JDBCVarchar本身就被映射为String类型。

  boolean id() default false;
String column() default "";
String property() default "";
Class<?> javaType() default void.class;
JdbcType jdbcType() default JdbcType.UNDEFINED;
Class<? extends TypeHandler<?>> typeHandler() default UnknownTypeHandler.class;
One one() default @One;
Many many() default @Many;
其中比较好理解的是columnpropertyjavaTypejdbcType这四个,typeHandler是重新定义JdbcTypejavaType的映射处理handlerTypeHandler的应以和使用参考这里:http://www.mybatis.org/core/zh/configuration.html

The one attribute is for single associations, similar to <association>, and the many attribute is for collections, similar to <collection>. They are named as they are to avoid class naming conflicts.
OneMany属性就是定义字段的对应关系。
 
在注解中还有这四个Provider,他们有什么用呢?

@InsertProvider
@UpdateProvider
@DeleteProvider
@SelectProvider
Mybatis本身提供了SQL Builder功能,SQL Builder功能的介绍参考这里:http://www.mybatis.org/core/statement-builders.html
这四个Provider是用来提供SQL Builder的配置的,会将Sql按照类功能描述的形式表示出来,Provider将这些SQL提供给CRUD执行。
再简单的说,Provider提供了类SQLSQL之间的转换,并提供最终生成的执行SQL
 
这些注解已经能够提供普通SQL语句的替换功能了,如果你的需求比这个还要复杂,那还是使用xml配置为最好。真正能控制SQL和功能之间的协调关系的还是直接写SQL为宜,将SQL统一管理放置也是通用的做法。
 
还有一点:AnnotationXml配置可以同时存在,这个也是必须的。我们有些Sql特别长且功能比较复杂,写在代码里非常不容易管理,因此提供统一的xml管理还是很有必要的。
 
注意本文的注解是mybatis本身提供的,和SpringAOPIoC特性没有关系,我们现在做的就是单独使用mybatis来进行开发。至于mybatisSpring的结合,其实就是将mybatisSqlSessionFactory委托为Spring管理,再加上IoC特性,能在使用时节省不少的代码量。
 
本次的内容就到这里。
 

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-305091-1-1.html 上篇帖子: Mybatis like 模糊查询问题 下篇帖子: mybatis中的#{}和${}的区别
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表