文章目录

  • 一、搭建环境
    • 1、创建项目
    • 2、添加jar包
    • 3、创建实体
    • 4、创建Mybatis工具类
  • 二、配置Mybatis框架
    • 1、添加db.properties文件
    • 2、添加log4j.properties文件
    • 3、添加全局配置文件
    • 4、添加UsersMapper接口
    • 5、添加UsersMapper映射配置文件
  • 三、实现查询所有用户
    • 1、修改映射配置文件
    • 2、修改UserMapper接口添加抽象方法
    • 3、创建业务层接口
    • 4、创建业务层接口实现类
    • 5、创建测试类
    • 6、运行结果
  • 四、实现根据用户ID查询用户
    • 1、修改映射配置文件
    • 2、修改UsersMapper接口添加抽象方法
    • 3、修改业务层接口
    • 4、修改业务层接口实现类
    • 5、创建测试类
  • 五、Mapper 动态代理模式下的多参数处理
    • 1、顺序传参法
    • 2、@Param注解传参法
    • 3、POJO传参法
    • 4、Map传参法
  • 六、映射配置文件中的特殊字符处理
    • 1、使用符号实体
    • 2、使用CDATA区
  • 七、 Mybatis 的分页查询
    • 1、使用 RowBounds
      • 1.1、修改映射文件
      • 1.2、修改UsersMapper接口
      • 1.3、创建测试类
    • 2、使用 SQL 语句分页
      • 2.1、修改映射配置文件
      • 2.2、修改UsersMapper
      • 2.3、创建测试类
  • 八、Mapper 动态代理模式下的 DML 操作
    • 1、实现添加用户业务
      • 1.1、修改映射配置文件
      • 1.2、修改UsersMapper接口
      • 1.3、创建测试类
  • 九、主键值回填
    • 1、获取自增主键值
      • 1.1、开启自动获取自增主键值
        • 局部配置:
        • 全局配置:
      • 1.2、修改UsersMapper接口
      • 1.3、创建测试类
    • 2、获取非自增主键值
      • 2.1、修改映射配置文件
      • 2.2、修改UsersMapper接口
      • 2.3、创建测试类

一、搭建环境

1、创建项目

2、添加jar包

3、创建实体

