百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

MyBatis框架系列三之——MyBatis 框架 Dao 代理

toyiye 2024-08-25 15:40 4 浏览 0 评论

一、Dao 代理实现 CURD

2)getMapper 获取代理对象

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

SqlSession session = factory.openSession();
StudentDao dao = session.getMapper(StudentDao.class);
复制代码

使用工具类:

StudentDao studentDao =
    MyBatisUtil.getSqlSession().getMapper(StudentDao.class);
复制代码

3)使用 Dao 代理对象方法执行 sql 语句

select 方法:

@Test
public void testSelect() throws IOException {
    final List<Student> studentList = studentDao.selectStudents();
    studentList.forEach( stu -> System.out.println(stu));
}
复制代码

insert 方法:

@Test
public void testInsert() throws IOException {
    Student student = new Student();
    student.setId(1006);
    student.setName("林浩");
    student.setEmail("linhao@163.com");
    student.setAge(26);
    int nums = studentDao.insertStudent(student);
    System.out.println("使用 Dao 添加数据:"+nums);
}
复制代码

update 方法

@Test
public void testUpdate() throws IOException {
    Student student = new Student();
    student.setId(1006);
    student.setAge(28);
    int nums = studentDao.updateStudent(student);
    System.out.println("使用 Dao 修改数据:"+nums);
}
复制代码

delete 方法

@Test
public void testDelete() throws IOException {
    int nums = studentDao.deleteStudent(1006);
    System.out.println("使用 Dao 修改数据:"+nums);
}
复制代码

2、原理

动态代理

MapperProxy 类定义:

?

invoke()方法:

?

重点方法:

二、深入了解参数

1、parameterType

parameterType: 接口中方法参数的类型, 类型的完全限定名或别名。这个属性是可选的,因为 MyBatis可以推断出具体传入语句的参数,默认值为未设置(unset)。接口中方法的参数从 java 代码传入到mapper 文件的 sql 语句。

int 或 java.lang.Integer
hashmap 或 java.util.HashMap
list 或 java.util.ArrayList
student 或 com.bjpowernode.domain.Student

select,insert,update,delete 都可以使用 parameterType 指定类型。

例如:

<delete id="deleteStudent" parameterType="int">
    delete from student where id=#{studentId}
</delete>
复制代码

等同于

<delete id="deleteStudent" parameterType="java.lang.Integer">
    delete from student where id=#{studentId}
</delete>
复制代码

2、Mybatis 传递参数

从 java 代码中把参数传递到 mapper.xml 文件。

3、一个简单参数

Dao 接口中方法的参数只有一个简单类型(java 基本类型和 String),占位符 #{ 任意字符 },和方法的参数名无关。

接口方法:

Student selectById(int id);
复制代码

mapper 文件:

<select id="selectById" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where id=#{studentId}
</select>
复制代码

#{studentId} , studentId 是自定义的变量名称,和方法参数名无关。

测试方法:

@Test
public void testSelectById(){
    //一个参数
    Student student = studentDao.selectById(1005);
    System.out.println("查询 id 是 1005 的学生:"+student);
}
复制代码

4、多个参数-使用@Param

当 Dao 接口方法多个参数,需要通过名称使用参数。 在方法形参前面加入@Param(“自定义参数名”),mapper 文件使用#{自定义参数名}。
例如定义 List selectStudent( @Param(“personName”) String name ) { … }
mapper 文件 select * from student where name = #{ personName}

接口方法:

List<Student> selectMultiParam(@Param("personName") String name,
                                @Param("personAge") int age);
复制代码

mapper 文件:

<select id="selectMultiParam" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name=#{personName} or age=#{personAge}
</select>
复制代码

测试方法:

@Test
public void testSelectMultiParam(){
    List<Student> stuList = studentDao.selectMultiParam("李力",20);
    stuList.forEach( stu -> System.out.println(stu));
}
复制代码

5、多个参数-使用对象

使用 java 对象传递参数, java 的属性值就是 sql 需要的参数值。 每一个属性就是一个参数。
语法格式: #{ property,javaType=java 中数据类型名,jdbcType=数据类型名称 }
javaType, jdbcType 的类型 MyBatis 可以检测出来,一般不需要设置。常用格式 #{ property }

创建保存参数值的对象 QueryParam

package com.bjpowernode.vo;
public class QueryParam {
    private String queryName;
    private int queryAge;
    //set ,get 方法
}
复制代码

接口方法:

List<Student> selectMultiObject(QueryParam queryParam);
复制代码

mapper 文件:

<select id="selectMultiObject" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name=#{queryName} or age=#{queryAge}
</select>
复制代码

