第二章 单表的CURD操作

/04-curd
学生类属性不变
自定义Dao接口实现类
用map的方式了解即可

public interface IStudentDao {//插入void insertStudent(Student student);void insertStudentCatchId(Student student);//删改void deletetudentById(int id);void updateStudent(Student student);//查询所有List<Student> selectAllStudents();    Map<String, Object> selectAllStudentsMap();   //查询指定Student selectStudentById(int id);//根据姓名查询List<Student> selectStudentsByName(String name);}

修改Dao实现类
增删改查 模糊查询

public class StudentDaoImpl implements IStudentDao {private SqlSession sqlSession;//增@Overridepublic void insertStudent(Student student) {try {sqlSession = MyBatisUtils.getSqlSession();sqlSession.insert("insertStudent", student);    sqlSession.commit();} finally {if(sqlSession != null) {sqlSession.close();//sqlSession 关闭了就不用回滚}}}//插入后用新id初始化被插入对象@Overridepublic void insertStudentCatchId(Student student) {try {sqlSession = MyBatisUtils.getSqlSession();sqlSession.insert("insertStudentCatchId", student);  sqlSession.commit();} finally {if(sqlSession != null) {sqlSession.close();//sqlSession 关闭了就不用回滚}}}//删@Overridepublic void deletetudentById(int id) {try {sqlSession = MyBatisUtils.getSqlSession();sqlSession.delete("deletetudentById", id);  sqlSession.commit();} finally {if(sqlSession != null) {sqlSession.close();//sqlSession 关闭了就不用回滚}}}//改@Overridepublic void updateStudent(Student student) {try {sqlSession = MyBatisUtils.getSqlSession();sqlSession.update("updateStudent", student);sqlSession.commit();} finally {if(sqlSession != null) {sqlSession.close();//sqlSession 关闭了就不用回滚}}}//查询所有@Overridepublic List<Student> selectAllStudents() {List<Student> students = null;try {sqlSession = MyBatisUtils.getSqlSession();students = sqlSession.selectList("selectAllStudents");//查询不用修改,所以不用提交} finally {if(sqlSession != null) {sqlSession.close();//sqlSession 关闭了就不用回滚}}return students;}//了解即可 查询指定可以返回的map对象@Overridepublic Map<String, Object> selectAllStudentsMap() {Map<String, Object> map = new HashMap<>();try {sqlSession = MyBatisUtils.getSqlSession();map = sqlSession.selectMap("selectAllStudents", "name");//查询不用修改,所以不用提交} finally {if(sqlSession != null) {sqlSession.close();//sqlSession 关闭了就不用回滚}}return map;}//通过id查询@Overridepublic Student selectStudentById(int id) {Student student = null;try {sqlSession = MyBatisUtils.getSqlSession();student = sqlSession.selectOne("selectStudentById", id);} finally {if(sqlSession != null) {sqlSession.close();//sqlSession 关闭了就不用回滚}}return student;}   //通过名字查询 模糊查询@Overridepublic List<Student> selectStudentsByName(String name) {List<Student> students = null;try {sqlSession = MyBatisUtils.getSqlSession();students = sqlSession.selectList("selectStudentByName", name);//查询不用修改,所以不用提交} finally {if(sqlSession != null) {sqlSession.close();//sqlSession 关闭了就不用回滚}}return students;}}

工具类不变,获取主配置文件、sqlSessionFactory、sqlSession的创建

public class MyBatisUtils {private static SqlSessionFactory sqlSessionFactory;public static SqlSession getSqlSession() {try {InputStream is = Resources.getResourceAsStream("mybatis.xml");if (sqlSessionFactory == null) {sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);}return sqlSessionFactory.openSession();} catch (IOException e) {e.printStackTrace();}return null;}
}

映射文件中写SQL语句

<mapper namespace="test"><!-- parameterType属性可以省略 --><insert id="insertStudent" parameterType="Student">insert into student(name,age,score) values(#{name}, #{age}, #{score})<!-- 也放在dao包下,表示映射 --></insert><insert id="insertStudentCatchId">insert into student(name,age,score) values(#{name}, #{age}, #{score})<!-- order可以不写  将查询到的id属性赋值给student--><selectKey resultType="int" keyProperty="id" order="AFTER">select @@identity</selectKey></insert><delete id="deletetudentById">delete from student where id=#{xxx}  <!-- 这里的#{}仅仅是个占位符,里面放什么都可以 --></delete><update id="updateStudent">update student set name=#{name}, age=#{age}, score=#{score} where id=#{id}</update><select id="selectAllStudents" resultType="Student">select id,name,age,score from student</select><select id="selectStudentById" resultType="Student">select id,name,age,score from student where id=#{jjj}</select><select id="selectStudentByName" resultType="Student"><!-- select id,name,age,score from student where name like concat('%', #{xxx}, '%') -->select id,name,age,score from student where name like '%' #{xxx} '%'</select></mapper>

主配置文件不变

<configuration><!--注册DB连接四要素属性文件  --><properties resource="jdbc.properties"/><!-- 定义类型别名 --><typeAliases><!-- <typeAlias type="com.bjpowernode.beans.Student" alias="Student"/> --><!-- 将指定包中所有类的简单类名当作其别名 --><package name="com.bjpowernode.beans"/></typeAliases><!-- 配置运行环境 --><environments default="mysqlEm"><environment id="mysqlEm"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.user}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><!-- 注册映射文件 --><mappers><mapper resource="com/bjpowernode/dao/mapper.xml"/></mappers>
</configuration>

方法测试

public class MyTest {private IStudentDao dao;@Beforepublic void before() {dao = new StudentDaoImpl();}@Testpublic void test01() {//id都是空的Student student = new Student("张三", 23, 93.5);System.out.println("插入前:student = " + student);dao.insertStudent(student);System.out.println("插入后:student = " + student);}@Testpublic void test02() {//id都是空的Student student = new Student("张三", 23, 93.5);System.out.println("插入前:student = " + student);dao.insertStudentCatchId(student);System.out.println("插入后:student = " + student);}@Testpublic void test03() {dao.deletetudentById(17);}@Testpublic void test04() {Student student = new Student("李四", 23, 93.5);student.setId(18);dao.updateStudent(student);}@Testpublic void test05() {List<Student> students = dao.selectAllStudents();for(Student student : students) {System.out.println(student);}}@Testpublic void test06() {Map<String, Object> map = dao.selectAllStudentsMap();System.out.println(map.get("李四"));}@Testpublic void test07() {Student student = dao.selectStudentById(19);System.out.println(student);}@Testpublic void test08() {List<Student> students = dao.selectStudentsByName("张");for(Student student : students) {System.out.println(student);}}}

2.2 属性名与查询字段名不相同

resultType可以将查询结果直接映射为实体Bean对象的条件是,SQL查询的字段名与实体Bean的属性名一致。因为在将查询结果转换为指定类型对象时,系统自动将查询结果字段名称作为对象的属性名,通过反射机制完成对象的创建。
当SQL查询的字段名与实体Bean的属性名不一致时,将无法创建出需要类型的对象。此时有两种解决方案。
首先修改student表

1)查询字段使用别名
/05-property-column-unsame
修改mapper映射文件

<mapper namespace="test"><!-- parameterType属性可以省略 --><insert id="insertStudent" parameterType="Student">insert into student(tname,tage,score) values(#{name}, #{age}, #{score})<!-- 也放在dao包下,表示映射 --></insert><select id="selectAllStudents" resultType="Student">select tid id,tname name,tage age,score from student</select><select id="selectStudentById" resultType="Student">select tid id,tname name,tage age,score from student where tid=#{jjj}</select></mapper>

2)使用结果映射resultMap
修改mapper即可

<mapper namespace="test"><!-- parameterType属性可以省略 --><insert id="insertStudent" parameterType="Student">insert into student(tname,tage,score) values(#{name}, #{age}, #{score})<!-- 也放在dao包下,表示映射 --></insert><resultMap type="Student" id="studentMapper"><id column="tid" property="id"/><result column="tname" property="name"/><result column="tage" property="age"/>      </resultMap><select id="selectAllStudents" resultMap="studentMapper">select tid,tname,tage,score from student</select><select id="selectStudentById" resultMap="studentMapper">select tid,tname,tage,score from student where tid=#{jjj}</select></mapper>

2.3 Mapper动态代理

‘在前面自定义Dao接口实现类时发现一个问题:Dao的实现类其实没有实质性的工作,它仅仅是通过SqlSession的相关API定位到映射文件mapper中相应id的SQL语句,真正对DB进行操作的工作其实是由框架通过mapper中的SQL完成的。
所以MyBatis框架就抛开了Dao的实现类,直接定位到映射文件mapper中的相应SQL语句,对DB进行操作。这种实现方式称为Mapper的动态代理。
Mapper的动态代理。无需程序员实现Dao接口。接口是由MyBatis结合映射文件自动生成的动态代理实现的
/07-mapperDynamicProxy
1)修改映射文件的namespace属性值

其他不变

<mapper namespace="com.bjpowernode.dao.IStudentDao">

2)修改日志输出控制文件
mapper的namespace修改了,需要将日志输出控制文件中logger的输出对象进行修改。

log4j.logger.com.bjpowernode.dao.IStudentDao=trace,console

3)Dao接口方法名
Mybatis框架要求,接口中的方法名,与映射文件mapper中相应的SQL标签的id值相同。


