当前位置: 首页 > news >正文

MyBatis3(动态SQL 常用的动态SQL 元素 映射器注解 基本注解 结果映射注解)

动态SQL

什么是MyBatis的动态SQL?

**定义:**根据不同的条件拼接SQL语句,实现对数据库更准确的操作;

**实现:**映射器配置文件或者注解

常用的动态SQL元素

  • if 元素:判断语句,单条件分 支判断.
  • choose 元素 (when,otherwise): 多条件分支判断,等同于java 的 switch.
  • trim (where,set): 辅助元素,用于处理一些 SQL 拼接的问题.
  • foreach 元素 :循环语句,在in 语 句等列举条件常用
  • bind 元素 :自定义上下文变量, 传递参数.

if元素

语法:

语法
< if  test =”条件”> 满足条件的语句 </ if>

注意:拼接SQL语句的时候要注意AND符号

实现:

Student.java 下面所需要的bean同这个一样

package bean;import java.io.Serializable;
import java.util.Date;public class Student implements Serializable{private int sid;private String sname;private Date birthday;private String Ssex;private int classid;private Clazz clazz;public int getSid() {return sid;}public void setSid(int sid) {this.sid = sid;}public String getSname() {return sname;}public void setSname(String sname) {this.sname = sname;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getSsex() {return Ssex;}public void setSsex(String ssex) {Ssex = ssex;}public int getClassid() {return classid;}public void setClassid(int classid) {this.classid = classid;}public Clazz getClazz() {return clazz;}public void setClazz(Clazz clazz) {this.clazz = clazz;}public Student(int sid, String sname, Date birthday, String ssex, int classid, Clazz clazz) {super();this.sid = sid;this.sname = sname;this.birthday = birthday;Ssex = ssex;this.classid = classid;this.clazz = clazz;}public Student() {super();}@Overridepublic String toString() {return "Student [sid=" + sid + ", sname=" + sname + ", birthday=" + birthday + ", Ssex=" + Ssex + ", classid="+ classid + ", clazz=" + clazz + "]";}
}

StudentMapper.java

public List<Student> selectIf(Student s);

StudentMapper.xml

<!-- OGNL 对象图导航语言 属性 运算符 逻辑 字符串增强 == --><!-- test中的表达式成立 就把if标签里面的字串拼接 -->
<select id="selectIf" parameterType="student"resultType="student"><include refid="stusql"></include>where 1=1<if test="ssex != null">and ssex=#{ssex}</if><if test="classid != 0">and classid=#{classid}</if>
</select>

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
Student s = new Student();
//s.setSname("测试");
//s.setBirthday(new Date());
//s.setSsex("女");
s.setClassid(1);
List<Student> list = studentMapper.selectIf(s);//s.setSid(1);
list.forEach(System.out::println);
DaoUtil.closeSqlSession(sqlSession);

choose 、when 、otherwise 元素

为什么用choose 元素

  • 场景1 当新闻编号不为空,则只用新闻编号作为查询条件;
  • 场景2 当新闻编号为空,而新闻标题不为空,则用新闻标题作为条件进行模糊查询
  • 场景3 当新闻编号和新闻标题都为空,则要求新闻作者不能为空

语法:

<choose>  
<when test=“条件”>满足条件的语句</ when><otherwise> 满足其他条件的语句<otherwise>
</choose>

choose类似于switch 只要满足条件只走一个

注意:拼接SQL语句的时候要注意AND和逗号

实现:

StudentMapper.java

public List<Student> selectChoose(Student s);

StudentMapper.xml

<select id="selectChoose" parameterType="student" resultType="student">select * from student<where><choose><when test="sname">and sname=#{sname}</when><when test="birthday">and birthday=#{birthday}</when><when test="Ssex">and Ssex=#{ssex}</when><when test="classid">and classid=#{classid}</when><otherwise>classid=2</otherwise></choose></where>
</select>

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
Student s = new Student();
s.setClassid(1);
List<Student> list = studentMapper.selectChoose(s);
list.forEach(System.out::println);
DaoUtil.closeSqlSession(sqlSession);

trim、where、set元素

trim(不常用)

语法:

语法:
<trim   prefix = “”suffixOverrides = “” prefixOverrides=“”suffix=“”></trim>prefix 需要拼接的子句,可以是where,or 或者set;suffixOvrrides 忽略通过管道分隔的文本序列后缀。一般不与prefixOvrrides 同时使用prefixOvrrides 忽略通过管道分隔的文本序列前缀。一般不与suffixOvrrides 同时使用

实现:

StudentMapper.java

public List<Student> findStudentTrim(Student s);

StudentMapper.xml

<!-- trim 万能标签prefix 开始添加一个什么prefixOverrides 开始去掉一个什么suffix 结束添加一个什么suffixOverrides 结束去掉一个什么--><select id="findStudentTrim" parameterType="student" resultType="student">select * from student <trim prefix=" where " prefixOverrides="and" ><if test="ssex != null"> and ssex= #{ssex}</if><if test="classid != 0"> and classid = #{classid}</if></trim></select>

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);Student s = new Student();
//		s.setSname("测试");
//		s.setBirthday(new Date());
//		s.setSsex("女");s.setClassid(1);
List<Student> list = studentMapper.findStudentTrim(s);
list.forEach(System.out::println);
DaoUtil.closeSqlSession(sqlSession);


