MyBatis 注解配置及动态SQL
一、注解配置
目前MyBatis支持注解配置,用注解方式来替代映射文件,但是注解配置还是有点不完善,在开发中使用比较少,大部分的企业还是在用映射文件来进行配置。不完善的地方体现在于当数据表中的字段名与实体对象的属性名不一致时,需要配置ResultMap,但是注解的配置只能是在方法前,也就是当前方法能使用这个配置,其他的方法是不能应用此注解配置的ResultMap。
注解配置的方式是直接在数据访问接口的方法前加上相应的注解
@select(“select * from student ”)
public List<Student> find();
在MyBatis的主配置文件的mappers节点中注册所有的数据持久化接口类
案例:
数据持久化接口
|
public interface SubjectDao { @Select("select * from subject") @Results({ @Result(id=true,column="subjectNo",property="id"), @Result(column="subjectName",property="subjectName"), @Result(column="classHour",property="hour") }) public List<Subject> find(); } |
MyBatis主配置文件的mappers节点配置
|
<!-- 如果有映射时,对映射文件进行配置 --> <mappers> <!-- 加载单个映射文件,允许映射文件与持久接口类不在同一目录下。 --> <mapper resource="com/icss/mapping/AdminDao.xml"/> <mapper resource="com/icss/mapping/GradeDao.xml"/> <mapper resource="com/icss/mapping/StudentDao.xml"/> <!-- 注解配置时,需要在主配置文件中注册数据持久化接口类 --> <mapper class="com.icss.dao.SubjectDao"/> <!-- 加载这个包中的所有映射文件,要求持久化接口与映射文件必须在同一个目录中 --> <!-- <package name="com.icss.dao"/> --> </mappers> |
当表中的数据行有一对多或多对一的映射关系时的处理方式
一对多:
|
//一对多 : many @Select("select * from grade") @Results( { @Result(id=true, column="gradeId",property="gradeId"), @Result(column="gradeName", property="gradeName"), @Result(column="gradeId",property="subjects", many=@Many(select = "com.etc.dao.SubjectDao.findSubjectByGradeId")) } ) public List<Grade> find(); |
多对一:
|
@Select("select * from subject") @Results({ @Result(id=true,column="subjectNo",property="id"), @Result(column="subjectName",property="subjectName"), @Result(column="classHour",property="hour"), //多对一的情况操作,根据年级编号调用年级的数据持久化接口的方法,返回一个年级对象存储在grade这个属性中。 @Result(column="gradeId",property="grade",one=@One(select="com.icss.dao.GradeDao.getGradeById")) }) public List<Subject> find(); |
数据持久化层代码:
|
package com.icss.dao; import java.util.List; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.One; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import com.icss.entity.Subject; public interface SubjectDao { @Select("select * from subject") @Results({ @Result(id=true,column="subjectNo",property="id"), @Result(column="subjectName",property="subjectName"), @Result(column="classHour",property="hour"), //多对一的情况操作,根据年级编号调用年级的数据持久化接口的方法,返回一个年级对象存储在grade这个属性中。 @Result(column="gradeId",property="grade",one=@One(select="com.icss.dao.GradeDao.getGradeById")) }) public List<Subject> find(); //根据年级查询课程 @Select("select * from subject where gradeId=#{id}") @Results({ @Result(id=true,column="subjectNo",property="id"), @Result(column="subjectName",property="subjectName"), @Result(column="classHour",property="hour"), //多对一的情况操作,根据年级编号调用年级的数据持久化接口的方法,返回一个年级对象存储在grade这个属性中。 @Result(column="gradeId",property="grade",one=@One(select="com.icss.dao.GradeDao.getGradeById")) }) public List<Subject> findByGID(int id); //新增 @Insert("insert into subject(null,#{subjectName},#{hour},#{grade.gradeId})") public int add(Subject subject); //删除 @Delete("delete from subject where subjectNo=#{id}") public int delete(int id); //修改 @Update("update subejct set subjectName=#{subjectName},classHour=#{hour}," + " gradeId=#{grade.gradeId} where subjectNo=#{id}") public int update(Subject subject); } |
在团队开发中,建议统一用其中的一种处理方式,用注解就全部用注解,用映射文件就统一用映射文件。
二、模糊查询
错误的处理方法:
|
<!-- 字段与属性名不一致,不能用resultType属性 --> <select id="getStudents" resultMap="studentMap" parameterType="map"> select * from student <if test="name != null"> where name like '%'+#{name}+'%' </if> </select> |
正确的方式是在参数传入之前就加了这些通配符。
|
sqlSession = SqlSessionFactoryUtil.getsqlSession(); StudentDao dao= sqlSession.getMapper(StudentDao.class); //参数传入到映射文件前就加了模糊查询的通配符 Map<String, String> map = new HashMap<>(); map.put("name", "%张%"); //调用方法,执行查询 list=dao.getStudents(map); 映入文件如下: <!-- 字段与属性名不一致,不能用resultType属性 --> <select id="getStudents" resultMap="studentMap" parameterType="map"> select * from student <if test="name != null"> where name like #{name} </if> </select> |
三、动态SQL
MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力,也是MyBatis最有特色的地方,就是它的动态SQL,解决了我们多条件时SQL指令的拼接问题。查询学生信息:条件可能(姓名,年龄,年级,性别,地址)
通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语 言来改进这种情形,这种语言可以被用在任意映射的 SQL 语句中。 动态SQL非常简单,与JSTL的使用非常类似。
if:当条件成立时,则把内部的SQL拼接到外部的SQL指令中。
|
<!-- 字段与属性名不一致,不能用resultType属性 --> <select id="getStudents" resultMap="studentMap" parameterType="map"> select * from student <if test="name != null"> where name like #{name} </if> </select> |
choose, when, otherwise:
这是一个多重if-else结构,如果只有一个when和otherwise,则可以认为是if-else结构
|
<!-- 字段与属性名不一致,不能用resultType属性 --> <select id="getStudents" resultMap="studentMap" parameterType="map"> select * from student <choose> <when test="name != null"> where name like #{name} </when> <otherwise> where age > #{age} </otherwise> </choose> </select> |
where:
当条件比较多的时候,要进行条件拼接,where的作用是进行条件拼接,自动加上where 关键字,而且会把多余的and 或 or 这些连接关键字去掉。
|
<!-- 字段与属性名不一致,不能用resultType属性 --> <select id="getStudents" resultMap="studentMap" parameterType="map"> select * from student <where> <if test="name != null"> and name like #{name} </if> <if test="age != null"> and age > #{age} </if> </where> </select> 拼接后的SQL: select * from student where and name like '%张%' and age > 22 标红的 and 会自动去掉. |
set: 用于修改的SQL指令
在修改的SQL指令中自动加上set关键字,同时把多余的逗号(,)去掉。非常适合部分值
|
<update id="update" parameterType="map"> update student <set> <if test="name != null"> name=#{name}, </if> <if test="age != null"> age=#{age}, </if> <if test="sex != null"> sex=#{sex}, </if> <if test="phone != null"> phone=#{phone} </if> </set> where studentNo=1002 </update> 拼接后的SQL: update student set name='肖月月',age=20,sex='女' where studentNo=1002 |
foreach
这个动态 SQL 通用的必要操作是迭代一个集合, 通常是构建在 IN 条件中.
|
<select id="getStudents1" resultMap="studentMap" parameterType="list"> select * from student where address in <foreach item="s" collection="list" open="(" close=")" separator=","> #{s} </foreach> </select> |
业务层处理:
|
sqlSession = SqlSessionFactoryUtil.getsqlSession(); StudentDao dao= sqlSession.getMapper(StudentDao.class); List<String> arr = new ArrayList<String>(); arr.add("广州市"); arr.add("深圳市"); //调用方法,执行查询 list=dao.getStudents1(arr); |
MyBatis 注解配置及动态SQL的更多相关文章
- mybatis注解开发,动态sql
在利用mybatis注解开始时,如果没有用到动态sql时,可以直接写 @Select("select * from order") List<XlSubOrder> g ...
- 08—mybatis注解配置二
动态sql mybatis的注解也支持动态sql.mybatis提供了各种注解,如@InsertProvider.@UpdateProvider.@DeleteProvider和@SelectProv ...
- Mybatis系列全解(八):Mybatis的9大动态SQL标签你知道几个?提前致女神!
封面:洛小汐 作者:潘潘 2021年,仰望天空,脚踏实地. 这算是春节后首篇 Mybatis 文了~ 跨了个年感觉写了有半个世纪 ... 借着女神节 ヾ(◍°∇°◍)ノ゙ 提前祝男神女神们越靓越富越嗨 ...
- MyBatis学习总结_11_MyBatis动态Sql语句
MyBatis中对数据库的操作,有时要带一些条件,因此动态SQL语句非常有必要,下面就主要来讲讲几个常用的动态SQL语句的语法 MyBatis中用于实现动态SQL的元素主要有: if choose(w ...
- SSM框架之Mybatis(6)动态SQL
Mybatis(6)动态SQL 1.动态SQL 出现原因:有些时候业务逻辑复杂时,我们的 SQL 是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了 1.1.if标签 我们根据实体类的不 ...
- MyBatis:学习笔记(4)——动态SQL
MyBatis:学习笔记(4)——动态SQL
- Spring mybatis源码篇章-动态SQL节点源码深入
通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-动态SQL基础语法以及原理 前话 前文描述到通过mybatis默认的解析驱动类org.apache.ibat ...
- MyBatis注解配置动态SQL
MySQL创建表 DROP TABLE IF EXISTS `tb_employee`; CREATE TABLE `tb_employee` ( `id` int(11) NOT NULL AUTO ...
- 学习MyBatis必知必会(7)~注解开发、动态SQL
一.MyBatis的注解开发 开发中推荐是使用xml文件配置 1.配置映射关系[使用注解的方式]: <!-- 全局的配置文件 --> <configuration> <! ...
随机推荐
- 2018 Wannafly summer camp Day8--连通块计数
连通块计数 描述 题目描述: 小 A 有一棵长的很奇怪的树,他由 n 条链和 1 个点作为根构成,第 i条链有 ai 个点,每一条链的一端都与根结点相连. 现在小 A 想知道,这棵长得奇怪的树有多少 ...
- MySQL Group Replication 搭建[Multi-Primary Mode]
1. 环境准备 CentOS7.3 percona-server-5.7.18-14 两台服务器ip地址和主机名 10.0.68.206 yhjr-osd-mysql01-uat 10.0.68.20 ...
- Java线程池的创建详解
本篇文章主要总结了Java创建线程池的三种方式以及线程池参数的详细说明,对线程池感兴趣的同学可以作为参考学习. 1)通过工具类java.util.concurrent.Executors的静态方法来创 ...
- python学习笔记(3)---cookie & session
一.cookie & session 1.cookie: cookie 就是由服务器发送给客户端的特殊信息,而这些信息以文本的方式存放在客户端,然后客户端每次向服务器发送请求都会带上这些特殊信 ...
- thinkphp5 toArray()报错
//DB操作返回是数组.模型直接操作返回是对象 //对象类型转换数组 //打开 database.php 增加或修改参数 'resultset_type' => '\think\Collecti ...
- 帝国cms教程父栏目和子栏目都能在当前栏目高亮
首先在/e/class/userfun.php这个文件里面加上下面代码.上面父栏目的,下面子栏目的.红色代表css样式.自定义吧 function currentPage($classid,$this ...
- Spark运行模式_spark自带cluster manager的standalone cluster模式(集群)
这种运行模式和"Spark自带Cluster Manager的Standalone Client模式(集群)"还是有很大的区别的.使用如下命令执行应用程序(前提是已经启动了spar ...
- Django学习之mysql应用基础
使用pip 安装mysql pip install mysql 使用命令行打开数据库且选择使用已有的数据库 显示已有数据库show databases; 选择已有数据库 use s23; 显示s23数 ...
- rails中发送ajax请求
最近在写一个blog系统练练手,遇到一个一个问题,用户添加评论的时候想发送ajax请求,但是rails里的ajax和Python中的不太一样,Python中的ajax是用js,jquery实现的和ra ...
- 解决 Node.js 错误 Error:listen EADDRINUSE
第一次尝试 node.js 中的 express 框架,写了第一个 js 文件之后,在 WebStorm 运行,到游览器刷新,成功运行. 又创建一个 js 文件,写的是静态路由的访问,结果出现了 Er ...