4)Dao对象的获取
使用时,需要调用SqlSession的getMapper()方法,即可获取指定接口的实现类对象。
该方法的参数为指定Dao接口类的class值。

测试类修改

public class MyTest {private IStudentDao dao;private SqlSession sqlSession;@Beforepublic void before() {sqlSession = MyBatisUtils.getSqlSession();dao = sqlSession.getMapper(IStudentDao.class);}@Afterpublic void after() {if (sqlSession != null) {sqlSession.close();}}@Testpublic void test01() {//id都是空的Student student = new Student("张三", 23, 93.5);System.out.println("插入前:student = " + student);dao.insertStudent(student);System.out.println("插入后:student = " + student);sqlSession.commit();}@Testpublic void test02() {Student student = new Student("张三", 23, 93.5);System.out.println("插入前:student = " + student);dao.insertStudentCatchId(student);System.out.println("插入后:student = " + student);sqlSession.commit();}@Testpublic void test03() {dao.deletetudentById(17);sqlSession.commit();}@Testpublic void test04() {Student student = new Student("李四", 23, 93.5);student.setId(18);dao.updateStudent(student);sqlSession.commit();}@Testpublic void test05() {List<Student> students = dao.selectAllStudents();for(Student student : students) {System.out.println(student);}sqlSession.commit();}/*不能用了* @Test public void test06() {* * Map<String, Object> map = dao.selectAllStudentsMap();* System.out.println(map.get("李四")); sqlSession.commit();* * }*/@Testpublic void test07() {Student student = dao.selectStudentById(19);System.out.println(student);sqlSession.commit();}@Testpublic void test08() {List<Student> students = dao.selectStudentsByName("张");for(Student student : students) {System.out.println(student);}sqlSession.commit();}}

2.4 多查询条件无法整体接收问题的解决

/08-selectByMap
1)将这多个参数封装为一个Map
A、修改Dao接口
添加如下方法

List<Student> selectAllStudentsByCondition(Map<String, Object> map);

B、修改测试类

@Testpublic void test01() {Student stu = new Student("田七", 27, 95);Map<String, Object> map = new HashMap<String, Object>();map.put("nameCon", "张");map.put("ageCon", 23);map.put("stu", stu);List<Student> students = dao.selectAllStudentsByCondition(map);for(Student student : students) {System.out.println(student);}sqlSession.commit();}

C、修改映射文件

<select id="selectAllStudentsByCondition" resultType="Student">select id,name,age,score from student where name like '%' #{nameCon} '%' and age > #{ageCon} and score > #{stu.score}</select>

2)多个参数逐个接收
/09-selectByCondition
A、修改Dao接口