<select id="selectMultiObject" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student
    where name=#{queryName,javaType=string,jdbcType=VARCHAR}
    or age =#{queryAge,javaType=int,jdbcType=INTEGER}
</select>
复制代码

测试方法:

@Test
public void selectMultiObject(){
    QueryParam qp = new QueryParam();
    qp.setQueryName("李力");
    qp.setQueryAge(20);
    List<Student> stuList = studentDao.selectMultiObject(qp);
    stuList.forEach( stu -> System.out.println(stu));
}
复制代码

6、多个参数-按位置

参数位置从 0 开始, 引用参数语法 #{ arg 位置 } , 第一个参数是#{arg0}, 第二个是#{arg1}
注意:mybatis-3.3 版本和之前的版本使用#{0},#{1}方式, 从 mybatis3.4 开始使用#{arg0}方式。

接口方法:

List<Student> selectByNameAndAge(String name,int age);
复制代码

mapper 文件

<select id="selectByNameAndAge" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name=#{arg0} or age =#{arg1}
</select>
复制代码

测试方法:

@Test
public void testSelectByNameAndAge(){
    //按位置参数
    List<Student> stuList = studentDao.selectByNameAndAge("李力",20);
    stuList.forEach( stu -> System.out.println(stu));
}
复制代码

7、多个参数-使用 Map

Map 集合可以存储多个值,使用 Map 向 mapper 文件一次传入多个参数。Map 集合使用 String 的 key,Object 类型的值存储参数。 mapper 文件使用 # { key } 引用参数值。
例如:

Map<String,Object> data = new HashMap<String,Object>();
          data.put(“myname”,”李力”);
          data.put(“myage”,20);
复制代码

接口方法:

List<Student> selectMultiMap(Map<String,Object> map);
复制代码

mapper 文件:

<select id="selectMultiMap" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name=#{myname} or age =#{myage}
</select>
复制代码

测试方法:

@Test
public void testSelectMultiMap(){
    Map<String,Object> data = new HashMap<>();
    data.put("myname","李力");// #{myname}
    data.put("myage",20); // #{myage}
    List<Student> stuList = studentDao.selectMultiMap(data);
    stuList.forEach( stu -> System.out.println(stu));
}
复制代码

8、#和$

#:占位符,告诉 mybatis 使用实际的参数值代替。并使用 PrepareStatement 对象执行 sql 语句, #{…}代替sql 语句的“?”。这样做更安全,更迅速,通常也是首选做法,

mapper 文件

<select id="selectById" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where id=#{studentId}
</select>
复制代码

转为 MyBatis 的执行是:

String sql=” select id,name,email,age from student where id=?”;
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1,1005);
复制代码

解释:

  • where id=? 就是 where id=#{studentId} ps.setInt(1,1005) , 1005 会替换掉 #{studentId}
  • 字符串替换,告诉mybatis使用 字符串替换,告诉 mybatis 使用字符串替换,告诉mybatis使用包含的“字符串”替换所在位置。使用 Statement 把 sql 语句和${}的内容连接起来。主要用在替换表名,列名,不同列排序等操作。

例 1: 分别使用 id , email 列查询 Student
接口方法:

Student findById(int id);
Student findByEmail(String email);
复制代码

mapper 文件:

<select id="findById" resultType="com.bjpowernode.domain.Student">
    select * from student where id=#{studentId}
</select>
<select id="findByEmail" resultType="com.bjpowernode.domain.Student">
    select * from student where email=#{stuentEmail}
</select>
复制代码

测试方法:

@Test
public void testFindStuent(){
    Student student1 = studentDao.findById(1002);
    System.out.println("findById:"+student1);
    Student student2 = studentDao.findByEmail("zhou@126.net");
    System.out.println("findByEmail:"+student2);
}
复制代码

例 2:通用方法,使用不同列作为查询条件

接口方法:

Student findByDiffField(@Param("col") String colunName,@Param("cval") Object value);
复制代码

mapper 文件:

<select id="findByDiffField" resultType="com.bjpowernode.domain.Student">
    select * from student where ${col} = #{cval}
</select>
复制代码

测试方法:

@Test
public void testFindDiffField(){
    Student student1 = studentDao.findByDiffField("id",1002);
    System.out.println("按 id 列查询:"+student1);
    Student student2 = studentDao.findByDiffField("email","zhou@126.net");
    System.out.println("按 email 列查询:"+student2);
}
复制代码

三、封装 MyBatis 输出结果

1、resultType

resultType: 执行 sql 得到 ResultSet 转换的类型,使用类型的完全限定名或别名。 注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。resultType 和 resultMap,不能同时使用。

3)简单类型

接口方法:

int countStudent();
复制代码

mapper 文件:

<select id="countStudent" resultType="int">
    select count(*) from student
</select>
复制代码

测试方法:

@Test
public void testRetunInt(){
    int count = studentDao.countStudent();
    System.out.println("学生总人数:"+ count);
}
复制代码

2) 对象类型

接口方法:

Student selectById(int id);
复制代码

mapper 文件:

<select id="selectById" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where id=#{studentId}
</select>
复制代码

框架的处理: 使用构造方法创建对象。调用 setXXX 给属性赋值。 Student student = new Student();

注意:Dao 接口方法返回是集合类型,需要指定集合中的类型,不是集合本身。

3)Map

sql 的查询结果作为 Map 的 key 和 value。推荐使用 Map<Object,Object>。 注意:Map 作为接口返回值,sql 语句的查询结果最多只能有一条记录。大于一条记录是错误。

接口方法:

Map<Object,Object> selectReturnMap(int id);
复制代码

mapper 文件:

<select id="selectReturnMap" resultType="java.util.HashMap">
    select name,email from student where id = #{studentId}
</select>
复制代码

测试方法:

@Test
public void testReturnMap(){
    Map<Object,Object> retMap = studentDao.selectReturnMap(1002);
    System.out.println("查询结果是 Map:"+retMap);
}
复制代码

2、resultMap

resultMap 可以自定义 sql 的结果和 java 对象属性的映射关系。更灵活的把列值赋值给指定属性。常用在列名和 java 对象属性名不一样的情况。
使用方式:

1.先定义 resultMap,指定列名和属性的对应关系。 2.在select中把 resultType 替换为 resultMap。

接口方法:

List<Student> selectUseResultMap(QueryParam param);
复制代码

mapper 文件:

<!-- 创建 resultMap
    id:自定义的唯一名称,在<select>使用
    type:期望转为的 java 对象的全限定名称或别名
-->
<resultMap id="studentMap" type="com.bjpowernode.domain.Student">
    <!-- 主键字段使用 id -->
    <id column="id" property="id" />
    <!--非主键字段使用 result-->
    <result column="name" property="name"/>
    <result column="email" property="email" />
    <result column="age" property="age" />
</resultMap>

<!--resultMap: resultMap 标签中的 id 属性值-->
<select id="selectUseResultMap" resultMap="studentMap">
    select id,name,email,age from student where name=#{queryName} orage=#{queryAge}
</select>
复制代码

测试方法:

@Test
public void testSelectUseResultMap(){
    QueryParam param = new QueryParam();
    param.setQueryName("李力");
    param.setQueryAge(20);
    List<Student> stuList = studentDao.selectUseResultMap(param);
    stuList.forEach( stu -> System.out.println(stu));
}
复制代码

3、实体类属性名和列名不同的处理方式

1)使用列别名和

步骤:

  1. 创建新的实体类 PrimaryStudent
package com.bjpowernode.domain;
/**
* <p>Description: 实体类 </p>
* <p>Company: http://www.bjpowernode.com
*/
public class PrimaryStudent {
    private Integer stuId;
    private String stuName;
    private Integer stuAge;
    // set , get 方法
}
复制代码
  1. 接口方法
List<PrimaryStudent> selectUseFieldAlias(QueryParam param);
复制代码
  1. mapper 文件:
<select id="selectUseFieldAlias" resultType="com.bjpowernode.domain.PrimaryStudent">
    select id as stuId, name as stuName,age as stuAge
    from student where name=#{queryName} or age=#{queryAge}
</select>
复制代码

4.测试方法

@Test
public void testSelectUseFieldAlias(){
    QueryParam param = new QueryParam();
    param.setQueryName("李力");
    param.setQueryAge(20);
    List<PrimaryStudent> stuList;
    stuList = studentDao.selectUseFieldAlias(param);
    stuList.forEach( stu -> System.out.println(stu));
}
复制代码

2)使用

步骤:

  1. 接口方法
List<PrimaryStudent> selectUseDiffResultMap(QueryParam param);
复制代码
  1. mapper 文件:
<!-- 创建 resultMap
    id:自定义的唯一名称,在<select>使用
    type:期望转为的 java 对象的全限定名称或别名
-->
<resultMap id="primaryStudentMap"
    type="com.bjpowernode.domain.PrimaryStudent">
    <!-- 主键字段使用 id -->
    <id column="id" property="stuId" />
    <!--非主键字段使用 result-->
    <result column="name" property="stuName"/>
    <result column="age" property="stuAge" />
</resultMap>

<!--resultMap: resultMap 标签中的 id 属性值-->
<select id="selectUseDiffResultMap" resultMap="primaryStudentMap">
    select id,name,email,age from student
    where name=#{queryName} or age=#{queryAge}
