写点什么

Mybatis【1】-- 第一个 Mybatis 程序

发布于: 2020 年 11 月 16 日
Mybatis【1】-- 第一个Mybatis程序

1.框架是什么

* 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面而后者是从目的方面给出的定义。

* 一个框架是一个可复用的设计构件,它规定了应用的体系结构,阐明了整个设计、协作构件之间的依赖关系、责任分配和控制流程,表现为一组抽象类以及其实例之间协作的方法,它为构件复用提供了上下文(Context)关系。因此构件库的大规模重用也需要框架。

* 个人理解:框架最重要的是把我们常用的,可以重复使用的功能抽象出来,不需要我们去重复写,我们只需要调用,或者按照规定配置,按照规则使用就可以了。这样的缺点是很多时候我们不知道为什么可以这样子使用,里面实现的细节被屏蔽掉了,这也是很多初学者很懵逼的地方,这时候追根问底就有一定必要性了。


2.Mybatis 的介绍

Mybatis 本来是 Apache 的一个开源项目iBatis,这个项目 2010 年由Apache迁移到了Google,更名为 Mybatis,2013 年正式迁移到Github


Mybatis是一个 java 中一个持久层的框架,在里面封装了 jdbc 操作,如果还不了解 java 如何使用 jdbc 访问数据库,那么可以查看这篇文章,封装使开发者只需要把精力放在开发 sql 语句上,不用去注册驱动,创建 Connection,配置 Statement,自己写代码管理事务等等。


Mybatis 通过 xml 或者注解的方式将需要执行的 statement 配置好,通过映射将 java 对象与 sql 中的动态参数一起生成最终的 sql 语句,执行完之后返回对象,其中也是映射的结果。


3.Mybatis 和 Hibernate 对比

1.Hibernate 是全自动的 ORM 框架,也就是完全实现了 POJO 和数据库表之间的映射,会自动生成 SQL。但是 Mybatis 不会自动生成,SQL 还是需要自己写,但是映射关系框架会自动处理,这样一个好处就是可以看得到 SQL,很多时候系统自动生成 SQL 并不是高效的,我们有时候需要优化 SQL,或者一些复杂的查询可能自动化的很难做到,缺点就是需要花时间写。


2.使用 XML 文件进行配置,分离了了 sql 与代码,这样比较容易维护。

3.Mybatis 是一个轻量级的框架。学习成本比 Hibernate 低很多,jar 包依赖也很少,上手比较快。


4.Mybatis 的结构图:



Mybatis 的运行机制:我们通过配置 Mybatis.xml(里面配置好数据库,需要扫描的 mapper.xml 文件等),程序会自动扫描配置好的 mapper 文件,当我们请求一个接口(请求数据库),接口会直接映射到对应的 sql 标签,同时将我们所写的配置文件读取并将数据库字段与对象属性匹配(这也是映射,如果不一致,需要自己手写映射关系),将 sql 参数传进去,然后执行相关的 sql,返回时又做了一次映射,把对象返回给我们。当然,这么描述是很表面的,因为 mybatis 还有事务,缓存等方面,以上只是大概。



5.IDEA 创建第一个程序

这里我们会使用 idea 创建项目,如果 maven 没有配置好,请参考:https://blog.csdn.net/aphysia/article/details/80363684

5.1 创建 mysql 数据库

使用一下的命令行:

CREATE DATABASE `test` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;CREATE TABLE `student` ( `id` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(20) NOT NULL , `age` INT NOT NULL , `score` DOUBLE NOT NULL , PRIMARY KEY (`id`)) ENGINE = MyISAM; 
复制代码

5.2 使用 idea 创建项目(Maven)

项目结构图(bean下面放的类对应我们的数据库里面的student表,也就是它的一个实体类,dao包下面放着我们的数据库的操作,resources下面放着我们的 xml 或者各种资源):


new --> Project -->点击Maven


点击next,GroupId,ArtifactId可以自己指定,点击下一步


自己指定project name(项目名),点击finish