List<Student> selectAllStudentsByCondition(String name, int age);

B、修改测试类

List<Student> students = dao.selectAllStudentsByCondition("张", 23);for(Student student : students) {System.out.println(student);}sqlSession.commit();

C、修改映射文件
这里使用索引 分别指向第一个内容和第二个内容

<select id="selectAllStudentsByCondition" resultType="Student">select id,name,age,score from student where name like '%' #{0} '%' and age > #{1} </select>

#{}中可以放什么内容?
1)参数对象的属性
2)随意内容,此时的#{}是个占位符
3)参数为map时的key
4)参数为map时,若key所对应的value为对象,则可将该对象的属性放入
5)参数的索引号

2.5 动态SQL

动态SQL,主要用于解决查询条件不确定的清空:提交的查询条件不同,执行的SQL语句不同。若将每种可能的情况逐一列出,对所有条件进行排列组合,会出现大量的SQL语句。
/10-dynamicSql
1)if标签
本例实现功能:用户提交的查询条件可以包含一个姓名的模糊查询,同时还可以包含一个年龄的下限。当然,用户在提交表单时可能两个条件均做出设定,或都不做,或只做一个。
引发的问题是,查询条件不确定,查询条件依赖于用户提交的内容。此时,就可使用动态SQL语句,根据用户提交内容对执行的SQL进行拼接。
接口类

