MyBatis学习(三)

本文详细介绍了MyBatis的动态代理机制,如何根据DAO接口创建对象并执行SQL。接着讲解了如何传参,包括parameterType的使用、简单类型参数、按位置传参、@Param注解、使用Java对象属性值以及使用Map传参。还通过实例展示了多种传参方式的应用,并探讨了#和$的区别。最后,讨论了MyBatis结果的封装,resultType与resultMap的使用场景,以及在列名与属性名不同时的处理策略和模糊查询的实现方法。
摘要由CSDN通过智能技术生成

MyBatis的动态代理

MyBatis根据dao的方法调用,获取执行sql语句的信息

MyBatis根据你的dao接口,创建一个dao接口的实现类,并创建这个类的对象

完成SqlSession调用方法,访问数据库

即自己不用再编写实现类了

动态代理的实现

使用SqlSession.getMapper(dao接口.java)获取这个dao接口的对象

对于MyBatis学习(二)最后的项目 进行复制 并改造

复制后导入idea

添加文件路劲进行导入

将文件导入后,修改pom.xml中文件名,修改为和复制后的新项目名(proxyDao)相同

删除接口的实现类文件,删除text中的测试文件,删除target文件,对myapp进行修改

修改myapp后如下

package ys;

import org.apache.ibatis.session.SqlSession;
import ys.dao.StudentDao;
import ys.domain.Student;
import ys.utils.mybatisclass;

import java.util.List;

public class myapp {
    public static void main(String[] args) {
//        使用MyBatis动态代理机制,使用SqlSession.getMapper(接口)
//        getMapper能获取dao接口对于的实现类对象
        SqlSession sqlSession = mybatisclass.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        Student student=new Student();
//        选择添加数据
        student.setName("刘备");
        student.setEmail("48979.189");
        student.setId(8);
        student.setAge(45);
//        调用dao方法执行添加数据操作
        int nums= dao.insertStudent(student);
//        调用dao 的方法执行查询数据库的操作
        List<Student> students =dao.selectStudents();
        for (Student stu: students){
            System.out.println("学生="+stu);
        }
    }
}

传参(从java文件将参数传到sql映射文件(mapper文件))

使得sql语句更加灵活,功能更加丰富

1.parameterType:

写在mapper文件中的一个属性,表示dao接口中方法的参数的数据类型。

例如StudentDao接口

public Student selectStudentById(Integer id)

 2. 一个简单类型的参数及传参:

简单类型:mybatis把java的基本数据类型和String类型都叫简单类型

 在mapper文件获取简单类型的一个参数的值,使用#{任意字符}

基本原理机制(了解)

使用#{ }之后,mybatis执行sql是使用的jdbc中的PreparedStatement对象(自动创建执行)

由mybatis执行下列代码:

//1.mybatis创建Connection ,PreparedStatement对象

String  sql="select name,id,age,email from Student where id=?";

PreparedStatement  pst = conn.PreparedStatement(sql);

pst.setInt(1,1001);

//2.执行sql封装resultType="ys.domian.Student"  这个对象

ResultSet rs =ps.executeQuery();

Student student =null;