</select>
复制代码
  1. 测试方法
@Test
public void testSelectUseDiffResultMap(){
    QueryParam param = new QueryParam();
    param.setQueryName("李力");
    param.setQueryAge(20);
    List<PrimaryStudent> stuList;
    stuList = studentDao.selectUseDiffResultMap(param);
    stuList.forEach( stu -> System.out.println(stu));
}
复制代码

四、模糊 like

模糊查询的实现有两种方式, 一是 java 代码中给查询数据加上“%” ; 二是在 mapper 文件 sql 语句的条件位置加上“%”

需求:查询姓名有“力”的
例 1: java 代码中提供要查询的 “%力%”
接口方法:

List<Student> selectLikeFirst(String name);
复制代码

mapper 文件:

<select id="selectLikeFirst" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student
    where name like #{studentName}
</select>
复制代码

测试方法:

@Test
public void testSelectLikeOne(){
    String name="%力%";
    List<Student> stuList = studentDao.selectLikeFirst(name);
    stuList.forEach( stu -> System.out.println(stu));
}
复制代码

例 2:mapper 文件中使用 like name "%" #{xxx} "%"

接口方法:

List<Student> selectLikeSecond(String name);
复制代码

mapper 文件:

<select id="selectLikeSecond" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student
    where name like "%" #{studentName} "%"
</select>
复制代码

测试方法:

@Test
public void testSelectLikeSecond(){
    String name="力";
    List<Student> stuList = studentDao.selectLikeSecond(name);
    stuList.forEach( stu -> System.out.println(stu));
}

相关推荐

# Python 3 # Python 3字典Dictionary(1)

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中,格式如...

Python第八课:数据类型中的字典及其函数与方法

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值...

Python中字典详解(python 中字典)

字典是Python中使用键进行索引的重要数据结构。它们是无序的项序列(键值对),这意味着顺序不被保留。键是不可变的。与列表一样,字典的值可以保存异构数据,即整数、浮点、字符串、NaN、布尔值、列表、数...

Python3.9又更新了:dict内置新功能,正式版十月见面

机器之心报道参与:一鸣、JaminPython3.8的热乎劲还没过去,Python就又双叒叕要更新了。近日,3.9版本的第四个alpha版已经开源。从文档中,我们可以看到官方透露的对dic...

Python3 基本数据类型详解(python三种基本数据类型)

文章来源:加米谷大数据Python中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。在Python中,变量就是变量,它没有类型,我们所说的"类型"是变...

一文掌握Python的字典(python字典用法大全)

字典是Python中最强大、最灵活的内置数据结构之一。它们允许存储键值对,从而实现高效的数据检索、操作和组织。本文深入探讨了字典,涵盖了它们的创建、操作和高级用法,以帮助中级Python开发...

超级完整|Python字典详解(python字典的方法或操作)

一、字典概述01字典的格式Python字典是一种可变容器模型,且可存储任意类型对象,如字符串、数字、元组等其他容器模型。字典的每个键值key=>value对用冒号:分割,每个对之间用逗号,...

Python3.9版本新特性:字典合并操作的详细解读

处于测试阶段的Python3.9版本中有一个新特性:我们在使用Python字典时,将能够编写出更可读、更紧凑的代码啦!Python版本你现在使用哪种版本的Python?3.7分?3.5分?还是2.7...

python 自学,字典3(一些例子)(python字典有哪些基本操作)

例子11;如何批量复制字典里的内容2;如何批量修改字典的内容3;如何批量修改字典里某些指定的内容...

Python3.9中的字典合并和更新,几乎影响了所有Python程序员

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

Python3大字典:《Python3自学速查手册.pdf》限时下载中

最近有人会想了,2022了,想学Python晚不晚,学习python有前途吗?IT行业行业薪资高,发展前景好,是很多求职群里严重的香饽饽,而要进入这个高薪行业,也不是那么轻而易举的,拿信工专业的大学生...

python学习——字典(python字典基本操作)

字典Python的字典数据类型是基于hash散列算法实现的,采用键值对(key:value)的形式,根据key的值计算value的地址,具有非常快的查取和插入速度。但它是无序的,包含的元素个数不限,值...

324页清华教授撰写【Python 3 菜鸟查询手册】火了,小白入门字典

如何入门学习python...

Python3.9中的字典合并和更新,了解一下

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

python3基础之字典(python中字典的基本操作)

字典和列表一样,也是python内置的一种数据结构。字典的结构如下图:列表用中括号[]把元素包起来,而字典是用大括号{}把元素包起来,只不过字典的每一个元素都包含键和值两部分。键和值是一一对应的...

取消回复欢迎 发表评论:

请填写验证码