public interface IStudentDao {List<Student> selectStudentsByIf(Student student);
}

映射文件
通过在where后添加一个“1=1”条件,解决两个条件均未做设定的情况。
有名字,按名字查。没名字有年龄,按年龄查。都没有,显示所有。

<select id="selectStudentsByIf" resultType="Student">select id,name,age,score from student where 1=1<if test="name != null and name !=''">and  name like '%' #{name} '%'</if><if test="age > 0">and age > #{age}</if></select>

测试类

@Testpublic void test01() {//Student stu = new Student("张", 23, 0);//Student stu = new Student("", 23, 0);Student stu = new Student("", 0, 0);List<Student> students = dao.selectStudentsByIf(stu);for(Student student : students) {System.out.println(student);}sqlSession.commit();}

2)where标签
上述添加1=1,当数据量大时,严重影响查询效率。
Dao接口

List<Student> selectStudentsByWhere(Student student);

映射文件
在有查询条件时,自动添加where子句;没有查询条件时,不会添加。而且系统会自动将多出的and去掉。

<select id="selectStudentsByWhere" resultType="Student">select id,name,age,score from student <where><if test="name != null and name != ''">and   name like '%' #{name} '%'</if><if test="age > 0">and age > #{age}</if></where></select>

测试类

public void test02() {Student stu = new Student("张", 23, 0);//Student stu = new Student("", 23, 0);//Student stu = new Student("", 0, 0);List<Student> students = dao.selectStudentsByWhere(stu);for(Student student : students) {System.out.println(student);}sqlSession.commit();}

3)choose标签
只可以包含when和otherwise,联合使用完成java中的开关语句switch…case功能
本例完成,若姓名不空,按姓名查询;若姓名为空,按年龄查;若没有查询条件,则没有结果。
Dao接口

List<Student> selectStudentsByChoose(Student student);

映射文件

<select id="selectStudentsByChoose" resultType="Student">select id,name,age,score from student <where><choose><when test="name != null and name != ''">and  name like '%' #{name} '%'  </when><when test="age > 0">and age > #{age}</when><otherwise>1 = 2</otherwise></choose></where></select>

测试类

//choose用法  when中有一个成立了,后面就不看了@Testpublic void test03() {//Student stu = new Student("张", 23, 0);//Student stu = new Student("", 23, 0);Student stu = new Student("", 0, 0);List<Student> students = dao.selectStudentsByChoose(stu);for(Student student : students) {System.out.println(student);}sqlSession.commit();}

4)foreach标签 遍历数组
Dao接口

List<Student> selectStudentsByForeach(int[] ids);

映射文件