while(rs.next()){

//从数据库取表的一行数据,存到一个java对象属性中

student =new Student();

student.setId(rs.getInt("id");

student.setName(rs.getString("name");

student.setEmail(rs.getString("email");

student.setAge(rs.getInt("age");

}
return student;//把student这个返回值给了dao方法调用的返回值

多个参数传参--按位置传参 (了解)

参数位置从0开始,引用参数语法#{arg位置},第一个参数是#{arg0},第二个是#{arg1}

需要注意的是mybatis-3.3版本及以前的版本用#{0},#{1}的方式,从mybatis开始使用#{arg0}的方式

多个参数传参--使用@Param(掌握)

当Dao接口方法有多个参数时,需要通过名称使用参数,在方法形参前面加入@Param("自定义参数名"),mapper文件使用#{自定义参数名}

多个参数传参--使用java对象属性值作为参数实际值(掌握)

创建一个java实体类,并在接口中定义方法用java类作为类型,进行传值

多个参数传参--使用Map(了解)

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

实例----各种方法传参的实际应用

将proxyDao项目进行复制,命名为param,修改pom.xml文件中的名字,改为与项目名相同

在接口中定义新的方法(StudentDao.java)

package ys.dao;

import org.apache.ibatis.annotations.Param;
import ys.domain.QueryParam;
import ys.domain.Student;

import java.util.List;
import java.util.Map;

public interface StudentDao {
    /**
     * 一个简单类型的参数:
     * 简单类型:mybatis把java的基本数据类型和String类型都叫简单类型
     *
     * 在mapper文件获取简单类型的一个参数的值,使用#{任意字符}
     * */
//    一个简单类型参数传参
    public Student selectStudentById(Integer id);
//    多个参数按位置传参
    List<Student> selectByNameAndAge(String name,int age);
//    使用@Param多参数传参
    List<Student> selectMultiParam(@Param("personName")String name,
                                   @Param("personAge")int age);
//使用java对象的属性值,作为参数实际值
    List<Student> selectMultiObject(QueryParam param);
//    使用Map多参数传值
    List<Student> selectMap(Map<String,Object> map);
//    使用$占位符
List<Student> select$(@Param("personSName")String name);
//使用$占位符 替换类名
List<Student> select$order(@Param("VSName")String name);
}

sql映射文件(StudentDao.xml)

<?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">
<mapper namespace="ys.dao.StudentDao">
<!--  parameterType 用来表dao接口中方法参数的数据类型
  parameterType它的值是java数据类型的全限定名称或者mybatis定义的别名(mybatis文档中它的定义的)
  例如 parameterType="java.lang.Integer
       parameterType="int"
       不是强制必须写入parameterType,可以不用写
       mybatis可以通过反射机制能够发现接口参数的数类型 所以大多数时候我们都不写-->
    <select id="selectStudentById" parameterType="java.lang.Integer" resultType="ys.domain.Student">
        select name,id,age,email from Student where id=#{id}
    </select>
    <select id="selectByNameAndAge" resultType="ys.domain.Student">
        select name,id,age,email from Student where name=#{arg0} and age=#{arg1}
    </select>
    <select id="selectMultiParam" resultType="ys.domain.Student">
        select name,id,age,email from Student where name=#{personName} or age=#{personAge}
    </select>
<!--    使用java对象的属性值,作为参数实际值
使用对象语法:#{属性名,javaType=类型名称,jdbcType=数据类型   -完整格式(但一般不怎么写)
  javaType:指java中的属性数据类型
  jdbcType:在数据库中的数类型
  例如:#{SName,javaType=java.lang.String,jdbcType=VARCHAR}

  常用语法:#{属性名}     javaType,jdbcType的值通过mybatis反射能获取,不用提供
  -->
    <select id="selectMultiObject" resultType="ys.domain.Student">
        select name,id,age,email from Student where name=#{SName} or age=#{SAge}
    </select>
<!--    Map 多参数传参-->
    <select id="selectMap" resultType="ys.domain.Student">
        select name,id,age,email from Student where name=#{myName} or age=#{myAge}
    </select>
<!--    使用$占位符-->
    <select id="select$" resultType="ys.domain.Student">
        select name,id,age,email from Student where name=${personSName}
    </select>
<!--    使用$替换列表名-->
    <select id="select$order" resultType="ys.domain.Student">
        select * from Student order by  ${VSName}
    </select>
</mapper>

 主方法( myapp.java)

package ys;

import org.apache.ibatis.session.SqlSession;
import ys.dao.StudentDao;
import ys.domain.QueryParam;
import ys.domain.Student;
import ys.utils.mybatisclass;

import java.util.*;

public class myapp {
    public static void main(String[] args) {
//        从键盘获取一个值
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入你要查询的学生id:");
//        从键盘获取值,取出int类型的值赋值给number(意味着只有int类型的值能被获取)
        int number = scanner.nextInt();
//        使用MyBatis动态代理机制,使用SqlSession.getMapper(接口)
//        getMapper能获取dao接口对于的实现类对象
        SqlSession sqlSession = mybatisclass.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
//        调用dao 的方法执行查询数据库的操作 单参数传递
        Student students =dao.selectStudentById(number);
        System.out.println("学生="+students);
//        调用dao的方法执行查询操作 多参数传值--按位置传参
        List<Student> students1=dao.selectByNameAndAge("刘备",45);
        students1.forEach(student -> System.out.println(student));
//        调用dao的方法进行查询  多参数传值--@Param
        List<Student> students2=dao.selectMultiParam("张三",45);
        students2.forEach(stu -> System.out.println(stu));
//        设置java属性值
        QueryParam queryParam=new QueryParam();
        queryParam.setSAge(45);
        queryParam.setSName("隆");
//  调用dao方法进行查询,java对象属性值作为参数实际值 (多参数传值一种)
        List<Student> students3=dao.selectMultiObject(queryParam);
        students3.forEach(student -> System.out.println(student) );
//        使用Map集合进行多参数传参
        Map<String,Object> data=new HashMap<>();
//        往Map集合写值
        data.put("myName","隆");
        data.put("myAge",20);
        List<Student> students4=dao.selectMap(data);
        students4.forEach(student -> System.out.println(student));
//        使用$占位符
        List<Student> students5=dao.select$("'张三'");
        students5.forEach(student -> System.out.println(student));
//        使用$进行列表名的替换
        List<Student> students6 =dao.select$order("'id'");
        students6.forEach(student -> System.out.println(student));
    }
}

#和$(掌握)

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

select id,name,email,age from Studnet where name=#{name}


// 结果是 select id,name,email,age from Studnet where name=?
// 然后用#{} 的值代替?

$:字符串替换,告诉mybatis使用$包含的“字符串”替换所在位置,使用Statement把sql语句和${}

的内容连接起来,主要用在替换列表名,列名,不同排序等操作,效率比#{}低,容易出现问题。

select id,name,email,age from Studnet where name=${name}


//select id,name,email,age from Studnet where name=""+"刘备"

//${}直接连接在语句上

封装MyBatis输出结果

resultType(返回类型和接口方法的类型的全限定名称是相同的)

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

<select id="selectStudentById" resultType="ys.domain.Student">
        select name,id,age,email from Student 
    </select>

resultType是返回的类型,不一定是实体类,可以是任意java类 。原理是指将查询的表的值赋给resultType值中的类中的同名属性

resultType可以返回简单类型 

//查询语句
<select id="selectCount" resultType="int">   // 也可以写作resultType="java.long.Integer"(全限定名称)
        select count(*) from Student 
    </select>


//接口方法
int selectCount();

定义别名

在resources文件下的主配置文件中定义

<typeAliases>

  //可以指定一个类型一个自定义别名.
  //type:自定义类型的全限定名称
 //alias:自定义的别名(短小,容易记忆)

 <typeAlias type="ys.domain.Student"  alias="Stu"/>

</typeAliases>

//sql映射文件的写法

  <select id="selectByNameAndAge" resultType="Stu">

        select name,id,age,email from Student 

    </select>
<package name="ys.domain">

<package name="ys.dao">

//name 是包名,这个包中的所有类,类名就是别名(类名不区分大小写)



//在sql映射文件中的写法
  <select id="selectByNameAndAge" resultType="Student"> //类名即别名

        select name,id,age,email from Student 

    </select>

 查询返回Map

返回map  列名作为key值,列值是value 一一对应
使用map作为返回值 最多返回一行 多行数据会报错

 //使用Map作为返回值 -----接口方法

    Map<Object,Object> selectObject(Integer id);


//map的全限定名称java.util.HashMap----sql映射文件

    <select id="selectObject" resultType="java.util.HashMap">

        select id,name from Student where id=#{stu}

    </select>

//查询返回map---主方法    mybatisclass.getSqlSession()---工具类封装的方法

SqlSession sqlSession = mybatisclass.getSqlSession();
       
StudentDao dao = sqlSession.getMapper(StudentDao.class);

Map<Object,Object> map =dao.selectObject(1);
     
System.out.println(map);

resultMap(结果映射)

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

什么时候使用:

1.你自定义列值赋值给哪个属性

2.当你的列名和属性名不一样时,一定要使用resultMap

使用方式:

1.先定义resultMap,指定列名和属性的对应关系

2.在<select>中吧resultType换成resultMap

//    resultMap的用法---接口方法

   List<Student> selectResultMap();

//sql映射文件写入的内容

<!--    使用resultMap定义映射关系-->

<!--    创建resultMap id:自定义的唯一名称 在<select>中使用 type:期望转为java对象的全限定名称或别名-->

    <!--        主键字段使用id   非主键字段使用result-->

    <!--        column:列名  property:java属性名-->

    <resultMap id="studentMap" type="ys.domain.Student">

        <id column="id" property="id"/>

        <result column="name" property="name"/>

        <result column="email" property="email"/>

        <result column="age" property="age"/>

    </resultMap>

<!--  id同样是接口方法名,resultType被resultMap替换,值为之前定义的id值  -->

    <select id="selectResultMap" resultMap="studentMap">

        select id,name,email,age from Student

    </select>

//主方法

 List<Student> students7=dao.selectResultMap();

 students7.forEach(student -> System.out.println(student));

对于列名与java对象属性名不同时

采用resultMap进行sql语句

//    resultMap的用法---接口方法

   List<StudentMap> selectResultStudent();

//sql映射文件写入的内容

    <resultMap id="studentResultMap" type="ys.domain.StudentMap">

        <id column="id" property="stuid"/>

        <result column="name" property="stuname"/>

        <result column="email" property="stuemail"/>

        <result column="age" property="stuage"/>

    </resultMap>


    <select id="selectResultStudent" resultMap="studentResultMap">

        select id,name,email,age from Student

    </select>

//主方法

 List<Student> students8=dao.selectResultStudent();

 students8.forEach(student -> System.out.println(student));

  对列表进行命名别名

<select id="ResultStudent" resultType="ys.domain.StudentMap">

    select id as stuid,name as stuname ,email as stuemail ,age as stuage from StudentMap

</select>

 模糊查询like

1. 方法一

在java代码指定like的内容

//    模糊查询like的用法

    List<Student> selectLike(String name);



//sql映射文件----#{}  简单参数传参

  <select id="selectLike" resultType="ys.domain.Student">

        select * from Student where name like #{name}

    </select>


//      Like 模糊查询 用法 -----主方法

        String name="%张%";

        List<Student> students8=dao.selectLike(name);

// List<Student> students8=dao.selectLike("%张%"); 作用与前面两句相同

        students8.forEach(student -> System.out.println(student));

2.方法二    

在sql映射文件中拼接like内容

//    模糊查询like的用法

    List<Student> selectLike2(String name);



//sql映射文件----#{}  简单参数传参

  <select id="selectLike2" resultType="ys.domain.Student">

        select * from Student where name like "%" #{name} "%"

    </select>


//      Like 模糊查询 用法 -----主方法

        String name="张";

        List<Student> students9=dao.selectLike2(name);

        students9.forEach(student -> System.out.println(student));

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值