zoukankan      html  css  js  c++  java
  • Mybatis在Maven项目中使用

    Mybatis概览

    ORM是什么?

    ORM是Object Realtion Mapping的缩写,顾名思义,即对象关系映射。

    ORM是一种以面向对象的方式来进行数据库操作的技术。Web开发中常用的语言,都会有对应的ORM框架,而Mybatis就是Java开发中一种常用的ORM框架。

    简单地理解,通过Java进行数据库访问的正常流程可以分为以下几步:

    1. 准备好SQL语句
    2. 调用JDBC的API传入SQL语句,设置参数
    3. 解析JDBC返回的结果

    这个过程实际上非常麻烦,比如:

    • 在Java代码中拼接SQL非常麻烦,而且易于出错
    • JDBC的代码调用有很多重复性的代码
    • 从JDBC返回的结果转换成领域模型的Java对象非常繁琐

    而使用ORM框架,则可以让我们用面向对象的方式来操作数据库,比如通过一个简单的函数就完成上面的流程,直接返回映射为Java对象的结果。这个流程中很大一部分工作就交给ORM自动化帮我们执行了。

    Mybatis是支持定制化SQL,存储过程以及高级映射的优秀持久层框架。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。Mybatis可以对配置和原生Map使用简单的XML或标注,将接口和Java的POJOS(Plan Old Java Objects,普通的Java对象)映射成数据库中的记录。

    简单地理解,你可以认为Mybatis将SQL语句,以及SQL返回结果到Java对象的映射,都放到一个易于配置的XML文件里了,你的Java代码会变得异常简单。当然除了XML,Mybatis同时也支持基于标注的方式,但是功能上会有一些限制。总体来说,还是推荐使用XML方式,一些简单的SQL使用标注会更方便一些。

    创建项目

    新建一个Maven项目,接下来引入Mybatis和MySQL的依赖:

    <!-- mybatis依赖 -->
        <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.0</version>
        </dependency>
        
        <!-- MySQL数据库依赖 -->
        <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</version>
        </dependency>

    既然是ORM的练习,先设计Object,再设计Relation,最后再看怎么做Mapping

    实体类设计

    分析我们的业务场景,可以设计三个类:

    • Question表示问题
    • Answer表示回答
    • Tag表示问题标签

    其中:

    • Question可以有多个Answer,一个Answer对应唯一一个Question,一对多的关系
    • Question可以有多个Tage,一个Tag可用于多个Question,多对多的关系

    暂时先不管Answer和Tag,只关注Question:

    Question.java

    package com.fpc.Entity;
    
    import java.util.Date;
    import java.util.List;
    
    public class Question {
        private int id;
        private String title;
        private String description;
        private Date createdTime;
        private List<Tag> tags;
        private List<Answer> answers;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getTitle() {
            return title;
        }
        public void setTitle(String title) {
            this.title = title;
        }
        public String getDescription() {
            return description;
        }
        public void setDescription(String description) {
            this.description = description;
        }
        public Date getCreatedTime() {
            return createdTime;
        }
        public void setCreatedTime(Date createdTime) {
            this.createdTime = createdTime;
        }
        public List<Tag> getTags() {
            return tags;
        }
        public void setTags(List<Tag> tags) {
            this.tags = tags;
        }
        public List<Answer> getAnswers() {
            return answers;
        }
        public void setAnswers(List<Answer> answers) {
            this.answers = answers;
        }
        
        
    }

    这里的Question实现了Serializable接口,实现这个接口是为了后面缓存查询结果是需要的。

    数据库设计

    除了设计Question,Answer和Tag数据表,还需要定义一张维护Question和Tag之间多对多关系的表。最终数据库设计如下:

    创建question表:

    CREATE TABLE question(
     id INT PRIMARY KEY AUTO_INCREMENT,
     createdTime DATETIME,
     description LONGTEXT,
     title VARCHAR(255)
    );

    接下来添加MyBatis的配置,在resources目录下简历mybatis.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>
        <!-- 引用db.properties配置文件 -->
        <properties resource="db.properties"></properties>
        <!--
            development:开发模式
            work:工作模式 
         -->
         <typeAliases>
             <!-- <typeAlias type="com.fpc.Entity.User" alias="_User"/> -->
             <package name="com.fpc.Entity"/>
         </typeAliases>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <!-- 配置数据库连接信息 -->
                <dataSource type="POOLED">
                    <!-- value属性值引用db.properties配置文件中配置的值 -->
                    <property name="driver" value="${driver}"/>
                    <property name="url" value="${url}"/>
                    <property name="username" value="${name}"/>
                    <property name="password" value="${password}"/>
                </dataSource>
            </environment>
        </environments>
        
        <mappers>
            <!-- 注册userMapper.xml文件, 
            userMapper.xml位于me.gacl.mapping这个包下,所以resource写成me/gacl/mapping/userMapper.xml-->
            <mapper resource="com/fpc/Mapping/questionMapper.xml"/>
            <!-- <mapper class="com.fpc.Mapping.questionMapperI"/> -->
        </mappers>
        
    </configuration>

    这就是一个最简单的MyBatis配置文件,定义了数据源和mapper文件的位置。

    关于MyBatis配置:

    后面会发现有了Spring和SpringBoot支持,很多配置不需要手动设置了,比如映射文件的位置,数据源和事务管理器等,这个文件需要的内容非常少,甚至可以不需要这个文件了。

    需要修改MyBatis配置文件的几种常用的情况包括:

    • 要增加插件,比如后面需要用到的分页插件
    • 修改MyBatis的运行时行为,参考settings选项
    • 重写类型处理器或创建自定义的类型处理器来处理非标准类型。

    定义Mapper接口

    Mapper的Java接口,这是数据库访问的接口:

    package com.fpc.Mapping;
    
    import org.apache.ibatis.annotations.Param;
    
    import com.fpc.Entity.Question;
    
    public interface questionMapperI {
        Question findOne(@Param("id") int id);
    }

    @Param是MyBatis提高的一个标注,表示id会解析成SQL语句的参数。

    使用XML定义Mapper

    对应于Mapper接口,还需要通过XML来给出Mapper的实现,将映射放在com/fpc/Mapping/下

    <?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,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的
    例如namespace="me.gacl.mapping.userMapper"就是me.gacl.mapping(包名)+userMapper(userMapper.xml文件去除后缀)
     -->
    <mapper namespace="com.fpc.Mapping.questionMapperI">
        <select id="findOne" resultType="com.fpc.Entity.Question">
            select * from question where id = #{id}
        </select>
    </mapper>

    Mapper的配置是MyBatis的精华,注意两点:

    • 对应于每一个Mapper的Java接口方法,XML配置中有对应的一个元素来描述其SQL语句
    • resultType元素定义了数据库返回(一行记录)如何映射到一个Java对象

    使用Mapper

    已经有一个可以根据id获取问题的接口方法了,编写测试类测试:

    package com.fpc.Test;
    
    import java.io.IOException;
    import java.io.Reader;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import com.fpc.Entity.Question;
    import com.fpc.Mapping.questionMapperI;
    
    public class TestMybatis {
        public static void main(String[] args) {
            String resource = "mybatis.xml";
            Reader reader;
            try {
                reader = Resources.getResourceAsReader(resource);
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
                SqlSession sqlSession = sqlSessionFactory.openSession();
                questionMapperI questionMapper = sqlSession.getMapper(questionMapperI.class);
                Question question = questionMapper.findOne(1);
                System.out.println(question.getDescription());
                sqlSession.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
    }

    把这个main方法运行起来就能看到结果了,调用看起来有点复杂,这里涉及Mybatis的几个关键类:

    • SqlSessionFactoryBuilder
    • SqlSessionFactory
    • SqlSession

    其实引入Spring Boot之后,你会发现这几个类都被屏蔽掉了,你只需专注于写Mapper即可。不过了解一下这几个类,对于我们调试程序和理解MyBatis都是大有裨益的。

  • 相关阅读:
    尝试实现一个简单的C语言string类型
    LeetCode.49
    Python学习 —— 实现简单的爬虫
    图表可视化表达的逻辑原理
    颜色参数
    Python交互图表可视化Bokeh:7. 工具栏
    Python交互图表可视化Bokeh:6. 轴线| 浮动| 多图表
    Python交互图表可视化Bokeh:5 柱状图| 堆叠图| 直方图
    Python交互图表可视化Bokeh:4. 折线图| 面积图
    Python交互图表可视化Bokeh:3. 散点图
  • 原文地址:https://www.cnblogs.com/fangpengchengbupter/p/7975773.html
Copyright © 2011-2022 走看看