MyBtis(一)?? 初识MyBatis

发布时间:2021-09-23 18:19:17



文章目录
mybatis基础知识Mybatis的使用配置实现注解实现
#{}和${}的区别



mybatis基础知识

MyBatis是一个实现了数据持久化的开源框架,其实它就像netty之于NIO一样,Mybatis是JDBC的封装,所以:


JDBC的缺点:


    需要频繁的进行数据库的建立、连接、断开操作,浪费资源,影响数据库性能;

    解决:连接池

    将SQL语句直接编码在Java代码中,需求改变时,需要修改Java代码;

    解决:将SQL语句和代码分开,SQL语句放在配置文件中

    JDBC编程中返回结果集存在硬编码的问题

    解决:将结果集映射成Java对象


MyBatis的优点:


    与JDBC相比,减少了50%以上的代码量。

    MyBatis是最简单的持久化框架,小巧并且简单易学。

    MyBatis相当灵活,不会对应用程序或者数据库的现有设计强加任何影响,SQL写在XML里,从程序代码中彻底分离,降低耦合度,便于统一管理和优化,并可重用。

    提供XML标签,支持编写动态SQL语句。

    提供映射标签,支持对象与数据库的ORM字段关系映射,可以把对象映射成表的元组、也可以把表中的元组映射成对象;


MyBatis框架的缺点:


    SQL语句的编写工作量较大,尤其是字段多、关联表多时,更是如此,对开发人员编写SQL语句的功底有一定要求。

    SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。


MyBatis和Hibernate的区别:


对于映射层而言,Hibernate的配置不需要接口和SQL,相反MyBatis是需要的,对于Hibernate而言,不需要编写大量的SQL,就可以完全映射,同时提供了日志、缓存、级联(级联比MyBatis强大)等特性,使用十分方便,但同时,Hibernate也存在巨大的缺陷;


MyBatis可以自由的书写SQL、支持动态SQL、处理列表、动态生成表名、支持存储过程,这样就可以灵活的定义查询语句,满足各类需求和性能优化的需要,这些再互联网系统中是十分重要的;


但MyBatis也有缺陷,他要编写SQL和映射规则,其工作量大于Hibernate,其次,它支持的工具也很有限,不能像Hibernate那样有许多的插件可以帮助生成映射代码和关联关系,而即使使用生成工具,往往也需要开发者进行进一步的简化,MyBatis通过手工编码,工作量相对大一些,所以对于性能要求不太苛刻的系统,使用Hibernate较好,对于性能要求高、响应快、灵活的系统则推荐使用MyBatis;


MyBatis与Hibernate相比主要的优势:


MyBatis不屏蔽SQL,这样开发者可以定制自己的SQL,无须自动生成(同时缺点就是工作量大,需要一定的学*成本),这样能够更精确的定义SQL,从而优化性能,符合移动互联网的高并发、大数据、高性能、高响应的要求;


MyBatis框架适用场合:


MyBatis专注于SQL本身,是一个足够灵活的DAO层解决方案。对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis将是不错的选择。


Mybatis的使用

先来介绍一下mybatis里面的一些组件吧,由SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory,然后由会话工厂创建会话SqlSession(与JDBC中的Statement类似),会话就是一个用户接口(他是不安全的,不能共用,所以一般都会在方法里面,作为一个局部变量),用户就可以那这个SqlSession使用他来操作数据库了;


上面介绍过,MyBatis能提供表元组和对象之间的映射,所以需要建立一张表,这里用Student:


create table Student(
SID int(10),
Sname varchar(20),
Ssex varchar(10),
Age int(10)
);

然后在这个表里面添加一些数据,以便后面用来测试,随便填写几个就可以了:


MyBatis开发有两种方式:


使用配置或使用注解;


配置实现

使用步骤:


    导入依赖;创建bean类、dao层接口;创建Mapper的xml文件、创建mybatis的xml文件;使用;

一、导入依赖


1、导入mybatis依赖:



org.mybatis
mybatis
3.4.5


2、还需要数据库的依赖:



mysql
mysql-connector-java
5.1.39


二、创建bean类、Mapper接口


bean类Student:


public class Student {
private int SID;
private String Sname;
private String Ssex;
private int Age;

public int getSID() {
return SID;
}

public void setSID(int SID) {
this.SID = SID;
}

public String getSname() {
return Sname;
}

public void setSname(String sname) {
Sname = sname;
}

public String getSsex() {
return Ssex;
}

public void setSsex(String ssex) {
Ssex = ssex;
}

public int getSage() {
return Age;
}

public void setSage(int sage) {
Age = sage;
}

@Override
public String toString() {
return "[id"+SID+" 名字"+Sname+" 性别"+Ssex+" 年龄"+Age+"]";
}
}

需要先创建自定义接口,但是不需要实现该接口,通过Mapper代理来实现:


如下,创建StudentMapper接口:


public interface StudentMapper {
public Student getStudentById(int id); //根据给定id查找并返回对象
}

三、创建两个xml文件


创建StudentMapper.xml文件,也放在resources下面,如上图所示,文件内容如下:


先说明:


select标签,和数据库的sql语句类似,这个表示查询,对应的还有update、delete、insert;id:除过使用id还可以使用name,name里面可以含有特殊字符,而id里面不能,表示一个代号或者说标识吧;parameter:入参类型,包括parameterType和parameterMap,参数类型可以是基本数据类型、自定义数据类型、Map类型;result:返回参数的类型,包括resultType和resultMap,参数类型和和上面一样;


PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">






statement标签根据SQL执行的业务可选择insert,delete,update,select。


MyBatis会根据规则自动创建UserDAO接口实现类的代理对象。


规则如下:


    Mapper.xml 中 namespace 为Mapper.java接口的全路径名。Mapper.xml中 statement 的 id 为Mapper.java接口中对应的方法名。Mapper.xml中 statement 的 parameter和Mapper.java接口中对应方法的参数类型一致。Mapper.xml中 statement 的 result 和Mapper.java接口中对应方法的返回值类型一致。

补充:


    不管是单个对象还是列表,在mapper.xml中的result的类型是一样的(但是他们的底层调用的方法不同,由mabatis处理,单个对象调用的是selectOne()方法,而列表调用的是selectList()),在对应的mapper.java接口中的返回值不一样;resultType适用于自定义类型属性和数据库表字段一样,而resultMap一般适用于不一样的情况,包括多表联合查询(即返回新的数据类型的时候);

添加MyBatis全局配置文件config.xml(文件名可自定义,这里用的mybatis-config.xml)


注意使用自己的数据库名字、自己的root用户、密码:



PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">





















注意,这个xml文件放在与Java文件同级的resources(名字可以自己起,但必须是配置文件,就是文件夹图标下面有4个黄色的横岗)文件下面:

下面是一个mybatis的配置文件(没用他,只是认识一些常用标签):



PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">






























































四、使用


测试代码:


我用的junit,所以需要这个jar包:




junit
junit
4.12
test


public class TestDemo1 {
@Test
public void test() throws IOException {
String resource = "配置使用mybatis/mybatis-config.xml";
//读取配置文件
InputStream asStream = Resources.getResourceAsStream(resource);
//创建sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(asStream);
//创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过动态代理产生StudentMapper对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = mapper.getStudentById(2); //获取id为2的数据的对象
System.out.println(student);
}
}


注解实现

使用步骤:


    导入依赖;创建对应的bean类、dao层接口;创建Mapper的xml文件、mybatis的全局配置xml文件;使用;

一、导入依赖


和上面一样,略;


二、创建对应的bean类、dao层接口


bean类和上面一样,略,dao层接口需要添加注解,如下(对应的增删该查方法我都写了):


public interface StudentMapper {
@Select("select * from student where SID = #{id}")
public Student getStudentById(int id);

@Select("select * from student where Sname = #{name} and Age = #{age}")
public Student getSnameAndSage(@Param("name") String name, @Param("age") int age);

@Select("select * from student")
public Student[] getAllStudent();

@Insert("insert into student (SID,Sname) values(#{SID},#{Sname})")
public void addStudent(Student student);

@Delete("delete from student where Sid = #{id}")
public void delete(int id);

@Update("update student set Sname = #{name} where id=#{id}")
public void setValue(@Param("id") int id,@Param("name") String name);
}

注意:在参数比较多的时候,需要在接口参数类型前面添加@Param(参数名称),否者它就不知道哪个参数放在sql语句的哪个地方了,这样可以指定这个参数是给哪的


