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基于动态代理方式的增删改查的更多相关文章

  1. 02.Mybatis的动态代理方式实现增删改查

    动态代理的方式实现增删改查: 通过约定的方式定位sql语句 约定 > 配置文件 > 硬编码 约定的目标是省略掉通过硬编码的方式定位sql的代码,通过接口直接定位出sql语句,以下代码为通过 ...

  2. MyBatis学习(三)---MyBatis和Spring整合

    想要了解MyBatis基础的朋友可以通过传送门: MyBatis学习(一)---配置文件,Mapper接口和动态SQL http://www.cnblogs.com/ghq120/p/8322302. ...

  3. Spring Boot入门系列(十八)整合mybatis,使用注解的方式实现增删改查

    之前介绍了Spring Boot 整合mybatis 使用xml配置的方式实现增删改查,还介绍了自定义mapper 实现复杂多表关联查询.虽然目前 mybatis 使用xml 配置的方式 已经极大减轻 ...

  4. Android-Sqlite-OOP方式操作增删改查

    之前写的数据库增删改查,是使用SQL语句来实现的,Google 就为Android开发人员考虑,就算不会SQL语句也能实现增删改查,所以就有了OOP面向对象的增删改查方式 其实这种OOP面向对象的增删 ...

  5. 基于vue-easytable实现数据的增删改查

    基于vue-easytable实现数据的增删改查 原理:利用vue的数据绑定和vue-easetable的ui完成增删改查 后端接口: 1.条件查询表中数据 http://localhost:4795 ...

  6. MyBatis总结三:使用动态代理实现dao接口

    由于我们上一篇实现MyBatis的增删改查的接口实现类的方法都是通过sqlsession调用方法,参数也都类似,所以我们使用动态代理的方式来完善这一点 MyBatis动态代理生成dao的步骤: 编写数 ...

  7. EF6 学习笔记(二):操练 CRUD 增删改查

    EF6学习笔记总目录 ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 接上篇: EF6 学习笔记(一):Code First 方式生成数据库及初始化数据库实际操作 本篇原文链接: I ...

  8. 基于SpringMVC的文件(增删改查)上传、下载、更新、删除

    一.项目背景 摘要:最近一直在忙着项目的事,3个项目过去了,发现有一个共同的业务,那就是附件的处理,附件包括各种文档,当然还有图片等特殊文件,由于时间的关系,每次都是匆匆忙忙的搞定上线,称这项目的空档 ...

  9. 【EF6学习笔记】(二)操练 CRUD 增删改查

    本篇原文链接: Implementing Basic CRUD Functionality 说明:学习笔记参考原文中的流程,为了增加实际操作性,并能够深入理解,部分地方根据实际情况做了一些调整:并且根 ...

随机推荐

  1. FJOI2020 的两道组合计数题

    最近细品了 FJOI2020 的两道计数题,感觉抛开数据范围不清还卡常不谈里面的组合计数技巧还是挺不错的.由于这两道题都基于卡特兰数的拓展,所以我们把它们一并研究掉. 首先是 D1T3 ,先给出简要题 ...

  2. 【贾志豪NOIP模拟题】慰问员工 cheer 【最小生成树】【对边权值的一些处理】

    Description LongDD 变得非常懒, 他不想再继续维护供员工之间供通行的道路. 道路被用来连接 N(5 <= N <= 10,000)个房子, 房子被连续地编号为 1..N. ...

  3. 【软连接已存在,如何覆盖】ln: failed to create symbolic link ‘file.txt’: File exists

    ln -s 改成 ln -sf f在很多软件的参数中意味着force ln -sf /usr/bin/bazel-1.0.0 /usr/bin/bazel

  4. Docker Error response from daemon,Docker 换镜像

    Docker换镜像,Docker  pull.Docker search 失败出现以下错误 Error response from daemon: Get https://index.docker.i ...

  5. C语言小练习 微型学生管理系统

    很简陋,没有做输入校验,以写出来为第一目的,中间出了不少问题,尤其是结构体内字符串赋值的时候(理解不透彻),字符串比较用strcmp不能直接==判定,逻辑也很重要,不然会出现莫名其妙的问题. 涉及知识 ...

  6. ping 的原理

    ping 的原理ping 程序是用来探测主机到主机之间是否可通信,如果不能ping到某台主机,表明不能和这台主机建立连接.ping 使用的是ICMP协议,它发送icmp回送请求消息给目的主机.ICMP ...

  7. 分布式服务治理框架Dubbo的前世今生及应用实战

    Dubbo的出现背景 Dubbo从开源到现在,已经出现了接近10年时间,在国内各大企业被广泛应用. 它到底有什么魔力值得大家去追捧呢?本篇文章给大家做一个详细的说明. 大规模服务化对于服务治理的要求 ...

  8. javascript的原型与原型链

    首先套用一句经典名言,JavaScript中万物皆对象. 但是对象又分为函数对象和普通对象. function f1(){}; var f2=function(){}; var f3=new Func ...

  9. 『学了就忘』Linux文件系统管理 — 67、通过命令模式进行LVM分区

    目录 1.物理卷管理 (1)准备硬盘或者分区 (2)建立物理卷 (3)查看物理卷 (3)删除物理卷 2.创建卷组 (1)建立卷组 (2)查看卷组 (3)增加卷组容量 (4)减小卷组容量 (5)删除卷组 ...

  10. 零基础学习java------35---------删除一个商品案例,删除多个商品,编辑(修改商品信息),校验用户名是否已经注册(ajax)

    一. 删除一个商品案例 将要操作的表格 思路图  前端代码 <%@ page language="java" contentType="text/html; cha ...