博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Mybatis初步学习
阅读量:4100 次
发布时间:2019-05-25

本文共 16719 字,大约阅读时间需要 55 分钟。

Mybatis简介

mybatis是一个基于java的持久层框架,特点就是以SQL语句为核心的不完全的ORM(关系型映射)框架

  • 持久层:可以将业务数据存储到磁盘,具备长期存储能力,只要磁盘不损坏,在断电或者其他情况下,重新开启系统仍然可以读取到这些数据
  • 优点:可以使用巨大的磁盘空间存储相当大的数据,并且很廉价
  • 缺点:慢,相对于内存而言

使用mybatis的好处:

  • 可以简化传统的JDBC繁琐的连接操作(必须操作Connection,Statement,ResultSet),而使用Mybatis之后,我们只需要提供SQL语句就好了,其余的建立连接,操作Statement,ResultSet,处理JDBC相关异常等等,都可以交给MyBatis处理,我们的关注点集中在SQL语句,和增改删查这些操作层面
  • 支持使用简单的XML或者注解来配置和映射原生信息,将接口和java的pojo映射成数据库中的记录

 我这里采取的是为IDEA配置MyBatis环境,IDEA默认不支持Mybatis开始,需要自己下载第三方插件来支持,但是MyBatis Plugin是收费的,需要自己破解,具体的破解方式这里就不详述了,大家可以自己在网上查找破解方法

MyBatis程序

一、准备数据库

首先我们创建一个数据库【mybatis】,在创建一个名为【student】的表