<select id="selectStudentsByForeach" resultType="Student">
<!--         select id,name,age,score from student where id in (1,3,20)-->        select id,name,age,score from student <if test="array.length > 0">  where id in<foreach collection="array" item="myid" open="(" close=")" separator=",">#{myid}</foreach></if></select>

测试

@Testpublic void test04() {int[] ids = {1, 3};List<Student> students = dao.selectStudentsByForeach(ids);for(Student student : students) {System.out.println(student);}sqlSession.commit();}

5)foreach 遍历list基本类型
Dao接口

List<Student> selectStudentsByForeach2(List<Integer> ids);

映射文件

<select id="selectStudentsByForeach2" resultType="Student">select id,name,age,score from student <if test="list.size > 0">   where id in<foreach collection="list" item="myid" open="(" close=")" separator=",">#{myid}</foreach></if></select>

测试

@Testpublic void test05() {List<Integer> ids = new ArrayList<Integer>();ids.add(1);ids.add(3);List<Student> students = dao.selectStudentsByForeach2(ids);for(Student student : students) {System.out.println(student);}sqlSession.commit();}

6)foreach 遍历list自定义数据类型
Dao接口

List<Student> selectStudentsByForeach3(List<Student> students);

映射文件

<select id="selectStudentsByForeach3" resultType="Student">select id,name,age,score from student <if test="list.size > 0">   where id in<foreach collection="list" item="stu" open="(" close=")" separator=",">#{stu.id}</foreach></if></select>

测试

@Testpublic void test06() {Student stu1 = new Student();stu1.setId(1);Student stu2 = new Student();stu2.setId(3);List<Student> stus = new ArrayList<Student>();stus.add(stu1);stus.add(stu2);List<Student> students = dao.selectStudentsByForeach3(stus);for(Student student : students) {System.out.println(student);}sqlSession.commit();}

7)sql标签
可读性差,但对于大量重复语句易修改。
Dao接口

List<Student> selectStudentsBySqlFragment(List<Student> students);

映射

<select id="selectStudentsBySqlFragment" resultType="Student">select <include refid="selectColumns"></include>from student <if test="list.size > 0">  where id in<foreach collection="list" item="stu" open="(" close=")" separator=",">#{stu.id}</foreach></if></select><sql id="selectColumns">id,name,age,score</sql>

测试

@Testpublic void test07() {Student stu1 = new Student();stu1.setId(1);Student stu2 = new Student();stu2.setId(3);List<Student> stus = new ArrayList<Student>();stus.add(stu1);stus.add(stu2);List<Student> students = dao.selectStudentsBySqlFragment(stus);for(Student student : students) {System.out.println(student);}sqlSession.commit();}

