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
  • 相关阅读:
    【故障处理】ORA-12162: TNS:net service name is incorrectly specified (转)
    android studio 编程中用到的快捷键
    java时间格式串
    android Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine.
    linux安装vmware
    x1c 2017 安装mint18的坑——grub2
    x1c2017 8G版 win linux的取舍纠结记录
    python的try finally (还真不简单)
    kafka+docker+python
    json文件不能有注释
  • 原文地址:https://www.cnblogs.com/yunquan/p/10424856.html
Copyright © 2011-2022 走看看