public class Users {private int userid;private String username;private String usersex;public int getUserid() {return userid;}public void setUserid(int userid) {this.userid = userid;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getUsersex() {return usersex;}public void setUsersex(String usersex) {this.usersex = usersex;}@Overridepublic String toString() {return "Users{" +"userid=" + userid +", username='" + username + '\'' +", usersex='" + usersex + '\'' +'}';}
}

4、创建Mybatis工具类

package com.bjsxt.utils;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.InputStream;public class MybatisUtils {private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<>();private static SqlSessionFactory sqlSessionFactory = null;static{//创建SqlSessionFactoryInputStream is = null;try{is = Resources.getResourceAsStream("mybatis-cfg.xml");}catch (IOException e){e.printStackTrace();}sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);}//获取SqlSessionpublic static SqlSession getSqlSession(){SqlSession sqlSession = threadLocal.get();if(sqlSession == null){sqlSession = sqlSessionFactory.openSession();threadLocal.set(sqlSession);}return sqlSession;}//关闭SqlSessionpublic static void closeSqlSession(){SqlSession sqlSession = threadLocal.get();if(sqlSession != null){sqlSession.close();threadLocal.set(null);}}
}

二、配置Mybatis框架

1、添加db.properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/bjsxt
jdbc.username=root
jdbc.password=mysql

2、添加log4j.properties文件

log4j.rootLogger=debug,console,logfile### appender.console输出到控制台 ###
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=<%d> %5p (%F:%L) [%t] (%c) - %m%n
log4j.appender.console.Target=System.out### appender.logfile输出到日志文件 ###
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=SysLog.log
log4j.appender.logfile.MaxFileSize=500KB
log4j.appender.logfile.MaxBackupIndex=7
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=<%d> %p (%F:%L) [%t] %c - %m%n

3、添加全局配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--    引入db.properties属性文件--><properties resource="db.properties"/><!--    配置别名--><typeAliases><package name="com.bjsxt.pojo"/></typeAliases><!--    配置环境--><environments default="development"><environment id="development"><transactionManager type="JDBC"></transactionManager><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><!--    引入Mapper映射配置文件--><mappers><package name="com.bjsxt.mapper"/></mappers>
</configuration>

4、添加UsersMapper接口

public interface UsersMapper {}

5、添加UsersMapper映射配置文件

<?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="com.bjsxt.mapper.UsersMapper"></mapper>

三、实现查询所有用户

1、修改映射配置文件

<?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="com.bjsxt.mapper.UsersMapper"><!--    查询所有用户--><select id="selectUsersAll" resultType="users">select * from users</select></mapper>

2、修改UserMapper接口添加抽象方法

public interface UsersMapper {List<Users> selectUsersAll();
}

3、创建业务层接口

public interface UsersService {List<Users> findUsersAll();
}

4、创建业务层接口实现类

public class UsersServiceImpl implements UsersService {@Overridepublic List<Users> findUsersAll() {List<Users> list = null;try{SqlSession sqlSession = MybatisUtils.getSqlSession();//getMapper方法的作用是根据给定的接口的Class对象,生成该接口的接口实现类的代理对象UsersMapper mapper = sqlSession.getMapper(UsersMapper.class);list = mapper.selectUsersAll();}catch (Exception e){e.printStackTrace();}finally {MybatisUtils.closeSqlSession();}return list;}
}

5、创建测试类

public class SelectUsersAllTest {public static void main(String[] args) {UsersService usersService = new UsersServiceImpl();List<Users> list = usersService.findUsersAll();//遍历list的两种方式list.forEach(e -> System.out.println(e));list.forEach(System.out::println);}
}

6、运行结果

四、实现根据用户ID查询用户

1、修改映射配置文件

<!--    根据用户ID查询用户--><select id="selectUsersById" resultType="users">select * from users where userid = #{userid}</select>

2、修改UsersMapper接口添加抽象方法

public interface UsersMapper {List<Users> selectUsersAll();Users selectUsersById(int userid);
}

3、修改业务层接口

public interface UsersService {List<Users> findUsersAll();Users findUsersById(int userid);
}

4、修改业务层接口实现类

    @Overridepublic Users findUsersById(int userid) {Users users = null;try{SqlSession sqlSession = MybatisUtils.getSqlSession();UsersMapper mapper = sqlSession.getMapper(UsersMapper.class);users = mapper.selectUsersById(userid);}catch (Exception e){e.printStackTrace();}finally {MybatisUtils.closeSqlSession();}return users;}

5、创建测试类

public class SelectUsersByIdTest {public static void main(String[] args) {UsersService usersService = new UsersServiceImpl();Users users = usersService.findUsersById(1);System.out.println(users);}
}

五、Mapper 动态代理模式下的多参数处理

1、顺序传参法

在映射文件中,SQL 语句中的参数需要使用 arg0,arg1…或者 param1,param2…表示参数的顺序。此方法可读性低,且要求参数的顺序不能出错,在开发中不建议使用。

UsersMapper.java:

List<Users> selectUsersOrderParam(String username,String usersex);

UsersMapper.xml:

<!--    根据用户姓名与性别查询用户,使用顺序传参法--><select id="selectUsersOrderParam" resultType="users">select * from users where username = #{param1} and usersex =#{param2}</select>
<!--    根据用户姓名与性别查询用户,使用顺序传参法--><select id="selectUsersOrderParam" resultType="users">select * from users where username = #{arg0} and usersex =#{arg1}</select>

2、@Param注解传参法

在接口方法的参数列表中通过@Param 注解来定义参数名称,在 SQL 语句中通过注解中所定义的参数名称完成参数位置的指定。
此方式在参数不多的情况还是比较直观的,推荐使用。

UsersMapper.xml:

    <!--    根据用户姓名与性别查询用户,使用@Param注解传参法--><select id="selectUsersAnnParam" resultType="users">select * from users where username = #{name} and usersex =#{sex}</select>

UsersMapper.java:

List<Users> selectUsersAnnParam(@Param("name") String username,@Param("sex") String usersex);

3、POJO传参法

在 Mapper 动态代理中也可以使用 POJO 作为传递参数的载体,在 SQL 语句中绑定参数时使用 POJO 的属性名作为参数名即可。此方式推荐使用。

UsersMapper.xml:

    <!--    根据用户姓名与性别查询用户,使用POJO传参法--><select id="selectUsersPOJOParam" resultType="users">select * from users where username = #{username} and usersex =#{usersex}</select>

UsersMapper.java:

List<Users> selectUsersPOJOParam(Users users);

SelectUsersPOJOParamTest.java:

public class SelectUsersPOJOParamTest {public static void main(String[] args) {SqlSession sqlSession = MybatisUtils.getSqlSession();UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);Users users = new Users();users.setUsername("kang");users.setUsersex("male");List<Users> list = usersMapper.selectUsersPOJOParam(users);list.forEach(System.out::println);MybatisUtils.closeSqlSession();}
}

4、Map传参法

在 Mapper 动态代理中也可以使用 Map 作为传递参数的载体,在 SQL 语句中绑定参数时使用 Map 的 Key 作为参数名即可。此方法适合在传递多参数时,如果没有 POJO 能与参数匹配,可以使用该方式传递参数。推荐使用。
MyBatis 传递 map 参数时,如果传递参数中没有对应的 key 值,在执行 sql 语句时默认取的是 null。

UsersMapper.xml:

<!--    根据用户姓名与性别查询用户,使用Map传参法--><select id="selectUsersMapParam" resultType="users">select * from users where username = #{keyname} and usersex =#{keysex}</select>

UsersMapper.java:

List<Users> selectUsersMapParam(Map<String ,String>map);

SelectUsersMapParamTest.java:

public class SelectUsersMapParamTest {public static void main(String[] args) {SqlSession sqlSession = MybatisUtils.getSqlSession();UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);Map<String ,String > map = new HashMap<>();map.put("keyname","kang");map.put("keysex","male");List<Users> list = usersMapper.selectUsersMapParam(map);list.forEach(System.out::println);MybatisUtils.closeSqlSession();}
}

六、映射配置文件中的特殊字符处理

在 Mybatis 的映射配置文件中不可以使用一些特殊字符,如:<,>。
版本较高可用

1、使用符号实体

我们可以使用符号的实体来表示:

    <!--    查询用户ID大于1的用户,特殊字符处理--><select id="selectUsers" resultType="users">select * from users where userid &gt; #{userid}</select>

2、使用CDATA区

CDATA:全称为 Character Data,以"<![CDATA[ "内容" ]]>",CDATA 中的内容不会被解析程序解析。

    <!--    查询用户ID大于1的用户,特殊字符处理--><select id="selectUsers" resultType="users">select * from users where userid <![CDATA[ > ]]> #{userid}</select>

七、 Mybatis 的分页查询

1、使用 RowBounds

RowBounds 是 Mybatis 提供的一个专门处理分页的对象。在 RowBounds 对象中有两个成员变量:

  • offset:偏移量,从 0 开始计数
  • limit:限制条数

使用 RowBounds 进行分页,非常方便,不需要在 SQL 语句中写 limit,即可完成分页功能。但是由于它是在 SQL 查询出所有结果的基础上截取数据的,所以在数据量大的 SQL中并不适用,它更适合在返回数据结果较少的查询中使用。

1.1、修改映射文件

<!--    查询所有数据使用RowBounds实现分页处理--><select id="selectUsersRowBounds" resultType="users">select * from users</select>

1.2、修改UsersMapper接口

    List<Users> selectUsersRowBounds(RowBounds rowBounds);

1.3、创建测试类

public class SelectUsersRowBoundsTest {public static void main(String[] args) {SqlSession sqlSession = MybatisUtils.getSqlSession();UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);RowBounds rowBounds = new RowBounds(0,2);List<Users> list = usersMapper.selectUsersRowBounds(rowBounds);list.forEach(System.out::println);}
}

2、使用 SQL 语句分页

在分页查询时,如果返回的结果较多,那么需要使用特定的 SQL 语句来实现分页处理。在 MySQL 数据库中我们可以使用 limit 实现分页。

2.1、修改映射配置文件

<!--    查询所有数据使用limit实现分页处理--><select id="selectUsersLimit" resultType="users">select * from users limit #{offset},#{limit}</select>

2.2、修改UsersMapper

 List<Users> selectUsersLimit(@Param("offset") int offset,@Param("limit") int limit);

2.3、创建测试类

public class SelectUsersLimitTest {public static void main(String[] args) {SqlSession sqlSession = MybatisUtils.getSqlSession();UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);List<Users> list = usersMapper.selectUsersLimit(0,2);list.forEach(System.out::println);MybatisUtils.closeSqlSession();}
}

八、Mapper 动态代理模式下的 DML 操作

1、实现添加用户业务

1.1、修改映射配置文件

<!--    添加用户--><insert id="insertUsers">insert into users values (default ,#{username},#{usersex})</insert>

1.2、修改UsersMapper接口

  int insertUsers(Users users);

1.3、创建测试类

public class InsertUsersTest {public static void main(String[] args) {SqlSession sqlSession = MybatisUtils.getSqlSession();UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);Users users = new Users();users.setUsername("kkkkkyyyyyyyyyy");users.setUsersex("male");int flag = usersMapper.insertUsers(users);System.out.println(flag);sqlSession.commit();MybatisUtils.closeSqlSession();}
}

九、主键值回填

在数据库中插入数据时,有时我们是需要获取新数据的主键值。在 Mybatis 中支持主键值回填,可以让我们更够更方便的获取新添加数据的主键值。
Mybatis 中支持两种方法获取主键:
获取自增主键的值。如:MySQL、SqlServer
获取非自增主键的值。如 Oracle

1、获取自增主键值

1.1、开启自动获取自增主键值

有两种方式:

  • 局部配置
  • 全局配置

局部配置:

映射配置文件:

<!--    添加用户获取主键值(自增)--><insert id="insertUsersGetKey" useGeneratedKeys="true" keyProperty="userid">insert into users values (default ,#{username},#{usersex})</insert>

全局配置:

全局配置文件:

<settings>
<setting name="useGeneratedKeys" value="true"/>
</settings>

映射配置文件:

<!--添加用户获取主键值[自增]-->
<insert id="insertUsersGetKey" keyProperty="userid">
insert into users values(default ,#{username},#{usersex})
</insert>

1.2、修改UsersMapper接口

void insertUsersGetKey(Users users);

1.3、创建测试类

public class InsertUsersGetKeyTest {public static void main(String[] args) {SqlSession sqlSession = MybatisUtils.getSqlSession();UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);Users users = new Users();users.setUsername("aaaaaa");users.setUsersex("male");usersMapper.insertUsersGetKey(users);sqlSession.commit();System.out.println(users.getUserid());MybatisUtils.closeSqlSession();}
}

2、获取非自增主键值

2.1、修改映射配置文件

在Mysql数据库中获取插入数据的主键的值有两种:select LAST_INSERT_ID() ,
SELECT @@Identity。
SELECT @@Identity是select LAST_INSERT_ID() 的同义词,两者作用是相同的

<!--    添加用户获取主键值【非自增】 oracle[order:Before]  mysql[order:After]--><insert id="insertUsersGetKey2"><selectKey order="AFTER" keyProperty="userid" resultType="int">select LAST_INSERT_ID()</selectKey>insert into users values(default ,#{username},#{usersex})</insert>
</mapper>

2.2、修改UsersMapper接口

    void insertUsersGetKey2(Users users);

2.3、创建测试类

public class InsertUsersGetKey2Test {public static void main(String[] args) {SqlSession sqlSession = MybatisUtils.getSqlSession();UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);Users users = new Users();users.setUsername("kangkang");users.setUsersex("male");usersMapper.insertUsersGetKey2(users);sqlSession.commit();System.out.println(users.getUserid());MybatisUtils.closeSqlSession();}
}

Mybatis_Mapper动态代理的使用相关推荐

  1. 【spring】动态代理

    代理 动态代理 特点:字节码随用随创建,随用随加载 作用:不修改源码的基础上对方法增强 分类:基于接口的动态代理.基于子类的动态代理 基于接口的动态代理: 涉及的类:Proxy     提供者:JDK ...

  2. (转)面试必备技能:JDK动态代理给Spring事务埋下的坑!

    一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...

  3. Java动态代理和静态代理区别

    静态代理 package staticproxy;/*** 接口* @author newtouch**/ public interface IHello {public void sayHello( ...

  4. java动态代理【一】

    java动态代理的定义:为其他目标类的方法增加切面的逻辑,即在执行目标类方法的时候,先去执行一段如校验检测的逻辑代码.java通俗一点就是生成一个继承目标类的子类,并在每个调用方法都添加一段逻辑. 应 ...

  5. 支撑Java框架的基础技术:泛型,反射,动态代理,cglib

    以Spring为例要想看明白他的源码需要彻底理解Java的一些基础技术泛型,反射同时对于一些高级技术例如动态代理,cglib和字节码技术也需要掌握,下面就按章节来一一说清楚这些技术的核心部分,最后手写 ...

  6. 支撑Spring的基础技术:泛型,反射,动态代理,cglib等

    1.静态代码块和非静态代码块以及构造函数 出自尚学堂视频:<JVM核心机制 类加载全过程 JVM内存分析 反射机制核心原理 常量池理解> public class Parent {stat ...

  7. 【spring】初识aop(面向切面编程) 使用jdk动态代理

    BankServiceIImple.java 代码实现: package com.zzxtit.aop;import java.math.BigDecimal;public interface Ban ...

  8. java静态代理与动态代理

    2019独角兽企业重金招聘Python工程师标准>>> 代理模式是java常见的设计模式.其目的是为其他对象提供一个代理以控制对某个真实对象的访问.通过代理类这一中间层,有效控制对真 ...

  9. Java动态代理机制

    在Java的动态代理机制中,有两个重要的类.一个是InvocationHandler,另一个是Proxy. InvocationHandler:每一个动态代理类都必须要实现InvocationHand ...

最新文章

  1. 将shp导入SDE中出现“表或视图不存在”问题
  2. Android studio | From Zero To One —— Hello Android
  3. [ZT]C#的多线程机制探索(2)
  4. 【牛客 - 188D 】愤怒(01滚动数组优化dp,括号匹配方案个数,tricks)
  5. php 流(Stream)
  6. 一旦上云,欲罢不能,带大家薅一薅“云羊毛”
  7. 《SQL与关系数据库理论——如何编写健壮的SQL代码》一第2章
  8. idea打不了断点红点没对号_你可能不知道的 IDEA 高级调试技巧
  9. python爬虫网络中断_python爬虫项目设置一个中断重连的程序的实现
  10. 基于Senparc的二次封装
  11. 图文介绍进程和线程的区别
  12. win7,win10系统激活工具下载
  13. 17-基于51单片机的银行排队叫号系统设计
  14. The Tangled Web: A Guide to Securing Modern Web Applications 原版pdf
  15. 质因数分解法、短除法、辗转相除法、更相减损法求最大公约数
  16. 报错:Exception opening socket
  17. ubuntu server 20.04 配置无线wifi网络并设置固定ip公司连接家里的linux服务器配置
  18. SAP Business One(SAP B1)国家增值税税率变更设置操作指引
  19. dorado 刷新_dorado5 datatree 刷新问题
  20. Smart210学习记录------块设备

热门文章

  1. (亲测有效)在SecureCRT终端挂载Ubuntu时遇到的问题
  2. win7无线局域网_存储卡具备WiFi有多方便?东芝 FlashAir 无线存储卡上手体验
  3. 用DirectX绘制使用纹理的立方体
  4. 这个“安装 OS X Yosemite”应用程序副本不能验证
  5. 在Centos 7 上 搭建 K8S --坑b)
  6. Windows 使用 FluentTerminal 搭配 Oh-My-Posh
  7. java获得U盘根目录、读取图片视频头文件信息、获取视频时长
  8. Java 设计模式 轻读汇总版
  9. 关于Linux下上网速度慢的问题
  10. Shell笔记(超级完整)