DROP DATABASE IF EXISTS mybatis;CREATE DATABASE mybatis DEFAULT CHARACTER SET utf8;use mybatis;CREATE TABLE student(  id int(11) NOT NULL AUTO_INCREMENT,  studentID int(11) NOT NULL UNIQUE,  name varchar(255) NOT NULL,  PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO student VALUES(1,1,'我没有三颗心脏');INSERT INTO student VALUES(2,2,'我没有三颗心脏');INSERT INTO student VALUES(3,3,'我没有三颗心脏');

二、创建工程

在IDEA中新建一个java工程,并命名为【HelloMybatis】,然后导入必要的jar包

  • mybatis-3.4.6.jar
  • mysql-connector-java-5.1.21-bin.jar

三、创建实体类

在package【pojo】下新建实体类【Student】,用于映射student

package pojo;public class Student {    int id;    int studentID;    String name;    /* getter and setter */}

四、配置文件mybatis-config.xml

在【src】目录下创建MyBatis的主配置文件mybatis-config.xml,其主要作用是提供连接数据库用的驱动,数据名称,编码方式,账号密码等

五、配置文件Student.xml

在Package【pojo】下新建一个【Student.xml】文件

六、编写测试类

在Package【Test】下创建测试类【TestMyBatis】:

package test;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 pojo.Student;import java.io.IOException;import java.io.InputStream;import java.util.List;public class TestMyBatis {    public static void main(String[] args) throws IOException {        // 根据 mybatis-config.xml 配置的信息得到 sqlSessionFactory        String resource = "mybatis-config.xml";        InputStream inputStream = Resources.getResourceAsStream(resource);        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        // 然后根据 sqlSessionFactory 得到 session        SqlSession session = sqlSessionFactory.openSession();        // 最后通过 session 的 selectList() 方法调用 sql 语句 listStudent        List
listStudent = session.selectList("listStudent"); for (Student student : listStudent) { System.out.println("ID:" + student.getId() + ",NAME:" + student.getName()); } }}

运行测试:可以获取数据库信息

基本原理:

  • 应用程序找MyBatis要数据
  • MyBatis从数据库中找来数据

           1、通过mybatis-config.xml定位哪个数据库

           2、通过Student.xml执行对应的sql语句

           3、基于Student.xml把返回的数据库封装在Student对象中

           4、把多个Student对象装载一个Student集合中

  • 返回一个Student集合

MyBatis——CRUD操作

一、配置Student.xml,首先在SQL映射文件中新增语句,用来支撑CRUD的系列操作

insert into student (id, studentID, name) values (#{id},#{studentID},#{name})
delete from student where id = #{id}
update student set name=#{name} where id=#{id}

 二、实现增删改查

package test;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 pojo.Student;import java.io.IOException;import java.io.InputStream;import java.util.List;public class TestMyBatis {    public static void main(String[] args) throws IOException {        // 根据 mybatis-config.xml 配置的信息得到 sqlSessionFactory        String resource = "mybatis-config.xml";        InputStream inputStream = Resources.getResourceAsStream(resource);        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        // 然后根据 sqlSessionFactory 得到 session        SqlSession session = sqlSessionFactory.openSession();        // 增加学生        Student student1 = new Student();        student1.setId(4);        student1.setStudentID(4);        student1.setName("新增加的学生");        session.insert("addStudent", student1);        // 删除学生        Student student2 = new Student();        student2.setId(1);        session.delete("deleteStudent", student2);        // 获取学生        Student student3 = session.selectOne("getStudent", 2);        // 修改学生        student3.setName("修改的学生");        session.update("updateStudent", student3);        // 最后通过 session 的 selectList() 方法调用 sql 语句 listStudent        List
listStudent = session.selectList("listStudent"); for (Student student : listStudent) { System.out.println("ID:" + student.getId() + ",NAME:" + student.getName()); } // 提交修改 session.commit();//提交事务 // 关闭 session session.close(); }}

模糊查询:

在Student.xml配置文件中配置SQL映射

 写一个测试方法:

@Testpublic void test() throws IOException {    // 根据 mybatis-config.xml 配置的信息得到 sqlSessionFactory    String resource = "mybatis-config.xml";    InputStream inputStream = Resources.getResourceAsStream(resource);    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);    // 然后根据 sqlSessionFactory 得到 session    SqlSession session = sqlSessionFactory.openSession();    // 模糊查询    List
students = session.selectList("findStudentByName", "三颗心脏"); for (Student student : students) { System.out.println("ID:" + student.getId() + ",NAME:" + student.getName()); }}

总结:

  • parameterType:要求输入参数的类型
  • resultType:输出的类型
  • #{}:在MyBatis中代表一种占位符
  • ${}:代表一个“拼接符号”,会引入SQL注入,不建议使用

适用场景:对SQL优化要求比较高,或项目需求或业务经常变动

与Hibernate相比:Hibernate学习成本比较高,而SQL语句并不需要开发人员完成,只需要调用API即可,但是缺点是没办法对SQL语句进行修改和优化,而MyBatis虽然需要开发人员自己配置SQL语句,MyBatis来实现映射关系,但是这样的项目可以适应经常变化的项目需求。

编写日志输出环境配置文件

使用log4j工具来输出:

将【MyBatis】文件夹下【lib】中的log4j开头的jar包都导入工程并添加依赖,在【src】下新建一个文件夹log4j.properties资源

# Global logging configuration# 在开发环境下日志级别要设置成 DEBUG ,生产环境设为 INFO 或 ERRORlog4j.rootLogger=DEBUG, stdout# Console output...log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

1》第一句配置语句,指的是日志输出级别

日志输出级别(7个级别):OFF,FATAL,WARN,INFO,DEBUG,ALL

  • 一般常用的日志输出级别分别为 DEBUG、 INFO、 ERROR 以及 WARN,分别表示 “调试级别”、 “标准信息级别”、 “错误级别”、 “异常级别”。如果需要查看程序运行的详细步骤信息,一般选择 “DEBUG” 级别,因为该级别在程序运行期间,会在控制台才打印出底层的运行信息,以及在程序中使用 Log 对象打印出调试信息。
  • 如果是日常的运行,选择 “INFO” 级别,该级别会在控制台打印出程序运行的主要步骤信息。“ERROR” 和 “WARN” 级别分别代表 “不影响程序运行的错误事件” 和 “潜在的错误情形”。
  • 文件中 “stdout” 这段配置的意思就是将 DEBUG 的日志信息输出到 stdout 参数所指定的输出载体中。

2》第二条配置语句,设置名为stdout的输出端载体是哪种类型

  • 目前输出载体有
    ConsoleAppender(控制台)
    FileAppender(文件)
    DailyRollingFileAppender(每天产生一个日志文件)
    RollingFileAppender(文件大小到达指定大小时产生一个新的文件)
    WriterAppender(将日志信息以流格式发送到任意指定的地方)
  • 这里要将日志打印到 IDEA 的控制台,所以选择 ConsoleAppender

3》第三条配置语句:意为名为stdout的输出载体的layout(界面布局)是哪种类型

  • 目前输出端的界面类型分为
    HTMLLayout(以 HTML 表格形式布局)
    PatternLayout(可以灵活地指定布局模式)
    SimpleLayout(包含日志信息的级别和信息字符串)
    TTCCLayout(包含日志产生的时间、线程、类别等信息)
  • 这里选择灵活指定其布局类型,即自己去配置布局。

4》第四条配置语句:假如界面布局选择了PatternLayout灵活布局类型,要指定打印的具体格式

  • 格式信息配置元素大致如下:
    %m 输出代码中的指定的信息
    %p 输出优先级,即 DEBUG、 INFO、 WARN、 ERROR 和 FATAL
    %r 输出自应用启动到输出该 log 信息耗费的毫秒数
    %c 输出所属的类目,通常就是所在类的全名
    %t 输出产生该日志事件的线程名
    %n 输出一个回车换行符,Windows 平台为 “rn”,UNIX 平台为 “n
    %d 输出日志时的时间或日期,默认个事为 ISO8601,也可以在其后指定格式,比如 %d{yyy MMM dd HH:mm:ss},输出类似:2018 年 4 月18 日 10:32:00
    %l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数

Mybatis高级映射

1》一对一查询

首先我们来建立一个数据模型:;

use mybatis;CREATE TABLE student (  id int(11) NOT NULL AUTO_INCREMENT,  name varchar(255) DEFAULT NULL,  card_id int(11) NOT NULL,  PRIMARY KEY (id))AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;CREATE TABLE card (  id int(11) NOT NULL AUTO_INCREMENT,  number int(11)  NOT NULL,  PRIMARY KEY (id))AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;INSERT INTO student VALUES (1,'student1',1);INSERT INTO student VALUES (2,'student2',2);INSERT INTO card VALUES (1,1111);INSERT INTO card VALUES (2,2222);

我们查询的SQL语句,可以写成下面这样:

SELECT    student.*,    card.*FROM    student,cardWHERE student.card_id = card.id AND card.number = #{value}

接下来我们分别使用resultType和resultMap来实现查询

(1)使用resultType实现

首先创建学生student表对应的java实体类Student,其中封装的属性信息为响应数据库的字段

package pojo;public class Student {    int id;    String name;    int card_id;    /* getter and setter */}

由于最终的查询结果是由resultType指定的,也就是只能映射一个确定的java包装类,但是上面的Student类只包含学生的基本信息,并没有包含Card的信息,所以我们要创建一个最终映射类,以Student类为父类,然后追加Card的信息

package pojo;public class StudentAndCard extends Student {    private int number;    /* getter and setter /*}

然后在Student.xml映射文件中定义<select>类型的查询语句SQL配置,将之前设计好的SQL语句配置进去,然后指定输出参数属性为resultType,类型为StudentAndCard这个java包装类

然后在测试类中编写测试方法:

@Testpublic void test() throws IOException {    // 根据 mybatis-config.xml 配置的信息得到 sqlSessionFactory    String resource = "mybatis-config.xml";    InputStream inputStream = Resources.getResourceAsStream(resource);    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);    // 然后根据 sqlSessionFactory 得到 session    SqlSession session = sqlSessionFactory.openSession();    // 找到身份证身份证号码为 1111 的学生    StudentAndCard student = session.selectOne("findStudentByCard",1111);    // 获得其姓名并输出    System.out.println(student.getName());}

(2)使用resultMap实现

使用resultMap可以将数据字段映射到名称不一样的响应实体类属性上,重要的是,可以映射实体类中包裹的其他实体类

首先我们来创建一个封装了Card号码和Student实体类的StudentWithCard类:

package pojo;public class StudentWithCard {        Student student;    int number;    int id;    /* getter and setter */}

SQL语句依然没有发生变化,但是使用的输出映射属性改为resultMap,其中的映射类型是id为StudentInfoMap的resultMap配置

稍微修改一下测试类,测试使用resultMap实现一对一查询映射:

@Testpublic void test() throws IOException {    // 根据 mybatis-config.xml 配置的信息得到 sqlSessionFactory    String resource = "mybatis-config.xml";    InputStream inputStream = Resources.getResourceAsStream(resource);    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);    // 然后根据 sqlSessionFactory 得到 session    SqlSession session = sqlSessionFactory.openSession();    // 找到身份证身份证号码为 1111 的学生    StudentWithCard student = session.selectOne("findStudentByCard", 1111);    // 获得其姓名并输出    System.out.println(student.getStudent().getName());}

2》一对多查询

首先还是重新建立数据库模型:

use mybatis;CREATE TABLE student (  student_id int(11) NOT NULL AUTO_INCREMENT,  name varchar(255) DEFAULT NULL,  PRIMARY KEY (student_id))AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;CREATE TABLE class (  class_id int(11) NOT NULL AUTO_INCREMENT,  name varchar(255) NOT NULL,  student_id int(11)  NOT NULL,  PRIMARY KEY (class_id))AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;INSERT INTO student VALUES (1,'student1');INSERT INTO student VALUES (2,'student2');INSERT INTO class VALUES (1,'Java课',1);INSERT INTO class VALUES (2,'Java课',2);

然后编写我们的SQL语句:

SELECT   student.*FROM  student, classWHERE student.student_id = class.student_id AND class.class_id = #{value}

创建对应的实体:

public class Student {    private int id;    private String name;    /* getter and setter */}public class Class {    private int id;    private String name;    private List
students; /* getter and setter */}

在 Package【pojo】下新建一个【class.xml】文件完成配置:

编写测试类:

@Testpublic void test() throws IOException {    // 根据 mybatis-config.xml 配置的信息得到 sqlSessionFactory    String resource = "mybatis-config.xml";    InputStream inputStream = Resources.getResourceAsStream(resource);    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);    // 然后根据 sqlSessionFactory 得到 session    SqlSession session = sqlSessionFactory.openSession();    // 查询上Java课的全部学生    List
students = session.selectList("listStudentByClassName", "Java课"); for (Student student : students) { System.out.println("ID:" + student.getId() + ",NAME:" + student.getName()); }}

3》多对多查询

建立数据库模型:

use mybatis;CREATE TABLE students (  student_id int(11) NOT NULL AUTO_INCREMENT,  student_name varchar(255) DEFAULT NULL,  PRIMARY KEY (student_id))AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;CREATE TABLE courses (  course_id int(11) NOT NULL AUTO_INCREMENT,  course_name varchar(255) NOT NULL,  PRIMARY KEY (course_id))AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;CREATE TABLE student_select_course(  s_id int(11) NOT NULL,  c_id int(11) NOT NULL,  PRIMARY KEY(s_id,c_id)) DEFAULT CHARSET=utf8;INSERT INTO students VALUES (1,'student1');INSERT INTO students VALUES (2,'student2');INSERT INTO courses VALUES (1,'Java课');INSERT INTO courses VALUES (2,'Java Web课');INSERT INTO student_select_course VALUES(1,1);INSERT INTO student_select_course VALUES(1,2);INSERT INTO student_select_course VALUES(2,1);INSERT INTO student_select_course VALUES(2,2);

设计SQL语句:

SELECT    s.student_id,s.student_nameFROM    students s,student_select_course ssc,courses cWHERE s.student_id = ssc.s_id AND ssc.c_id = c.course_id AND c.course_name = #{value}

和上述一样创建对应的实体类,这里就不详述了,我们直接配置映射文件【Student.xml】

然后就是测试类,只需要修改调用名称

Mapper动态代理

使用MyBatis开发Web工程时,通过Mapper动态代理机制,可以只编写数据交互接口及方法定义,和对应的Mapper映射文件,具体的交互方法实现由MyBatis来完成,这样可以节省开发DAO层的时间

接下来我们看实例:

1》Mapper代理实例编写

我们编写一个使用Mapper代理查询学生信息的实例,首先还是在【pojo】下新建一个名为StudentMapper.xml的Mapper配置文件,其中包含了对Student的增删改查的SQL配置

INSERT INTO student(student_id, name) VALUES(#{id}, #{name})
DELETE FROM student WHERE student_id = #{id}
UPDATE student SET name = #{name} WHERE student_id = #{id}

如果需要使用StudentMapper.xml的Mapper代理,首先需要定义一个接口,名为StudentMapper,然后在里面新建四个方法定义,分别对应StudentMapper.xml中的Student的增删改查的SQL配置,然后将StudentMapper中的namespace改为StudentMapper接口定义的地方,也就是mapper包下的StudentMapper,这样就可以在业务中使用Mapper代理了,接口代码如下:

package mapper;import pojo.Student;public interface StudentMapper {    // 根据 id 查询学生信息    public Student findStudentById(int id) throws Exception;    // 添加学生信息    public void insertStudent(Student student) throws Exception;    // 删除学生信息    public void deleteStudent(int id) throws Exception;    // 修改学生信息    public void updateStudent(Student student) throws Exception;}

3》测试动态理:

在测试之前,先将mybatis-config.xml中配置的映射文件修改一下,然后在测试方法中使用SqlSssion类的getMapper方法,并将要加载的Mapper代理的接口类传递进去,就可以获得相关的Mapper代理对象了,使用Mapper代理对象对学生信息进行增删改查:

@Testpublic void test() throws Exception {    // 根据 mybatis-config.xml 配置的信息得到 sqlSessionFactory    String resource = "mybatis-config.xml";    InputStream inputStream = Resources.getResourceAsStream(resource);    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);    // 然后根据 sqlSessionFactory 得到 session    SqlSession session = sqlSessionFactory.openSession();    // 获取 Mapper 代理    StudentMapper studentMapper = session.getMapper(StudentMapper.class);    // 执行 Mapper 代理独享的查询方法    Student student = studentMapper.findStudentById(1);    System.out.println("学生的姓名为:" + student.getName());    session.close();}

使用Mapper代理的好处:

  • 可以让开发更加简洁,使查询结构更加清晰,工程结构更加规范

使用注解开发MyBatis

在上面的示例中,我们已经有了方便的Mapper代理对象,我们可以进一步省略掉XML的配置信息,进而使用方便的注解来开发MyBatis,让我们来实战一下:

1》为Mapper增加注解

我们把StudeMapper.xml下配置的SQL语句通过注解的方式原封不对动的配置在StudentMapper接口中:

public interface StudentMapper {    // 根据 id 查询学生信息    @Select("SELECT * FROM student WHERE student_id = #{id}")    public Student findStudentById(int id) throws Exception;    // 添加学生信息    @Insert("INSERT INTO student(student_id, name) VALUES(#{id}, #{name})")    public void insertStudent(Student student) throws Exception;    // 删除学生信息    @Delete("DELETE FROM student WHERE student_id = #{id}")    public void deleteStudent(int id) throws Exception;    // 修改学生信息    @Update("UPDATE student SET name = #{name} WHERE student_id = #{id}")    public void updateStudent(Student student) throws Exception;}

2》修改mybatis-config.xml

将之前配置的映射注释掉,新建一条:

NOTE:映射文件使用resource属性,映射类使用class属性

至于,MyBatis的缓存机制以及延迟加载我们后期学习

转载地址:http://ogeii.baihongyu.com/

你可能感兴趣的文章
VC2015搭建OpenCV环境(超详细教程)
查看>>
瑞萨soc平台R-Car H3平台lvds调试
查看>>
Servlet的一些细节
查看>>
HTTP协议
查看>>
request对象
查看>>
response对象
查看>>
cookie和session
查看>>
防止表单重复提交
查看>>
实现一次性验证码的校验
查看>>
JSP简介
查看>>
jsp语法
查看>>
EL表达式和JSTL标签
查看>>
JavaBean
查看>>
Spring简介
查看>>
Spring搭建环境与实例化容器
查看>>
Spring依赖注入的方式
查看>>
spring集成jdbc
查看>>
组件扫描
查看>>
spring进行简单的查询
查看>>
SpringBoot发送邮箱
查看>>