StudentMapper.java

public int updateTrim(Student s);

StudentMapper.xml

<update id="updateTrim" parameterType="student">update student<trim prefix="set" prefixOverrides="" suffix="" suffixOverrides=","><if test="sname!=null">sname=#{sname},</if><if test="birthday!=null">birthday=#{birthday},</if><if test="Ssex!=null">Ssex=#{ssex},</if><if test="classid!=0">classid=#{classid},</if></trim>where sid=#{sid}
</update>

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
Student s = new Student();
s.setSname("测试");
s.setBirthday(new Date());
s.setSsex("女");
s.setClassid(1);s.setSid(38);
int count = studentMapper.updateTrim(s);
if (count > 0) {sqlSession.commit();System.out.println("更新成功~");
} else {sqlSession.rollback();System.out.println("更新失败~");
}
// 释放资源
DaoUtil.closeSqlSession(sqlSession);

where

语法:

语法:
<where><if  test =”条件”> 满足条件的语句 </if>
</where>

说明:where 元素只会在至少有一个子元素的 条件返回SQL子句的情况下才去插入 “WHERE”子句。而且,若语句的开头为 “AND”或“OR”,where 元素也会将它们去除。

实现:

StudentMapper.java

public List<Student> selectWhere(Student s);

StundetMapper.xml

<!-- where标签 1.添加一个where关键词 2. 去掉where后的第一个and 3.当没where标签中没有任何成立的字串时 什么也不添加 -->
<select id="selectWhere" parameterType="student"resultType="student">select * from student<where><if test="ssex != null">and ssex=#{ssex}</if><if test="classid != 0">and classid=#{classid}</if></where>
</select>

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
Student s = new Student();
//s.setSname("测试");
//s.setBirthday(new Date());
//s.setSsex("女");
s.setClassid(1);
s.setSid(38);List<Student> list = studentMapper.selectWhere(s);
list.forEach(System.out::println);
// 释放资源
DaoUtil.closeSqlSession(sqlSession);

set

语法:

<set><if  test =”条件”> 满足条件的语句 </if>
</set>

说明: set 标签元素主要是用在更新操作的时候, 它的主要功能和 where 标签元素其实是差不多的,主要是在包含的语句前输出一个 set, 然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果 set 包含的内容为空的 话则会出错。有了 set 元素就可以动态的更 新那些修改了的字段。

实现:

StudentMapper.java

public int updateSet(Student s);

StudentMapper.xml

<update id="updateSet" parameterType="student">update student<set><if test="sname!=null">sname=#{sname},</if><if test="birthday!=null">birthday=#{birthday},</if><if test="Ssex!=null">Ssex=#{ssex},</if><if test="classid!=0">classid=#{classid},</if></set>where sid=#{sid}
</update>

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
Student s = new Student();
s.setSname("测试");
s.setBirthday(new Date());
s.setSsex("女");
s.setClassid(1);
s.setSid(2);int count = studentMapper.updateSet(s);
if (count > 0) {sqlSession.commit();System.out.println("更新成功~");
} else {sqlSession.rollback();System.out.println("更新失败~");
}
// 释放资源
DaoUtil.closeSqlSession(sqlSession);

foreach元素

语法:

<foreach   item = “” index=“” collection=“” open=“” separator=“” close=“”></foreach>item 循环中的当前元素;
index 当前循环元素的位置下标;
collection 方法传递的参数,一个数组或者集合;
close 以什么符号结束将这些集合元素包装起来;
open 以什么符号开始将这些集合元素包装起来;
separator 各个元素的间隔符号。

参数是数组

实现:

StudentMapper.java

public List<Student> selectForEach(int[] array);

StudentMapper.xml

<select id="selectForEach" resultType="student"><!-- select * from student where sid in --><include refid="stusql"></include>where sid in<!-- collection 参数名 item 要遍历的元素别名 open 起始字符 separator 分隔符 close 结束字符 --><foreach collection="array" item="item" open="(" separator=","close=")">#{item}</foreach>
</select>

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
int[] array = { 1, 3, 5, 7, 9 };
List<Student> list = studentMapper.selectForEach(array);
list.forEach(System.out::println);
// 释放资源
DaoUtil.closeSqlSession(sqlSession);


参数是ArrayList

StudentMapper.java

public List<Student> selectForEachList(List<Integer> list);

StudentMapper.xml

<select id="selectForEachList" resultType="student">select * from student where sid in<foreach collection="list" item="item" open="(" separator="," close=")">#{item}</foreach>
</select>

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Integer> listInteger = Arrays.asList(1, 3, 5, 7, 9);
List<Student> list = studentMapper.selectForEachList(listInteger);
list.forEach(System.out::println);
// 释放资源
DaoUtil.closeSqlSession(sqlSession);


批量增加

实现:

StudentMapper.java

public int insertlist(List<Student> list);

StudentMapper.xml

