MyBatis学习(三)MyBatis基于动态代理方式的增删改查
1、前言
上一期讲到MyBatis-Statement版本的增删改查、可以发现、这种代码写下来冗余的地方特别多、写一套没啥、如果涉及到多表多查询的时候就容易出现问题。故、官方推荐了一种方法、即MyBatis基于动态代理方式的增删改查、它是一种基于接口开发、Mapper动态的对SQL进行寻找。通过具体概念请点击此处 查阅、这里不过多解释、代码中有详细的注释。
项目骨架如图所示:

2、前期准备
1、编写conf.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 通过 environments 的 default值 和 environment 的 id 来指定mybatis运行时的数据库环境 -->
<environments default="development">
<!-- 开发环境(本机)、environment可以有多套 -->
<environment id="development">
<!-- 事务提交方式
JDBC:利用JDBC处理事务(commit rollback close)
MANAGED:将事务交给其他组件托管(Spring、jobss),默认情况下会关闭连接。
-->
<transactionManager type="JDBC"/>
<!-- 数据源类型
POOLED:使用数据库连接池
UNPOOLED:传统的JDBC模式(消耗性能、不推荐)
JNDI:从tomcat中获取内置数据库连接池
-->
<dataSource type="POOLED">
<!-- 配置数据库信息 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/xiao?serverTimezone=GMT%2B8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 加载映射文件 -->
<mapper resource="com/feng/mapper/studentMapper.xml"/>
</mappers>
</configuration>
2、创建实体类和对应的表(entity)
package com.feng.entity;
public class Student {
private int stuNo;
private String stuName;
private int stuAge;
private String graName;
public int getStuNo() {
return stuNo;
}
public void setStuNo(int stuNo) {
this.stuNo = stuNo;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public int getStuAge() {
return stuAge;
}
public void setStuAge(int stuAge) {
this.stuAge = stuAge;
}
public String getGraName() {
return graName;
}
public void setGraName(String graName) {
this.graName = graName;
}
public Student(int stuNo, String stuName, int stuAge, String graName) {
this.stuNo = stuNo;
this.stuName = stuName;
this.stuAge = stuAge;
this.graName = graName;
}
public Student() {
}
@Override
public String toString() {
return '{'+"stuNo=" + stuNo +
", stuName='" + stuName + '\'' +
", stuAge=" + stuAge +
", graName='" + graName + '\'' +
'}';
}
}

3、Mapper文件的编写
一个Mapper对应一个xml、动态代理方式中、mapper和对应的xml关系紧密、故两者放在同一文件夹下。
package com.feng.mapper;
import com.feng.entity.Student;
import java.util.List;
// 操作mybatis的接口
public interface StudentMapper {
/*
a. 约定
1、方法名和mapper.xml文件中标签的id值相同
2、方法的输入参数和mapper.xml文件中标签的parameterType类型一致
3、方法的返回值和mapper.xml文件中标签的resultType类型一致
b. 实现
1、namespace的值就是接口的全类名 (实现接口和xml的映射)
2、根据接口的方法名、找到mapper.xml中的SQL标签(方法名 = SQL标签Id值)
习惯:SQL映射文件(mapper.xml) 和接口放在同一个包中、注意修改conf.xml加载mapper文件的路径
以上、可以通过接口的方法定位 ---> SQL语句
*/
Student queryStudentByStuNo(int stuNo);
// 查询全部
List<Student> queryAllStudents();
// 增加
void addStudent(Student student);
// 删除
void deleteStudentByStuNo(int stuNo);
// 修改
void updateStudentByStuNo(Student student);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace:该mapper.xml映射文件的唯一标识-->
<mapper namespace="com.feng.mapper.StudentMapper">
<!-- 通过 namespace.id来定位该sql -->
<!-- 各种标签的id;
parameterType:输入参数的类型;
resultType:查询的返回结果的类型(具体对象映射到路径)
-->
<select id="queryStudentByStuNo" parameterType="int" resultType="com.feng.entity.Student">
select * from student where stuno = #{stuNo}
</select>
<select id="queryAllStudents" resultType="com.feng.entity.Student">
select * from student
</select>
<insert id="addStudent" parameterType="com.feng.entity.Student">
insert into student(stuno,stuname,stuage,graname) values(#{stuNo},#{stuName},#{stuAge},#{graName})
</insert>
<update id="updateStudentByStuNo" parameterType="com.feng.entity.Student">
update student set stuname=#{stuName},stuage=#{stuAge},graname=#{graName} where stuno=#{stuNo}
</update>
<delete id="deleteStudentByStuNo" parameterType="int">
delete from student where stuno = #{stuNo}
</delete>
</mapper>
4、编写测试类进行测试
(注:Mybatis约定了一个输入参数对应一个输出参数、且不能出现多个、故改动代码逻辑、采用对象的方式对返回值进行约定。)
package com.feng.test;
import com.feng.entity.Student;
import com.feng.mapper.StudentMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
public class Test {
// 1、查询单个学生
public static void queryStudentByStuNo() throws IOException {
// conf.xml ----> reader
Reader reader = Resources.getResourceAsReader("com/feng/conf.xml");
// reader ---> SqlSession
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sessionFactory.openSession();
StudentMapper studentMapper = session.getMapper(StudentMapper.class);
Student student = studentMapper.queryStudentByStuNo(1);// 接口中的方法->SQL语句
System.out.println(student);
session.close();
}
// 2、查询全部学生
public static void queryAllStudents() throws IOException {
Reader reader = Resources.getResourceAsReader("com/feng/conf.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sessionFactory.openSession();
StudentMapper studentMapper = session.getMapper(StudentMapper.class);
List<Student> students = studentMapper.queryAllStudents();
System.out.println(students);
session.close();
}
// 3、增加学生
public static void addStudent() throws IOException {
Reader reader = Resources.getResourceAsReader("com/feng/conf.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sessionFactory.openSession();
Student student = new Student(3, "柴犬", 25, "六年级");
StudentMapper studentMapper = session.getMapper(StudentMapper.class);
studentMapper.addStudent(student);
session.commit(); // 提交事务
System.out.println("增加成功!");
session.close();
}
// 4、修改学生
public static void updateStudentByStuNo() throws IOException {
Reader reader = Resources.getResourceAsReader("com/feng/conf.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sessionFactory.openSession();
Student student = new Student();
// 修改那个人, where stuNo = 2
student.setStuNo(2);
// 修改成啥样子
student.setStuName("三哈");
student.setStuAge(25);
student.setGraName("一年级");
StudentMapper studentMapper = session.getMapper(StudentMapper.class);
studentMapper.updateStudentByStuNo(student);
session.commit(); // 提交事务
System.out.println("修改成功!");
session.close();
}
// 5、删除学生
public static void deleteStudentByStuNo() throws IOException {
Reader reader = Resources.getResourceAsReader("com/feng/conf.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sessionFactory.openSession();
StudentMapper studentMapper = session.getMapper(StudentMapper.class);
studentMapper.deleteStudentByStuNo(3);
session.commit(); // 提交事务
System.out.println("删除成功");
session.close();
}
public static void main(String[] args) throws IOException {
deleteStudentByStuNo();
queryAllStudents();
}
}
5、测试结果

MyBatis学习(三)MyBatis基于动态代理方式的增删改查的更多相关文章
- 02.Mybatis的动态代理方式实现增删改查
动态代理的方式实现增删改查: 通过约定的方式定位sql语句 约定 > 配置文件 > 硬编码 约定的目标是省略掉通过硬编码的方式定位sql的代码,通过接口直接定位出sql语句,以下代码为通过 ...
- MyBatis学习(三)---MyBatis和Spring整合
想要了解MyBatis基础的朋友可以通过传送门: MyBatis学习(一)---配置文件,Mapper接口和动态SQL http://www.cnblogs.com/ghq120/p/8322302. ...
- Spring Boot入门系列(十八)整合mybatis,使用注解的方式实现增删改查
之前介绍了Spring Boot 整合mybatis 使用xml配置的方式实现增删改查,还介绍了自定义mapper 实现复杂多表关联查询.虽然目前 mybatis 使用xml 配置的方式 已经极大减轻 ...
- Android-Sqlite-OOP方式操作增删改查
之前写的数据库增删改查,是使用SQL语句来实现的,Google 就为Android开发人员考虑,就算不会SQL语句也能实现增删改查,所以就有了OOP面向对象的增删改查方式 其实这种OOP面向对象的增删 ...
- 基于vue-easytable实现数据的增删改查
基于vue-easytable实现数据的增删改查 原理:利用vue的数据绑定和vue-easetable的ui完成增删改查 后端接口: 1.条件查询表中数据 http://localhost:4795 ...
- MyBatis总结三:使用动态代理实现dao接口
由于我们上一篇实现MyBatis的增删改查的接口实现类的方法都是通过sqlsession调用方法,参数也都类似,所以我们使用动态代理的方式来完善这一点 MyBatis动态代理生成dao的步骤: 编写数 ...
- EF6 学习笔记(二):操练 CRUD 增删改查
EF6学习笔记总目录 ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 接上篇: EF6 学习笔记(一):Code First 方式生成数据库及初始化数据库实际操作 本篇原文链接: I ...
- 基于SpringMVC的文件(增删改查)上传、下载、更新、删除
一.项目背景 摘要:最近一直在忙着项目的事,3个项目过去了,发现有一个共同的业务,那就是附件的处理,附件包括各种文档,当然还有图片等特殊文件,由于时间的关系,每次都是匆匆忙忙的搞定上线,称这项目的空档 ...
- 【EF6学习笔记】(二)操练 CRUD 增删改查
本篇原文链接: Implementing Basic CRUD Functionality 说明:学习笔记参考原文中的流程,为了增加实际操作性,并能够深入理解,部分地方根据实际情况做了一些调整:并且根 ...
随机推荐
- Vue 中使用 TypeScript 详细总结
VUE 项目中使用 Typescript 第一节:项目起步 Vue 中使用 TypeScript 项目中主要使用到的第三方依赖 vue2 vue-class-component vue-propert ...
- Debugging and Running MPI in Xcode
1.安装 mpich2 与 Xcode mpich2安装地址:/usr/local/Cellar/mpich2/3.1.4/ Xcode 版本:Version 6.2 (6C131e) 2.新建工程 ...
- Neville 插值方法
简介 wikipedia: Neville's method 在数学上,Neville 算法是一种计算插值多项式方法,由数学家Eric Harold Neville提出.由给定的n+1个节点,存在一个 ...
- Python通过subprocess.Popen.poll控制流程
python写流程控制的时候,有时需要等待运行结果完成才能进行下一步.有几个想法: 一是反复循环判断直到生成结果文件(且文件中有预期结果),低效易出错: 二是用subprocess模块来判断进程结果, ...
- CSS浮动效果
#div1{ background-color: yellow; width: 150px; height:150px; position: absolute; top:150px; left: 15 ...
- 关于ARM的PC指针(什么时候PC+8,PC+4,PC-4,PC-8)转
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. ...
- 【NCBI教程】资源汇总整理 (转载)
主题 网址 备注 [NCBI教程]资源汇总整理 http://www.omicshare.com/forum/thread-200-1-1.html (出处: OmicShare Forum)
- C++ 中的多重继承的问题
如何正确使用C++多重继承 BY R12F · PUBLISHED 2011年06月17日 · UPDATED 2012年03月11日 原创文章,转载请注明:转载自Soul Apogee本文链接地 ...
- 开发安卓记账本-HelloAndroid的完成
这个寒假要完成一个家庭记账本软件的开发,今天完成了Android Studio的安装与第一个安卓应用的运行(HelloAndroid) 下图是效果: 1.Android Studio的安装 可直接百度 ...
- 日常Java 2021/11/9
线程的优先级 每一个Java线程都有一个优先级,这样有助于操作系统确定线程的调度顺序.Java线程的优先级是一个整数,其取值范围是1(Thread.MIN_PRIORITY ) -10 (Thread ...