zoukankan      html  css  js  c++  java
  • Mybatis笔记二:接口式编程

    旧方法的弊端

    在Mybatis笔记一中,我们使用命名空间+id的方式实现了Mybatis的执行,不过这里的命名空间是我们随便写的,id也是随意写的,这种方式其实是有弊端的,例如我们在执行的时候用的这个

      list =sqlSession.selectList("Message.selectOneMessage",1);
    

    这里有一个不好的地方,第二个参数是Object类型的,我们输入1,但是没办法保证类型安全,没办法保证其他人调用的时候也输入Integer类型,所以这次,我要换一个类型安全的方式,接口式编程

    接口式编程

    使用接口,首先我们要新建一个接口,我起名为MessageMapper

    package com.vae.springboot.study.mapper;
    import com.vae.springboot.study.bean.Message;
    
    public interface MessageMapper {
        public Message getMsgById(Integer id);
    }
    

    有了接口之后,我们的Message.xml类的配置文件需要和接口进行绑定一下

    首先,namespace从自定义的 Message换成了接口的地址

    其次,每个语句Id换成了接口的名称,而不是随意写的了,更换之后的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 -->
    <mapper namespace="com.vae.springboot.study.mapper.MessageMapper">
        <!--
            数据库查询数据
            insert、select、delete、update:sql语句类型
            id:sql语句唯一标识
            resultType:结果返回值类型-包名+类名 或 基本数据类型
            parameterType:匹配字段值-包名+类名 或 基本数据类型
        -->
        <select id="getMsgById" parameterType="com.vae.springboot.study.bean.Message"  resultType="com.vae.springboot.study.bean.Message">
            select * from message where ID=#{ID}
        </select>
    
    </mapper>
    

    可以对比笔记一发现,我们更改,只改了两个地方

    <mapper namespace="com.vae.springboot.study.mapper.MessageMapper">
     <select id="getMsgById" parameterType="com.vae.springboot.study.bean.Message"  resultType="com.vae.springboot.study.bean.Message">
            select * from message where ID=#{ID}
     </select>  
    

    namespace和id

    最后,我们来调用一下,SqlSessionFactory使用的频率太高了,所以上一篇我已经介绍了,封装成DBAcess类了

      @Test
        public void getOneNew() throws IOException {
            DBAcess dbAcess=new DBAcess();
            SqlSession sqlSession = dbAcess.getSqlSession();
            try {
                MessageMapper mapper =sqlSession.getMapper (MessageMapper.class);
                Message message=mapper.getMsgById(1);
                System.out.println(mapper);
                System.out.println(message.getId()+message.getCommand()+message.getDescription());
            }finally {
                sqlSession.close();
            }
    

    执行一下,结果也是ok的,这里需要解释一下

    我们使用的是接口,接口怎么可能调用方法呢?原因是自动的帮我们生成了一个实现类:代理对象

    可以看看我执行后输出的结果

    org.apache.ibatis.binding.MapperProxy@38d08cb5
    1查看精彩内容

    Proxy代理类。

    接口式编程的好处

    1. 返回值确定
    2. 参数确定,我写Integer,你就只能传入Integer
    3. 我不仅可以使用Mybatis,也可以使用Hibernate或者其他的工具,耦合度降低了

    接口式编程的增删改查

    上面我演示了接口式编程的查,现在演示一下其他的操作,增删改查

    先来看看我的实体类的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 -->
    <mapper namespace="com.website.mapper.ProductMapper">
        <!--
            数据库查询数据
            insert、select、delete、update:sql语句类型
            id:sql语句唯一标识
            resultType:结果返回值类型-包名+类名 或 基本数据类型
            parameterType:匹配字段值-包名+类名 或 基本数据类型
        -->
    
        <select id="getAll" parameterType="com.website.entity.Product"  resultType="com.website.entity.Product">
            select * from Product where 1=1
            <if test="name !=null and !&quot;&quot;.equals(name.trim())">and name =#{name}</if>
            <if test="type !=null and !&quot;&quot;.equals(type.trim())">and type like '%' #{type} '%'</if>
        </select>
    
    
        <select id="getOneById" parameterType="com.website.entity.Product"  resultType="com.website.entity.Product">
            select * from Product where ID=#{ID}
        </select>
    
        <insert id="insert"  parameterType="com.website.entity.Product">
        insert into Product values(#{id},#{name},#{price},#{type})
        </insert>
    
        <delete id="delete" parameterType="Integer">
                delete from Product where ID = #{id}
        </delete>
    
        <update id="update" parameterType="com.website.entity.Product">
        update Product set id=#{id},name=#{name},price=#{price},type=#{type} where id =#{id};
        </update>
    
    </mapper>
    

    这里面,增删改查,我都写了。可以发现一点,我在插入或者更新的时候,需要对一个对象进行操作,我写的参数都是对象实体类的字段名,这一点很方便。

    最后看看我的测试类吧

    package com.website.controller;
    
    import com.website.DB.DBAcess;
    import com.website.entity.Product;
    import com.website.mapper.ProductMapper;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    import static org.junit.Assert.*;
    
    public class ProductControllerTest {
    
        @Test
        public void list() throws IOException {
            Product product=new Product();
            List<Product> list=new ArrayList<>();
            DBAcess dbAcess=new DBAcess();
            SqlSession sqlSession = dbAcess.getSqlSession();
            try {
                ProductMapper mapper =sqlSession.getMapper (ProductMapper.class);
                list =mapper.getAll(product);
                System.out.println(list.size());
                System.out.println(list);
            }finally {
                sqlSession.close();
            }
        }
    
        @Test
        public void getOne() throws IOException {
            Product product=new Product();
            DBAcess dbAcess=new DBAcess();
            SqlSession sqlSession = dbAcess.getSqlSession();
            try {
                ProductMapper mapper =sqlSession.getMapper (ProductMapper.class);
                product=mapper.getOneById(1);
                System.out.println("------------"+product.getId());
                System.out.println("------------"+product.getName());
                System.out.println("------------"+product.getType());
                System.out.println("------------"+product.getPrice());
            }finally {
                sqlSession.close();
            }
        }
    
        @Test
        public void delete() throws IOException {
            DBAcess dbAcess=new DBAcess();
            SqlSession sqlSession = dbAcess.getSqlSession();
            try {
                ProductMapper mapper =sqlSession.getMapper (ProductMapper.class);
                mapper.delete(2);
                sqlSession.commit();
            }finally {
                sqlSession.close();
            }
        }
    
        @Test
        public void insert() throws IOException {
            Product product=new Product();
            product.setId(3);
            product.setName("IMac");
            product.setType("电脑");
            product.setPrice(15000.0);
    
            DBAcess dbAcess=new DBAcess();
            SqlSession sqlSession = dbAcess.getSqlSession();
            try {
                ProductMapper mapper =sqlSession.getMapper (ProductMapper.class);
                mapper.insert(product);
                sqlSession.commit();
            }finally {
                sqlSession.close();
            }
        }
    
    
        @Test
        public void update() throws IOException {
            Product product=new Product();
            product.setId(3);
            product.setName("IMac Pro");
            product.setType("台式电脑");
            product.setPrice(14500.0);
    
            DBAcess dbAcess=new DBAcess();
            SqlSession sqlSession = dbAcess.getSqlSession();
            try {
                ProductMapper mapper =sqlSession.getMapper (ProductMapper.class);
                mapper.update(product);
                sqlSession.commit();
            }finally {
                sqlSession.close();
            }
        }
    
    
    
    }
    

    可以发现,还是有不少的重复代码的,不爽啊。这个简单的操作上我还是喜欢JPA

    注意:查询不需要commit,其他的增删改都需要commit
  • 相关阅读:
    mysql_wp_replication_tutorial
    Procedure execution failed 2013
    [Err] 1136
    innodb_flush_log_at_trx_commit和sync_binlog 参数说明
    mysql没有oracle 那样一次性把data buffer 数据写入磁盘
    Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field
    MyEclipse之Widget is disposed
    Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Query was empty
    An internal error occurred during: "Building workspace". GC overhead limit exceeded
    Oracle 内部复制文档解读
  • 原文地址:https://www.cnblogs.com/yunquan/p/10424856.html
Copyright © 2011-2022 走看看