<!-- 批量添加 -->
<insert id="insertlist">insert into student(sname,birthday,ssex,classid) values<foreach collection="list" item="s" separator=",">(#{s.sname},#{s.birthday},#{s.ssex},#{s.classid})</foreach>
</insert>

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
Student s1 = new Student();
s1.setBirthday(new Date());
s1.setClassid(1);
s1.setSname("刘备");
s1.setSsex("男");
Student s2 = new Student();
s2.setBirthday(new Date());
s2.setClassid(2);
s2.setSname("关羽");
s2.setSsex("男");
Student s3 = new Student();
s3.setBirthday(new Date());
s3.setClassid(3);
s3.setSname("张飞");
s3.setSsex("男");List<Student> stulist = new ArrayList<>();
stulist.add(s1);
stulist.add(s2);
stulist.add(s3);
int ret = studentMapper.insertlist(stulist);if (ret == stulist.size()) {sqlSession.commit();
} else {sqlSession.rollback();
}// 释放资源
DaoUtil.closeSqlSession(sqlSession);

bind元素

定义一个变量

语法:

<bind   name=“”value=“_parameter”>
</bind>name 自定义变量的变量名
value 自定义变量的变量值
_parameter 传递进来的参数

实现:

StudentMapper.java

// 模糊查询
public List<Student> selectStudentLike(String keyname);

StudentMapper.xml

<select id="selectStudentLike" parameterType="String"resultType="student"><!-- 方式1 在业务层处理  不推荐--><!-- select * from student where sname like #{v} --><!-- 方式2 mysql的函数进行拼接 --><!-- select * from student where sname like concat('%',#{v},'%') --><!-- 方式3 sql语法 --><!-- select * from student where sname like "%"#{v}"%" --><!-- 方式4 ${v} 不推荐,不能防止sql注入--><!-- select * from student where sname like '%${v}%' --><!-- 方式5 bind标签  推荐 --><bind name="v" value="'%'+_parameter+'%'"/>select * from student where sname like #{v}
</select>

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
// 方式1:业务层进行拼接
List<Student> list = studentMapper.selectStudentLike("%三%");
list.forEach(System.out::println);
// 释放资源
DaoUtil.closeSqlSession(sqlSession);

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
// 方式2,3,4,5
List<Student> list = studentMapper.selectStudentLike("三");
list.forEach(System.out::println);
// 释放资源
DaoUtil.closeSqlSession(sqlSession);

#{}和${}区别

  • #{}匹配的是一个占位符,相当于JDBC中的一个?,会对一些敏感的字符进行过滤,编译过后会对传递的值加上双引号,因此可以防止SQL注入问题。
  • 匹配的是真实传递的值,传递过后,会与 s q l 语句进行字符串拼接。 {}匹配的是真实传递的值,传递过后,会与sql语句进行字符串拼接。 匹配的是真实传递的值,传递过后,会与sql语句进行字符串拼接。{}会与其他sql进行字符串拼接,不能预防sql注入问题。

#{}是预编译处理,$ {}是字符串替换。

mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

mybatis在处理 $ { } 时,就是把 ${ } 替换成变量的值。使用 #{} 可以有效的防止SQL注入,提高系统安全性。

示例完整代码:

StudentMapper.java

package mapper;import java.util.List;
import java.util.Map;import bean.Student;public interface StudentMapper {public List<Student> selectIf(Student s);public List<Student> selectWhere(Student s);public List<Student> selectChoose(Student s);public List<Student> findStudentTrim(Student s);public int updateSet(Student s);public int updateTrim(Student s);public List<Student> selectForEach(int[] array);public List<Student> selectForEachList(List<Integer> list);public int insertlist(List<Student> list);// 模糊查询public List<Student> selectStudentLike(String keyname);
}

StudentMapper.xml

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 指向接口的类路径 -->
<mapper namespace="mapper.StudentMapper"><!-- sql片段 --><sql id="stusql">select * from student</sql><select id="selectIf" parameterType="student"resultType="student"><include refid="stusql"></include>where 1=1<if test="ssex != null">and ssex=#{ssex}</if><if test="classid != 0">and classid=#{classid}</if></select><select id="selectWhere" parameterType="student"resultType="student">select * from student<where><if test="ssex != null">and ssex=#{ssex}</if><if test="classid != 0">and classid=#{classid}</if></where></select><!-- trim 万能标签prefix 开始添加一个什么prefixOverrides 开始去掉一个什么suffix 结束添加一个什么suffixOverrides 结束去掉一个什么--><select id="findStudentTrim" parameterType="student" resultType="student">select * from student <trim prefix=" where " prefixOverrides="and" ><if test="ssex != null"> and ssex= #{ssex}</if><if test="classid != 0"> and classid = #{classid}</if></trim></select><select id="selectChoose" parameterType="student"resultType="student">select * from student<where><choose><when test="sname">and sname=#{sname}</when><when test="birthday">and birthday=#{birthday}</when><when test="Ssex">and Ssex=#{ssex}</when><when test="classid">and classid=#{classid}</when><otherwise>classid=2</otherwise></choose></where></select><update id="updateSet" parameterType="student">update student<set><if test="sname!=null">sname=#{sname},</if><if test="birthday!=null">birthday=#{birthday},</if><if test="Ssex!=null">Ssex=#{ssex},</if><if test="classid!=0">classid=#{classid},</if></set>where sid=#{sid}</update><update id="updateTrim" parameterType="student">update student<trim prefix="set" prefixOverrides="" suffix="" suffixOverrides=","><if test="sname!=null">sname=#{sname},</if><if test="birthday!=null">birthday=#{birthday},</if><if test="Ssex!=null">Ssex=#{ssex},</if><if test="classid!=0">classid=#{classid},</if></trim>where sid=#{sid}</update><select id="selectForEach" resultType="student"><!-- select * from student where sid in --><include refid="stusql"></include>where sid in<!-- collection 参数名 item 要遍历的元素别名 open 起始字符 separator 分隔符 close 结束字符 --><foreach collection="array" item="item" open="(" separator=","close=")">#{item}</foreach></select><select id="selectForEachList" resultType="student">select * from student where sid in<foreach collection="list" item="item" open="(" separator="," close=")">#{item}</foreach></select><!-- 批量添加 --><insert id="insertlist">insert into student(sname,birthday,ssex,classid) values<foreach collection="list" item="s" separator=",">(#{s.sname},#{s.birthday},#{s.ssex},#{s.classid})</foreach></insert><select id="selectStudentLike" parameterType="String"resultType="student"><!-- 方式1 在业务层处理  不推荐--><!-- select * from student where sname like #{v} --><!-- 方式2 mysql的函数进行拼接 --><!-- select * from student where sname like concat('%',#{v},'%') --><!-- 方式3 sql语法 --><!-- select * from student where sname like "%"#{v}"%" --><!-- 方式4 ${v} 不推荐,不能防止sql注入--><!-- select * from student where sname like '%${v}%' --><!-- 方式5 bind标签  推荐 --><bind name="v" value="'%'+_parameter+'%'"/>select * from student where sname like #{v}</select>
</mapper>

测试类:

package test;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;import org.apache.ibatis.session.SqlSession;import bean.Student;
import dao.DaoUtil;
import mapper.StudentMapper;public class Test {public static void main(String[] args) {SqlSession sqlSession = DaoUtil.getSqlSession();StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
//		Student s = new Student();
//		s.setSname("测试");
//		s.setBirthday(new Date());
//		s.setSsex("女");
//		s.setClassid(1);
//
//		s.setSid(2);//		List<Student> list = studentMapper.selectIf(s);// 动态SQL
//		List<Student> list = studentMapper.selectWhere(s);
//		List<Student> list = studentMapper.selectChoose(s);
//		List<Student> list = studentMapper.findStudentTrim(s);//		int[] array = { 1, 3, 5, 7, 9 };
//		List<Student> list = studentMapper.selectForEach(array);
//		List<Integer> listInteger = Arrays.asList(1, 3, 5, 7, 9);
//		List<Student> list = studentMapper.selectForEachList(listInteger);// 方式1:业务层进行拼接
//		List<Student> list = studentMapper.selectStudentLike("%三%");// 方式2,3,4,5List<Student> list = studentMapper.selectStudentLike("三");list.forEach(System.out::println);//		int count = studentMapper.updateSet(s);
//		int count = studentMapper.updateTrim(s);
//		if (count > 0) {
//			sqlSession.commit();
//			System.out.println("更新成功~");
//		} else {
//			sqlSession.rollback();
//			System.out.println("更新失败~");
//		}//		Student s1 = new Student();
//		s1.setBirthday(new Date());
//		s1.setClassid(1);
//		s1.setSname("刘备");
//		s1.setSsex("男");
//		Student s2 = new Student();
//		s2.setBirthday(new Date());
//		s2.setClassid(2);
//		s2.setSname("关羽");
//		s2.setSsex("男");
//		Student s3 = new Student();
//		s3.setBirthday(new Date());
//		s3.setClassid(3);
//		s3.setSname("张飞");
//		s3.setSsex("男");
//		
//		List<Student> stulist = new ArrayList<>();
//		stulist.add(s1);
//		stulist.add(s2);
//		stulist.add(s3);
//		int ret = studentMapper.insertlist(stulist);
//
//		if (ret == stulist.size()) {
//			sqlSession.commit();
//		} else {
//			sqlSession.rollback();
//		}
//
//		// 释放资源DaoUtil.closeSqlSession(sqlSession);}
}

映射器注解

映射器配置文件的缺陷

  • 繁琐:配置文件的书写本身繁琐,需要掌 握的内容比较多
  • 不直观:配置文件和接口直接只是名称相同, 对应起来比较麻烦.

常用的注解

  • 基本注解:实现简单的增删改查操作。
  • 结果映射注解:实现结果的映射关系, 也可以完成级联映射。
  • 动态SQL注解:实现动态 SQL 的内容

基本注解

基本注解的分类

  • 增加操作 @Insert 类似 < insert > 完成新增
  • 删除操作 @Delete 类似 < delete > 完成删除
  • 修改操作 @Update 类似 < update > 完成修改
  • 查询操作 @Select 类似 < select > 完成查询

@Insert注解

**功能:**完成新增操作,类似配置文件的元素;

**说明:**新增时所用的参数取值是接口方法的入参,可以是对象,也可以是 Map 集合。

语法:

@Insert (“ sql 语句”)

主键回填

**功能:**完成数据库自增主键的回填

语法:

@Options(useGeneratedKeys = true, keyProperty = "主键属性")

实现:

实体类Student.java

package bean;import java.util.Date;public class Student {private int sid;private String sname;private Date birthday;private String Ssex;private int classid;private Clazz clazz;public int getSid() {return sid;}public void setSid(int sid) {this.sid = sid;}public String getSname() {return sname;}public void setSname(String sname) {this.sname = sname;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getSsex() {return Ssex;}public void setSsex(String ssex) {Ssex = ssex;}public int getClassid() {return classid;}public void setClassid(int classid) {this.classid = classid;}public Clazz getClazz() {return clazz;}public void setClazz(Clazz clazz) {this.clazz = clazz;}public Student(int sid, String sname, Date birthday, String ssex, int classid, Clazz clazz) {super();this.sid = sid;this.sname = sname;this.birthday = birthday;Ssex = ssex;this.classid = classid;this.clazz = clazz;}public Student() {super();}@Overridepublic String toString() {return "Student [sid=" + sid + ", sname=" + sname + ", birthday=" + birthday + ", Ssex=" + Ssex + ", classid="+ classid + ", clazz=" + clazz + "]";}
}

StudentMapper.java

@Insert("insert into student(sname,birthday,ssex,classid) " + "values(#{sname},#{birthday},#{ssex},#{classid})")
@Options(useGeneratedKeys = true, keyProperty = "sid")
// 主键回填注解@Options
public int addStudent(Student s);

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
Student s = new Student();
s.setSname("一猫人");
s.setBirthday(new Date());
s.setSsex("男");
s.setClassid(1);//s.setSid(18);
System.out.println(s);
int count = studentMapper.addStudent(s);
System.out.println(s);
if (count > 0) {sqlSession.commit();
} else {sqlSession.rollback();
}
// 释放资源
DaoUtil.closeSqlSession(sqlSession);

主键自增

**功能:**完成自定义主键的自增

语法:

@SelectKey ( statement = "自增规则", keyProperty = "主键属性", 
resultType = 结果类型, before = true )

@Delete删除

**功能:**完成删除操作,类似配置文件的元素;

说明:删除时所用的参数取值是接口方法的入参,可以是对象,也可以是 Map 集合。

语法:

@Delete (“ sql 语句”)

实现:

StudentMapper.java

@Delete("delete from student where sid=#{v}")
public int deleteStudent(int sid);

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
int count = studentMapper.deleteStudent(42);if (count > 0) {sqlSession.commit();
} else {sqlSession.rollback();
}
// 释放资源
DaoUtil.closeSqlSession(sqlSession);

@Update更新

**功能:**完成更新操作,类似配置文件的元素;

**说明:**更新时所用的参数取值是接口方法的入参,可以是对象,也可以是Map 集合。

语法:

@Update (“ sql 语句”)

实现:

StudentMapper.java

@Update("update student set sname=#{sname},birthday=#{birthday},ssex=#{ssex},classid=#{classid} where sid=#{sid}")
public int updateStudent(Student s);

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
// 修改
Student s = new Student();
s.setSname("一猫人");
s.setBirthday(new Date());
s.setSsex("男");
s.setClassid(1);s.setSid(41);
int count = studentMapper.updateStudent(s);
if (count > 0) {sqlSession.commit();
} else {sqlSession.rollback();
}
// 释放资源
DaoUtil.closeSqlSession(sqlSession);

@Select查询

**功能:**完成查询操作,类似配置文件的 元素;

**说明:**查询时所用的参数取值是接口方法的入参,可以是 对象,也可以是 Map 集合。

语法:

@Selete (“ sql 语句”)

实现:

StudentMapper.java

@Select("select * from student")
public List<Student> findAll();@Select("select * from student where sname=#{v}")
public Student findByName(String name);

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> list = studentMapper.findAll();
for (Student student : list) {System.out.println(student);
}
Student s = studentMapper.findByName("贾策");
System.out.println(s);
// 释放资源
DaoUtil.closeSqlSession(sqlSession);

注解和sqlMapper.xml 可以同时使用

注解底层还是sqlMapper 方法还是不能重载

传递多个参数的方式

  • 方法1:Map 方式 跟sqlmap一样
  • 方法2:JavaBean 方式跟sqlmap一样
  • 方法3:@Param 方式

实现:

StudentMapper.java

@Select("select * from student where ssex=#{sex} limit #{cpage},#{size}")
public List<Student> selectSexLimit(@Param("sex") String sex,@Param("cpage") int cpage, @Param("size") int size);

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> list = studentMapper.selectSexLimit("男", (3 - 1) * 3, 3);
for (Student student : list) {System.out.println(student);
}
// 释放资源
DaoUtil.closeSqlSession(sqlSession);

结果映射注解

@Results结果映射

功能: 完成数据库字段和 JavaBean 属性的映射关系;

说明:每个 @Results 可以包含多个 @Result,其中通过 id 属性来判断是否为主键。

语法:

@Results({ @Result(id = 是否为主键, column = "字段", property = "属性" ) })

@Results复用

实现:

SMasterMapper.java

//	@Results(id="smaster_map",value = {
//			@Result(column = "smid",property = "smid"),
//			@Result(column = "sm_name",property = "smname"),
//			@Result(column = "smsex",property = "smsex")
//	})@Results({@Result(column = "smid",property = "smid"),@Result(column = "sm_name",property = "smname"),@Result(column = "smsex",property = "smsex")})@Select("select * from schoolmaster")public List<SMaster> findAll();@Select("select * from schoolmaster where smid=#{v}")
//	@ResultMap("smaster_map")public SMaster findById(int id);

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
SMasterMapper sMasterMapper = sqlSession.getMapper(SMasterMapper.class);
List<SMaster> list = sMasterMapper.findAll();
list.forEach(System.out::println);
SMaster s = sMasterMapper.findById(2);
System.out.println(s);

注解映射各用各的

一对一映射

功能:一对一的关系映射;

说明:FetchType.lazy 是延时加载,FetchType.EAGER 是即时加载。

语法:

@One( Select = 一对一查询方法, 
fetchType = FetchType.EAGER ) 

实现:

StudentMapper.java

@Results({ @Result(column = "classid", property = "classid"),@Result(property = "clazz", column = "classid", one = @One(select = "mapper.ClazzMapper.selectAll")) })
@Select("select * from student")
public List<Student> selectStudentAndClazz();

Clazz.java

@Select("select * from class where classid=#{v}")
public List<Clazz> selectAll(int classid);

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> list = studentMapper.selectStudentAndClazz();
for (Student student : list) {System.out.println(student);
}
DaoUtil.closeSqlSession(sqlSession);

注解没有表联查 只有单表和自己写的映射关系

一对一映射的实现案例

一对多映射

功能:一对多的关系映射;

说明:FetchType.lazy 是延时加载,FetchType.EAGER 是即时加载。

语法

@Many( Select = 一对多查询方法, fetchType = FetchType.EAGER )

实现:

ClazzMapper.java

@Results({ @Result(column = "classid", property = "classid"),@Result(column = "classid", property = "stulist", many = @Many(select = "mapper.StudentMapper.selectStudentByClassId")) })@Select("select * from class")public List<Clazz> selectClazzAndStudent();

StudentMapper.java

@Select("select * from student where classid=#{v}")
public List<Student> selectStudentByClassId(int classid);

测试:

SqlSession sqlSession = DaoUtil.getSqlSession();
ClazzMapper clazzMapper = sqlSession.getMapper(ClazzMapper.class);
List<Clazz> list = clazzMapper.selectClazzAndStudent();
for (Clazz clazz : list) {System.out.println(clazz);
}
DaoUtil.closeSqlSession(sqlSession);

一对多映射的实现案例

示例完整代码:

ClazzMapper.java

package mapper;import java.util.List;import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;import bean.Clazz;public interface ClazzMapper {@Select("select * from class where classid=#{v}")public List<Clazz> selectAll(int classid);@Select("select * from class")public List<Clazz> selectClazzId(int classid);@Results({ @Result(column = "classid", property = "classid"),@Result(column = "classid", property = "stulist", many = @Many(select = "mapper.StudentMapper.selectStudentByClassId")) })@Select("select * from class")public List<Clazz> selectClazzAndStudent();
}

StudentMapper.java

package mapper;import java.util.List;
import java.util.Map;import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.annotations.UpdateProvider;
import org.apache.ibatis.jdbc.SQL;import bean.Student;public interface StudentMapper {@Select("select * from student")public List<Student> findAll();@Select("select * from student where sname=#{v}")public Student findByName(String name);@Select("select * from student where ssex=#{sex} limit #{cpage},#{size}")public List<Student> selectSexLimit(@Param("sex") String sex, @Param("cpage") int cpage, @Param("size") int size);@Insert("insert into student(sname,birthday,ssex,classid) " + "values(#{sname},#{birthday},#{ssex},#{classid})")@Options(useGeneratedKeys = true, keyProperty = "sid")// 主键回填注解@Optionspublic int addStudent(Student s);@Update("update student set sname=#{sname},birthday=#{birthday},ssex=#{ssex},classid=#{classid} where sid=#{sid}")public int updateStudent(Student s);@Delete("delete from student where sid=#{v}")public int deleteStudent(int sid);@Results({ @Result(column = "classid", property = "classid"),@Result(property = "clazz", column = "classid", one = @One(select = "mapper.ClazzMapper.selectAll")) })@Select("select * from student")public List<Student> selectStudentAndClazz();@Select("select * from student where classid=#{v}")public List<Student> selectStudentByClassId(int classid);
}

测试1:

package test;import java.util.Date;
import java.util.List;import org.apache.ibatis.session.SqlSession;import bean.Student;
import dao.DaoUtil;
import mapper.StudentMapper;public class Test01 {public static void main(String[] args) {SqlSession sqlSession = DaoUtil.getSqlSession();StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
//		List<Student> list = studentMapper.findAll();List<Student> list = studentMapper.selectSexLimit("男", (3 - 1) * 3, 3);for (Student student : list) {System.out.println(student);}
//
//		Student s = studentMapper.findByName("贾策");
//		System.out.println(s);// 添加
//		Student s = new Student();
//		s.setSname("一猫人");
//		s.setBirthday(new Date());
//		s.setSsex("男");
//		s.setClassid(1);
//
//		s.setSid(41);
//		System.out.println(s);
//		int count = studentMapper.addStudent(s);
//		System.out.println(s);//		int count = studentMapper.updateStudent(s);
//		int count = studentMapper.deleteStudent(42);//		if (count > 0) {
//			sqlSession.commit();
//		} else {
//			sqlSession.rollback();
//		}// 释放资源DaoUtil.closeSqlSession(sqlSession);}
}

测试2:

package test;import java.util.List;import org.apache.ibatis.session.SqlSession;import bean.SMaster;
import dao.DaoUtil;
import mapper.SMasterMapper;public class Test02 {public static void main(String[] args) {SqlSession sqlSession = DaoUtil.getSqlSession();SMasterMapper sMasterMapper = sqlSession.getMapper(SMasterMapper.class);List<SMaster> list = sMasterMapper.findAll();list.forEach(System.out::println);SMaster s = sMasterMapper.findById(2);System.out.println(s);}
}

测试3:

package test;import java.util.List;import org.apache.ibatis.session.SqlSession;import bean.Clazz;
import bean.Student;
import dao.DaoUtil;
import mapper.ClazzMapper;
import mapper.StudentMapper;public class Test03 {public static void main(String[] args) {SqlSession sqlSession = DaoUtil.getSqlSession();
//		StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
//		List<Student> list = studentMapper.selectStudentAndClazz();
//		for (Student student : list) {
//			System.out.println(student);
//		}ClazzMapper clazzMapper = sqlSession.getMapper(ClazzMapper.class);List<Clazz> list = clazzMapper.selectClazzAndStudent();for (Clazz clazz : list) {System.out.println(clazz);}DaoUtil.closeSqlSession(sqlSession);}
}

相关文章:

MyBatis3(动态SQL 常用的动态SQL 元素 映射器注解 基本注解 结果映射注解)

动态SQL 什么是MyBatis的动态SQL&#xff1f; **定义&#xff1a;**根据不同的条件拼接SQL语句&#xff0c;实现对数据库更准确的操作&#xff1b; **实现&#xff1a;**映射器配置文件或者注解 常用的动态SQL元素 if 元素&#xff1a;判断语句&#xff0c;单条件分 支判断…...

C#自定义事件的案例

方法一&#xff0c;详细的声明 namespace HelloWorldConsole {internal class Program{static void Main(string[] args){Customer customer new Customer();Waiter waiter new Waiter();customer.Order waiter.Action;customer.Action();}}public class OrderEventArgs : …...

flume系列之:flume机器做条带划分提高磁盘性能和吞吐量的详细步骤

flume系列之:flume机器做条带划分提高磁盘性能和吞吐量的详细步骤 磁盘条带划分新磁盘直接条带划分步骤有数据的磁盘做条带划分步骤磁盘条带划分 磁盘条带划分是将一个文件或数据块分散存储在多个物理磁盘上的技术。它可以提高磁盘的性能和吞吐量。以下是磁盘做了条带划分后可…...

C++基于opencv的视频质量检测--图像清晰度检测

文章目录 0.引言1. 原始算法实现2. 优化思路3. 优化后的代码4. 代码详细解读 0.引言 视频质量图像清晰度检测已在C基于opencv4的视频质量检测中有所介绍&#xff0c;本文将详细介绍其优化版本。 1. 原始算法实现 原始代码&#xff1a; double sharpnessDetect(const cv::Ma…...

力扣11.1

2518. 好分区的数目 给你一个正整数数组 nums 和一个整数 k 。 分区 的定义是&#xff1a;将数组划分成两个有序的 组 &#xff0c;并满足每个元素 恰好 存在于 某一个 组中。如果分区中每个组的元素和都大于等于 k &#xff0c;则认为分区是一个好分区。 返回 不同 的好分区…...

打印室预约系统|基于java和小程序的打印室预约系统设计与实现(源码+数据库+文档)

打印室预约系统 目录 基于java和小程序的打印室预约系统设计与实现 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕设布道师&#x…...

操作系统-多线程案例

一、单例模式&#xff08;是一种设计模式&#xff09; 设计模式有很多种&#xff0c;不同的语法中也有不同的设计模式 单例 单个实例&#xff08;对象) 某个类&#xff0c;在一个进程中&#xff0c;只应该创建出一个实例&#xff0c;&#xff08;原则上不该有多个&#xff…...

什么是FUSE用户态文件系统

零. 文件系统 1. 为什么要有文件系统 文件系统是操作系统中管理文件和目录的一种机制。它提供了组织、存储、检索和更新文件的方法&#xff0c;主要如下&#xff1a; 数据组织&#xff1a;文件系统将数据组织成文件和目录&#xff0c;使用户能够更方便地管理和查找文件。每个…...

[每日一练]销售分析(通过数据的0/1转换进行是否存在的查询)

#该题目来源于力扣&#xff1a; 1083. 销售分析 II - 力扣&#xff08;LeetCode&#xff09; 题目要求&#xff1a; 表&#xff1a;Product----------------------- | Column Name | Type | ----------------------- | product_id | int | | product_name | varch…...

.NET Core WebApi第7讲:项目的发布与部署

一、理解 前端跟后端拿数据&#xff0c;然后在前端页面中展示&#xff0c;就是我们要完成的事情。 把前端跟后端开发好之后&#xff0c;我们需要落地部署&#xff0c;这个时候就需要一个服务器。 服务器就是一台电脑&#xff0c;只要windows里面有一个叫IIS的管理器。 二、项目…...

【python 将数据写入csv文件】正确方式

data [{username: jack, password: 1234}, ……]# 保存为CSV文件 with open(IP_output.csv, w, newline, encodingutf-8) as file:fieldnames [username, password]writer csv.DictWriter(file, fieldnamesfieldnames, quotingcsv.QUOTE_NONE)writer.writeheader() # 写入列…...

OpenCV4.8 开发实战系列专栏之 10 - 像素值统计

大家好,欢迎大家学习OpenCV4.8 开发实战专栏,长期更新,不断分享源码。 专栏代码全部基于C++ 与Python双语演示,专栏答疑群 请联系微信 OpenCVXueTang_Asst 本文关键知识点:像素值统计 最小(min)最大(max)均值(mean)标准方差(standard deviation)API知识点 最大最小值min…...

pandas计算相关性并画热力图

实现这个功能有很多方法&#xff0c;但是下面的方法还是比较优雅的&#xff1a; cols ["ASSET", "HOUSES", "INCOME", "DEBT", "EDUC"] corr df[cols].corr() corr.style.background_gradient(axisNone)讲解&#xff1a; …...

初始Docker

概述&#xff1a; 容器&#xff0c;作为云原生技术的重要组成部分&#xff0c;与虚拟机一样&#xff0c;均属于虚拟化技术的范畴。然而&#xff0c;容器技术以其独特的优势&#xff0c;在虚拟化领域中脱颖而出。与虚拟机不同&#xff0c;容器能够摆脱操作系统的束缚&#xff0…...

Redis-概念、安装、基本配置

文章目录 一、Redis及Redis集群概念、分布式系统概念一-1 Redis是什么一-2 什么是分布式系统、分布式缓存一-3 什么是Redis集群、实现Redis集群的方法有哪些、这些跟Redis的sentinel和cluster有什么关系一-4 Redis的库一-5 Redis中的Key与Value是什么、如何进行操作使用它们添加…...

qt QPlainTextEdit详解

QPlainTextEdit是一个功能强大、易于使用的纯文本编辑器/查看器。它使用与QTextEdit相同的技术和概念&#xff0c;但是为纯文本的处理进行了优化&#xff0c;因此更适合处理大型纯文本文档。QPlainTextEdit不提供富文本编辑功能&#xff0c;如字体、颜色、大小等的格式化&#…...

【机器学习】23. 聚类-GMM: Gaussian Mixture Model

1. 定义和假设 定义&#xff1a;probabilistic clustering&#xff08;model-base&#xff09; 假设&#xff1a;数据服从正态分布 2. 算法内容 我们假设数据是由k个高斯&#xff08;正态&#xff09;分布混合生成的。每个分布有2个参数&#xff1a;μ和σ。 一个分布对应一…...

深度探索C++对象模型

文章目录 前言一、关于对象C对象模型 二、构造函数实例分析 拷贝构造函数程序转化语意学(Program Transformation Semantics)成员初始化列表 三、数据语义学(The Semantics of Data)数据存取多种继承情况讨论仅单一继承加上虚函数多重继承虚拟继承 Pointer to Data Members 四、…...

电脑怎么设置开机密码:保障个人信息安全的第一步

在数字化时代&#xff0c;个人信息的安全至关重要。电脑作为我们日常工作和生活中不可或缺的设备&#xff0c;存储了大量的私人数据和敏感信息。为了防止未经授权的访问&#xff0c;设置开机密码是保护个人隐私和信息安全的基本措施之一。本文将详细介绍如何在不同操作系统下为…...

MybatisPlus入门(六)MybatisPlus-null值处理

一、MybatisPlus-null值处理 1.1&#xff09;问题引入&#xff1a; 在查询中遇到如下情况&#xff0c;有部分筛选条件没有值&#xff0c;如商品价格有最大值和最小值&#xff0c;商品价格部分时候没有值。 1.2&#xff09;解决办法&#xff1a; 步骤一&#xff1a;新建查询实…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

​​企业大模型服务合规指南:深度解析备案与登记制度​​

伴随AI技术的爆炸式发展&#xff0c;尤其是大模型&#xff08;LLM&#xff09;在各行各业的深度应用和整合&#xff0c;企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者&#xff0c;还是积极拥抱AI转型的传统企业&#xff0c;在面向公众…...

【Ftrace 专栏】Ftrace 参考博文

ftrace、perf、bcc、bpftrace、ply、simple_perf的使用Ftrace 基本用法Linux 利用 ftrace 分析内核调用如何利用ftrace精确跟踪特定进程调度信息使用 ftrace 进行追踪延迟Linux-培训笔记-ftracehttps://www.kernel.org/doc/html/v4.18/trace/events.htmlhttps://blog.csdn.net/…...