三大框架之---MyBaits第二章相关推荐

  1. 手把手教你使用SSM框架实现一个学生管理系统第二章之创建一个web工程及相关配置文件的介绍

    SSM框架的基本介绍 文字概述: SSM:spring+springMVC+mybaits Spring:是一个容器,就是一个bean(实体对象)大集合. SpringMVC:控制器(业务逻辑层)(视 ...

  2. Foundations of Machine Learning 2nd——第二章 PAC学习框架 后记

    Foundations of Machine Learning 2nd--第二章 PAC学习框架后记 前言 Generalities 一般性 可确定性 VS 随机场景 定义1 Agnostic PAC ...

  3. 第二章 UT单元测试——GTest框架实例

    系列文章目录 第一章 UT单元测试--GoogleTest通用构建说明 第二章 UT单元测试--GTest框架实例 文章目录 系列文章目录 前言 一.环境配置 二.使用步骤 1.添加待测源码 2.修改 ...

  4. 微信小程序零基础入门_第二章 小程序框架_逻辑层

    第二章 小程序框架_逻辑层 2.1 逻辑层 小程序开发框架的逻辑层是基于JavaScript进行编写和实现的.在开发过程中写的所有代码,最终都被整合成一份JavaScript,在小程序启动的时候开始执 ...

  5. Foundations of Machine Learning 2nd——第二章 PAC学习框架

    Foundations of Machine Learning 2nd--第二章 PAC学习框架 前言 定义介绍 Generalization error Empirical error 定理1 PA ...

  6. 第二章 分布式服务框架Zookeeper

    第二章 分布式服务框架Zookeeper 1. Zookeeper概述 Zookeeper 发布/订阅模式的分布式框架主要是用来解决分布式应用中经常遇到的一些数据管理问题,提高分布式,高可用的服务,协 ...

  7. Educoder–Java高级特性(第二章)- 集合框架【笔记+参考代码】

    Educoder–Java高级特性(第二章)- 集合框架[笔记+参考代码] 第一关 编程要求 请仔细阅读右侧代码,根据方法内的提示,在Begin - End区域内进行代码补充,创建ArrayList集 ...

  8. 人工智能:第二章 知识表示方法

    第二章 知识表示方法 教学内容:本章讨论知识表示的各种方法,是人工智能课程三大内容(知识表示.知识推理.知识应用)之一,也是学习人工智能其他内容的基础. 教学重点:状态空间法.问题归约法.谓词逻辑法. ...

  9. [Effective Java]第二章 创建和销毁对象

    第一章      前言 略... 第二章      创建和销毁对象 1.            考虑用静态工厂方法代替构造器 创建对象方法:一是最常用的公有构造器,二是静态工厂方法.下面是一个Bool ...

  10. 《谁说菜鸟不会数据分析》学习笔记 第一章总览 第二章数据分析思路

    网上的信息太琐碎了,根本没搞懂什么是数据分析方法什么是数据分析方法论,所以找了一本比较简单的书来系统学习一下,本来打算粗略看完,但是觉得这本书知识还是不错的,所以决定在未来一周把这本书用心学一下. 这 ...

最新文章

  1. sysfs_create_dir_ns
  2. 逻辑模型设计步骤-粒度层次划分
  3. Java解码网站post字符串(swich case用法和乱码判断)
  4. python进阶学啥书籍_2018年Python学习进阶书籍推荐
  5. mysql 中函数如何转存_MySQL函数转储存(当前月数据同步)
  6. java中必检异常有哪些_Java面试题经典面试题220道(附答案)
  7. C++——多进程并发与多线程并发
  8. Git学习总结(13)——使用git.oschina作为自己的源代码在线管理库
  9. css中em单位和rem单位
  10. Windows Phone 更改datePicker的显示格式
  11. 利用构造函数实现累加
  12. 各平台的坐标拾取系统
  13. 【sketchup 2021】草图大师的高级工具使用3【复杂贴图制作实例(山体和球面贴图、全景天空绘制、吊顶添加光带)、图层(标记)工具使用、视图与样式工具的常规使用与高级使用说明】
  14. tomcat:学习:一:(第1次操作:成功)手机下载 tomcat 服务器里面的文件+tomcat 安装配置使用
  15. 常用贴片器件正负极区分
  16. AtCoder Beginner Contest 156 D Bouquet 失之交臂 容斥原理+二项式定理+乘法逆元+快速幂+模后负数 多余担心
  17. mt7620a上tf卡驱动的支持
  18. jboot 配置durid + logback debug打印 sql+执行参数(非?)
  19. MATLAB坐标轴位置调整
  20. java 获取两个时间差_java如何获取两个日期的时间差

热门文章

  1. 财务金额转换:小写金额转换成大写算法
  2. 元素偏移offset的常用属性
  3. 小程序打开速度慢是服务器原因吗,网页打开速度慢的原因以及解决方法
  4. 凸包(convex hull),凸包络面(convex envelope), 凸低估计量(convex underestimator), 图上方(epigraph),
  5. 各个版本的金蝶kis的区别
  6. 剪刀石头布 (上 下) 注意:合成图片,内容自理
  7. 解决:RN和H5之间通信
  8. 《企业大数据系统构建实战:技术、架构、实施与应用》一2.3 大数据制度和流程规范...
  9. 红帽子linux返回上层目录,【IT技术分享】红帽RHCSA/RHCE/RHCA Linux常用目录、命令、权限技术学习...
  10. Win10更改用户账户、appdata和ProgramData的默认存储路径