Mybatis(二)— 使用Mapper动态代理方式进行开发

本文介绍了MyBatis的两种开发方式:DAO开发方式和Mapper动态代理方式,并详细阐述了每种方式的具体实现过程,包括配置文件、接口定义、映射文件及测试类等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mybait有两种开发方式,一种是传统的dao开发方式,一种是Mapper动态代理方式。
这里简单地介绍下这两种方式。
需要用到的数据库表结构如下:
这里写图片描述

1.Dao开发方式

映射文件Student.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">

<!-- namespace:命名空间,做sql隔离 ,访问sql语句时,sql的id前面要带着命名空间-->
<mapper namespace="student">

    <!-- 
    id:sql语句唯一标识,不能重复。
    parameterType:属性指明查询时使用的参数类型
    resultType:属性指明查询返回的结果集类型。resultType="com.mq.pojo.Student"表示返回值是Student类型
    #{}占位符:起到占位作用,如果传入的是基本类型(string,long,double,int,boolean,float等),那么#{}中的变量名称可以随意写,一般和属性名相同。
    java.lang.Integer也可以直接写成int
     -->
    <select id="findStuById" parameterType="java.lang.Integer" resultType="com.mq.pojo.Student">
        select * from students where id=#{id}
    </select>

    <!-- 
    如果返回结果为集合,可以调用selectList方法,这个方法返回的结果就是一个集合,所以映射文件中应该配置成集合泛型的类型
    ${}拼接符:字符串原样拼接,如果传入的参数是基本类型(string,long,double,int,boolean,float等),那么${}中的变量名称必须是value
    注意:拼接符有sql注入的风险,所以慎重使用
     -->

    <select id="findStuByName" parameterType="java.lang.String" resultType="com.mq.pojo.Student">
        select * from students where name like '%${value}%'
    </select>

    <!-- 
    #{}:如果传入的是pojo类型,那么#{}中的变量名称必须是pojo中对应的属性,
    如果要返回数据库自增主键:可以使用select LAST_INSERT_ID()-->

    <insert id="insertStu" parameterType="com.mq.pojo.Student" >
        <!-- 执行 select LAST_INSERT_ID()数据库函数,返回自增的主键
        keyProperty:将返回的主键放入传入参数的Id中保存.
        order:当前函数相对于insert语句的执行顺序,在insert前执行是before,在insert后执行是AFTER
        resultType:id的类型,也就是keyproperties中属性的类型
        -->
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            select LAST_INSERT_ID()
        </selectKey>
        insert into students (name,sex,age,tel) values(#{name},#{sex},#{age},#{tel})
    </insert>

    <delete id="delStuById" parameterType="int">
        delete from students where id=#{id}
    </delete>

    <!--传入的是一个pojo类型,就是一个新的对象  -->
    <update id="updateStuById" parameterType="com.mq.pojo.Student">
        update students set name=#{name} where id=#{id}
    </update>

</mapper>

配置文件sqlconfig.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="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <!-- 配置数据库连接信息 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/study"/>
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>

     <mappers>
        <!-- 注册Student.xml文件,这两个文件在同一个目录下,都在src目录下-->
         <mapper resource="Student.xml"/>
     </mappers>

</configuration>

dao接口和实现类

public interface StudentDao {
    public Student findStuById(int id);
    public void findStuByName(String name);
    public void insertStu();
}
public class StudentDaoImpl implements StudentDao {

    private SqlSession session;
    public StudentDaoImpl(SqlSession session) {
        super();
        this.session = session;
    }

    @Override
    public Student findStuById(int id) {
        Student student = session.selectOne("student.findStuById", id);
        System.out.println(student);
        session.close();
        return student;
    }

    @Override
    public void findStuByName(String name) {
        List<Student> list = session.selectList("student.findStuByName", name);
        System.out.println(list);
        session.close();
    }

    @Override
    public void insertStu() {Student student=new Student();
    student.setAge(22);
    student.setSex("女");
    student.setTel("44544665");
    student.setName("小乔");

    session.insert("student.insertStu", student);
    //提交事务(mybatis会自动开启事务,但是它不知道何时提交,所以需要手动提交事务)
    session.commit();
    System.out.println("id值" + student.getId());
    }
}

测试类

public class StudentDaoTest {
private SqlSession session;

    //作用:在测试方法前执行这个方法
    @Before
    public void FirstDo() throws Exception{
        //加载配置文件
        String resource = "sqlconfig.xml";
        //通过流将核心配置文件读取进来
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //通过核心配置文件输入流来创建会话工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        session=factory.openSession();
    }
    //通过id查询数据库中的记录。并封装成对象
    @Test
    public void findStuById(){
        StudentDao student=new StudentDaoImpl(session);
        student.findStuById(2);
    }
    //模糊搜索
    @Test
    public void findStuByName(){
        StudentDao student=new StudentDaoImpl(session);
        student.findStuByName("飞");

    }
    //插入数据
    @Test
    public void insertStu(){
        StudentDao student=new StudentDaoImpl(session);
        student.insertStu();
    }
}

2.Mapper动态代理方式

Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。
使用Mapper动态代理方式,只需要编写接口,不用去实现这个接口,mybatis会帮我们动态生成代理对象
我们编写的接口必须要和映射文件存在一定的关联,mybatis才能根据接口中的方法找到对应的sql语句

Mapper接口开发需要遵循以下规范:

1、Mapper.xml文件中的namespace与mapper接口的类路径相同。
2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
4、Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

创建mapper接口

public interface StudentMapper {
    public Student findStuById(int id);
    public List<Student> findStuByName(String name);
    public void insertStu(Student student);

}

注意,接口的方法名,参数必须符合要求的规范

mapper映射文件StudentMapper.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接口代理实现编写规则:
    1. 映射文件中namespace要等于接口的全路径名称
    2. 映射文件中sql语句id要等于接口的方法名称
    3. 映射文件中传入参数类型要等于接口方法的传入参数类型
    4. 映射文件中返回结果集类型要等于接口方法的返回值类型
 -->
<mapper namespace="com.mq.mapper.StudentMapper">


    <select id="findStuById" parameterType="java.lang.Integer" resultType="com.mq.pojo.Student">
        select * from students where id=#{id}
    </select>

    <select id="findStuByName" parameterType="java.lang.String" resultType="com.mq.pojo.Student">
        select * from students where name like '%${value}%'
    </select>

    <!-- 
    #{}:如果传入的是pojo类型,那么#{}中的变量名称必须是pojo中对应的属性,
    如果要返回数据库自增主键:可以使用select LAST_INSERT_ID()-->

    <insert id="insertStu" parameterType="com.mq.pojo.Student" >

        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            select LAST_INSERT_ID()
        </selectKey>
        insert into students (name,sex,age,tel) values(#{name},#{sex},#{age},#{tel})
    </insert>

    <delete id="delStuById" parameterType="int">
        delete from students where id=#{id}
    </delete>

    <!--传入的是一个pojo类型,就是一个新的对象  -->
    <update id="updateStuById" parameterType="com.mq.pojo.Student">
        update students set name=#{name} where id=#{id}
    </update>

</mapper>

在sqlconfig.xml注册mapper映射文件

<?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="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <!-- 配置数据库连接信息 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/study"/>
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>

     <mappers>
        <!-- 注册Student.xml文件,这两个文件在同一个目录下,都在src目录下-->
         <mapper resource="Student.xml"/>
         <!--StudentMapper.xml在com/mq/mapper的包下  -->
         <mapper resource="com/mq/mapper/StudentMapper.xml"/>
     </mappers>

</configuration>

测试类

public class StudentMapperTest {
    private SqlSession session;
    //作用:在测试方法前执行这个方法
    @Before
    public void FirstDo() throws Exception{
        //加载配置文件
        String resource = "sqlconfig.xml";
        //通过流将核心配置文件读取进来
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //通过核心配置文件输入流来创建会话工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        session=factory.openSession();
    }


    @Test
    public void testFindStuById(){//获取mapper接口的代理对象
        StudentMapper stuMapper = session.getMapper(StudentMapper.class);
        //调用代理对象方法
        Student student = stuMapper.findStuById(3);
        System.out.println(student);
        //关闭session
        session.close();
    }

    @Test
    public void testFindStuByName(){
        StudentMapper stuMapper = session.getMapper(StudentMapper.class);
        List<Student> list = stuMapper.findStuByName("john");
        System.out.println(list);
        session.close();
    }

    //插入数据
    @Test
    public void insertStu(){
        StudentMapper stuMapper = session.getMapper(StudentMapper.class);
        Student student=new Student();
        student.setAge(34);
        student.setName("曹操");
        student.setSex("男");
        student.setTel("4854684866");
        stuMapper.insertStu(student);
        session.commit();
        session.close();
    }

}

我们只定义了接口,不用定义实现类。将接口中的方法和映射文件通过一定的规则对应起来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值