pom.xml里面添加依赖,每一个<dependency></dependency>之间都是一种依赖包,选中项目右键--> Maven --> Reimport,这样就可以下载我们所需要的依赖了:


    <dependencies>        <!-- mybatis核心包 -->        <dependency>            <groupId>org.mybatis</groupId>            <artifactId>mybatis</artifactId>            <version>3.3.0</version>        </dependency>        <!-- mysql驱动包 -->        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>            <version>5.1.29</version>        </dependency>        <!-- junit测试包 -->        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.11</version>            <scope>test</scope>        </dependency>        <!-- 日志文件管理包 -->        <dependency>            <groupId>log4j</groupId>            <artifactId>log4j</artifactId>            <version>1.2.17</version>         </dependency>        <dependency>            <groupId>org.slf4j</groupId>            <artifactId>slf4j-api</artifactId>            <version>1.7.12</version>        </dependency>        <dependency>            <groupId>org.slf4j</groupId>            <artifactId>slf4j-log4j12</artifactId>            <version>1.7.12</version>        </dependency>    </dependencies>
复制代码

为了能实现日志的打印功能,我们在 pom.xml 文件中已经引入了日志 dependency,在这里还需要在resources文件夹下新建配置log4j.properties文件,具体配置代表什么意思,可以参考log4j 与log4j2详解


log4j.properties


log4j.rootLogger=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=[service] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#log4j.appender.R=org.apache.log4j.DailyRollingFileAppender #log4j.appender.R.File=../logs/service.log #log4j.appender.R.layout=org.apache.log4j.PatternLayout #log4j.appender.R.layout.ConversionPattern=[service] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#log4j.logger.com.ibatis = debug #log4j.logger.com.ibatis.common.jdbc.SimpleDataSource = debug #log4j.logger.com.ibatis.common.jdbc.ScriptRunner = debug #log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate = debug #log4j.logger.java.sql.Connection = debug log4j.logger.java.sql.Statement = debuglog4j.logger.java.sql.PreparedStatement = debuglog4j.logger.java.sql.ResultSet =debug
复制代码

配置好这些之后,前面结构图上面写到有一个mybatis.xml文件,里面配置了运行的环境(关于数据库的连接),连接的数据库可以配置多个,但是必须指定使用哪一个,这样做的原因的世界在 xml 文件进行修改不需要重新编译,更换数据库比较简单,除此之外,里面还需要配置 mapper.xml,也就是映射文件,我们要告诉它,我们将 sql 配置写在哪个文件。


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>  		<!-- 配置运行环境 -->  		<!-- default 表示默认使用哪一个环境,可以配置多个,比如开发时的测试环境,上线后的正式环境等 -->  		<environments default="mysqlEM">  		  			<environment id="mysqlEM">  				<transactionManager type="JDBC">		  				</transactionManager>  				<dataSource type="POOLED">  					<property name="driver" value="com.mysql.jdbc.Driver"/>  					<property name="url" value="jdbc:mysql://127.0.0.1:3306/test"/>  					<property name="username" value="root"/>  					<property name="password" value="123456"/>  				</dataSource>  			</environment>  			<environment id="testEM">  				<transactionManager type="JDBC">  				</transactionManager>  				<dataSource type="POOLED">  					<property name="driver" value="com.mysql.jdbc.Driver"/>  					<property name="url" value="jdbc:mysql://127.0.0.1:3306/test"/>  					<property name="username" value="root"/>  					<property name="password" value="123456"/>  				</dataSource>  			</environment>  		</environments>  		<!-- 注册映射文件 -->  		<mappers>  			<mapper resource="mapper.xml"/>  		</mappers>  </configuration>
复制代码

配置好mybatis.xml文件我们就需要写 sql 语句,根据上面的mybatis.xml,我们需要写mapper.xml文件,下面的namespace现在可以随意命名,因为只有一个 mapper.xml 文件,sql 标签的 id 没有重复,执行时就是根据 id 来查找的,同时这里 parameterType 对应的是参数类型,类型要写带完整路径名的类:


mapper.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="abc">	<insert id="insertStudent" parameterType="bean.Student">		insert into student(name,age,score) values(#{name},#{age},#{score})	</insert></mapper>
复制代码

在 bean 包下面创建与数据库对应的Student类【在 bean 包下】(这里先把属性名字和数据库的字段名一致,如果不一致需要自己写映射),注意里面的方法我们需要实现 set 和 get 方法,这个在 IDEA 里面,打开当前类,右键--> Gernarate -->setter and getter全选就可以生成。


Student.class


package bean;public class Student {    // id属性	private Integer id;	// 名字属性	private String name;	// 年龄属性	private int age;	//分数属性	private double score;	// 构造方法,除了id,因为我们的id在数据库中是自增的	public Student( String name, int age, double score) {		super();		this.name = name;		this.age = age;		this.score = score;	}	public Integer getId() {		return id;	}	public void setId(Integer id) {		this.id = id;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public int getAge() {		return age;	}	public void setAge(int age) {		this.age = age;	}	public double getScore() {		return score;	}	public void setScore(double score) {		this.score = score;	}	@Override	public String toString() {		return "Student [id=" + id + ", name=" + name + ", age=" + age				+ ", score=" + score + "]";	}	}
复制代码

在这里我们需要写一个接口,来表示操作学生信息,先写一个插入学生信息的接口,那么肯定是传一个学生对象进去。


IStduent.class


package dao;import bean.Student;public interface IStudentDao {	public void insertStu(Student student);}
复制代码

下面就是接口的实现类(重点):

StudentDaoImpl.class


package dao;import java.io.IOException;import java.io.InputStream;import bean.Student;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;public class StudentDaoImpl implements IStudentDao {    // 实现插入的接口方法	public void insertStu(Student student) {		try {			InputStream inputStream;		    // 读取配置信息的文件			inputStream = Resources.getResourceAsStream("mybatis.xml");			// 由于这个文件里面配置了mapper.xml,框架会帮我们扫描这些mapper.xml,下面是初始化一个SqlSessionFactory对象			SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);			// 工厂会获取一个SqlSession对象			SqlSession sqlSession=sqlSessionFactory.openSession();			// 通过这个对象可以查找之前mapper.xml里面配置好的sql的id与 `insertStudent`相等的,执行对应的sql			sqlSession.insert("insertStudent",student);		} catch (IOException e) {
e.printStackTrace(); }
} }
复制代码

测试方法,如果不了解 Junit 测试请参考Junit测试详解

MyTest.class


import bean.Student;import dao.IStudentDao;import dao.StudentDaoImpl;import org.junit.Before;import org.junit.Test;public class MyTest {	private IStudentDao dao;	@Before	public void Before(){		dao=new StudentDaoImpl();	}	@Test	public void testInsert(){		Student student=new Student("1ADAS",23,94.6);		dao.insertStu(student);	}}
复制代码

测试的结果,从最后三行我们可以看到执行的 sql 语句,以及参数等:


5.3 使用 Eclipse,MyEclipse 创建项目(Maven)

区别不大,直接创建 java Project,如果下面没有 lib 这个文件,就要新建一个,然后把需要的包导(复制粘贴)进去,选中 lib 下面所有的包,右键-->Build Path--> Add to Path



下面是 myEclipse 下面的结构图,代码没有改变,需要自己下载相关的包


声明:这样的写法不是最好的,但是这是初学者最容易接受的写法,后面会慢慢的精简,我们到时候不需要写接口的实现类,同时会把关于 sqlSessionFactory 相关的操作抽取出来成为一个工具类,就不用写那么多相同的代码了。


6.总结


最后总结一下上面写法的思路:


1.先读取mybatis.xml文件流inputStream,这是最重要的配置文件,里面的内容配置的是数据库环境,比如连接哪一个数据库链接,除此之外,还有注册映射文件,比如扫描哪一个文件,我们配置的是/mapper.xml

2.通过inputStream创建sqlSessionFactory,也就是 sql 会话工厂,所谓工厂,肯定是用来创造或者制造sqlSession的。

3.sqlSessionFactory.openSession()可以打开一个sqlSession,也就是 sql 会话,获得这个操作数据库的会话窗口。

4.通过sqlSession提供的方法去操作数据库,提供方法名,和参数即可。比如 sqlSession.insert("insertStudent", student);,这个insertStudent从哪里冒出来的?当然是前面扫描mapper.xml的时候,mapper.xml里面配置的,insertStudent是 id,需要是唯一的,就能通过这个找到对应的 sql 来执行。

5.提交会话,commit,不一定需要,具体看数据库的类型.

6.关闭会话,sqlSession.close();


代码已经放在: https://github.com/Damaer/Mybatis-Learning


此文章仅代表自己(本菜鸟)学习积累记录,或者学习笔记,如有侵权,请联系作者删除。人无完人,文章也一样,文笔稚嫩,在下不才,勿喷,如果有错误之处,还望指出,感激不尽~


技术之路不在一时,山高水长,纵使缓慢,驰而不息。

公众号:秦怀杂货店


发布于: 2020 年 11 月 16 日阅读数: 50
用户头像

纵使缓慢,驰而不息。 2018.05.17 加入

慢慢走,比较快。公众号:秦怀杂货店

评论

发布
暂无评论
Mybatis【1】-- 第一个Mybatis程序