三、创建两个xml文件


上面基本一样,只不过SQL语句不用写到StudentMapper.xml里面,在StudentMapper.xml里面只需要这样就可以了:



PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">




mybatis的xml文件也不需要修改,略;


测试代码:


public class TestDemo1 {
@Test
public void test() throws IOException {
String resource = "注解使用mybatis/mybatis-config.xml";
//读取配置文件
InputStream asStream = Resources.getResourceAsStream(resource);
//创建sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(asStream);
//创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过动态代理产生StudentMapper对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

//查询id为2的元组
Student student = mapper.getStudentById(2);
System.out.println("=============查询id=2的记录======================");
System.out.println(student);

//往数据库添加新的元组
Student student1 = new Student();
student1.setSID(4);
student1.setSname("xxx");
mapper.addStudent(student1);
sqlSession.commit();

Student student2 = new Student();
student1.setSID(9);
student1.setSname("xxx");
mapper.addStudent(student2);
sqlSession.commit();

//返回列表所以元素
System.out.println("=============添加两条记录后所有的记录======================");
Student[] students1 = mapper.getAllStudent();
for (Student s : students1) {
System.out.println(s);
}

//删除
mapper.delete(4);
mapper.delete(9);
sqlSession.commit();
System.out.println("=============删除两条记录后所有的记录======================");
Student[] students2 = mapper.getAllStudent();
for (Student s : students2) {
System.out.println(s);
}
}
}


气人,不知道为什么多出一条0的记录!!!


#{}和${}的区别

顺便说一下,在配置文件里面,SQL语句的参数可以是#{} 还可以是${},这两者有什么区呢?


要看区别(后面几节也会用到),需要导入如下三个日志相关的依赖:




log4j
log4j
1.2.17


org.slf4j
slf4j-log4j12
1.7.21


org.slf4j
slf4j-api
1.7.21


然后需要一个 log4j 的配置文件 log4j.properties:


## debug 级别
log4j.rootLogger=DEBUG,Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.Target=System.out
log4j.appender.Console.layout = org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d{yyyy-MM-dd-HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n
log4j.logger.com.mybatis=DEBUG /


##输出sql 语句
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

把它配置文件的根目录下面:

最后就是在我们要用的mybatis的配置文件里面添加:








就是上面我们用的mybatis.xml文件里面添加:

#{}
相当于JDBC里面的PreparedStatement ;先编译,编译没问题再拿这个编译的结果去执行:


再次运行上面的代码:


${}
相当于JDBC里面的Statement;直接拿,然后编译执行;


所以相比之下,#{}效率更高,并且不存在SQL注入问题,比*踩

相关文档

  • word标题阴影边框怎么设置
  • redmine 安装使用总结 一键安装
  • (四)实验2-3-3 信号处理总结以及Linux下支持的信号列表
  • 形容橘子好吃的句子
  • 柳州国际会展中心
  • 精华风雨作文400字3篇
  • 农村贫困残疾人就业帮扶活动总结2021
  • 我家交通工具“三步曲”
  • 伊索寓言读后感400字(通用10篇)
  • 柿子的功效与作用及禁忌 食用方法
  • 韩国时尚女生短发发型图片
  • 电脑出现风扇故障怎么办
  • 幼小班体育教案:大懒猫和小老鼠
  • 我愿是“阳光城市”里的一棵小树
  • 怎样根治口腔溃疡?
  • 交管12123换驾驶证怎么获取体检信息?
  • 杀子求名
  • 钩针毛毯图片大全高清图片
  • ListView使用方法
  • [译] 用不到 200 行的 GO 语言编写您自己的区块链
  • 为什么训练时测试准确率大幅度波动_你也可以训练超大神经网络!谷歌开源GPipe库...
  • 实现线程同步的关键字
  • 通用返回类
  • 保洁人员工作计划5篇
  • 奇妙的蛋
  • 国务院任免国家工作人员 李树深任中科院副院长
  • 小虎成长记(续二十五)
  • 深入贯彻共青团宣传思想工作
  • 2016年11月项目经理工作总结
  • Spring boot 集成swagger-ui 在线API文档生成自我实践记录
  • 猜你喜欢

    电脑版