mybatis简介
myBatis是一个持久层框架,主要作用就是在java中操作数据库,其实就是在jdbc的基础上进行了封装,使用mybatis之后,开发者不用再花费精力去处理诸如注册驱动、创建Connection、配置Statement等繁琐过程。与之前学习的spring mvc要运行在web容器不同,mybatis不需要web容器,在c/s架构和b/s架构下均可运行。早期叫做iBatis,后来改名为myBatis,官网:http://www.mybatis.org/mybatis-3/
在官网上有中文版的介绍和文档,mybatis同时支持xml和注解,这里xml用的多一些。
第一个mybatis程序
这里将试用myBatis将一个Student对象中的数据存储到数据库中。
1.创建一个web的maven项目,添加mybatis的依赖jar包和mysql的数据库驱动
为了查看具体的sql信息,需要添加log4j:
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
除了mybatis的jar包之外,为了方便调试,这里要使用junit,其相关依赖jar包在你使用骨架创建maven项目的时候会自动加入的。
另外还需要在pom.xml文件中的build标签下添加:
<resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources>
因为后面我们要在dao包下编写xml文件,如果不添加上面内容的话,maven是不会将xml文件发布到编译后的classes目录下,这样就会导致mybatis到不到该文件。
2.创建一个Student实体类:
package com.monkey1024.bean; public class Student { private int id; private String name; private int age; private double score; //省略getter和setter }
3.创建数据库表
在数据库中创建一张表t_student,表中的字段要与上面Student类中的属性名一致(不一致的话需要额外的配置,目前先写成一致的),建表语句,主键id自增:
CREATE TABLE `learnmybatis`.`t_student` ( `id` INT NOT NULL AUTO_INCREMENT, `name` VARCHAR(20) NULL, `age` INT NULL, `score` DOUBLE NULL, PRIMARY KEY (`id`));
4.定义一个dao的接口:
package com.monkey1024.dao; import com.monkey1024.bean.Student; public interface StudentDao { void insertStudent(Student student); }
5.添加映射文件
映射文件,一般称之为mapper,主要是在里面编写SQL语句,里面具体配置,后面会详细讲解。暂时先照着下面的写,dtd约束可以直接拷贝下面的内容。mapper的文件名随意,一般会跟dao接口放在同一个包下,这里映射文件名称定为StudentMapper.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="monkey1024"> <!--parameterType可省略--> <insert id="insertStudent" parameterType="com.monkey1024.bean.Student"> INSERT INTO t_student(name,age,score) VALUES (#{name},#{age},#{score}) </insert> </mapper>
mybatis会检测到student类型的对象,所以parameterType一般不用指定,values后面的#{}中的内容是Student的属性名。
6.添加mybatis的主配置文件
主配置文件的名称同样也是可以随意命名的,这里就将其命名为mybatis.xml,将这个配置文件放到maven项目中的resources目录下。
<?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> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/learnmybatis?useSSL=false"/> <property name="username" value="root"/> <property name="password" value="monkey1024"/> </dataSource> </environment> </environments> <mappers> <!--注册映射文件--> <mapper resource="com/monkey1024/dao/StudentMapper.xml"/> </mappers> </configuration>
7.查看日志
mybatis支持下面的日志处理:
- SLF4J
- Apache Commons Logging
- Log4j 2
- Log4j
- JDK logging
在其官方文档中使用了Log4j作为的示例,因此这里我们也使用log4j进行处理。在resources目录下创建log4j.properties文件,里面加上下面内容:
log4j.rootLogger=trace,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= [%-5p][%d{yyyy-MM-dd HH:mm:ss}]%m%n
上面的内容使用了rootLogger作为日志对象,此时可能会输出太多的日志信息,我们可以通过修改配置只查看某个namespace下的日志:
##查看monkey1024的namespace下的sql语句
log4j.logger.monkey1024=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= [%-5p][%d{yyyy-MM-dd HH:mm:ss}]%m%n
8.创建接口的实现类
创建StudentDao接口的实现类:
package com.monkey1024.dao.impl; import com.monkey1024.bean.Student; import com.monkey1024.dao.StudentDao; 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 java.io.IOException; import java.io.InputStream; public class StudentDaoImpl implements StudentDao { private SqlSession sqlSession; @Override public void insertStudent(Student student) { try { //读取主配置文件 InputStream input = Resources.getResourceAsStream("mybatis.xml"); //创建SqlSessionFactory对象 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(input); //创建SqlSession对象 sqlSession = sessionFactory.openSession(); //新增数据操作 sqlSession.insert("insertStudent", student); //提交SqlSession sqlSession.commit(); } catch (IOException e) { e.printStackTrace(); } finally { if (sqlSession != null){ sqlSession.close(); } } } }
9.创建测试类,这里使用了junit:
package com.monkey1024.test; import com.monkey1024.bean.Student; import com.monkey1024.dao.StudentDao; import com.monkey1024.dao.impl.StudentDaoImpl; import org.junit.Test; public class StudentTest01 { @Test public void insertStudent(){ StudentDao studentDao = new StudentDaoImpl(); Student student = new Student("刘德华", 52, 98.50); studentDao.insertStudent(student); } }
顺利执行完成后,可以在数据库中找到新添加的那条数据。
在上面代码中,获取SqlSession对象的操作比较复杂,此时可以考虑将过去SqlSession对象的操作封装成一个方法。SqlSession对象是由SqlSessionFactory对象创建的,SqlSessionFactory是线程安全的,所以可以使用单例模式来创建SqlSessionFactory对象。
1.创建一个MyBatisUtil工具类:
import com.monkey1024.bean.Student; import com.monkey1024.dao.StudentDao; import com.monkey1024.util.MyBatisUtil; import org.apache.ibatis.session.SqlSession; public class StudentDaoImpl implements StudentDao { @Override public void insertStudent(Student student) { //SqlSession继承了AutoCloseable接口,所以可以自动关闭 try(SqlSession sqlSession = MyBatisUtil.getSqlSession()) { //新增数据操作 sqlSession.insert("insertStudent", student); //提交SqlSession sqlSession.commit(); } } }
上面的单例模式比较特殊,里面无需将构造方法私有化,至于MyBatisUtil这个类创建几个对象无所谓,他只要保证其内部只创建一个SqlSessionFactory对象就行,这里只是将单例模式应用在创建SqlSessionFactory对象上。
2.修改StudentDaoImpl类:
package com.monkey1024.dao.impl; import com.monkey1024.bean.Student; import com.monkey1024.dao.StudentDao; import com.monkey1024.util.MyBatisUtil; import org.apache.ibatis.session.SqlSession; public class StudentDaoImpl implements StudentDao { @Override public void insertStudent(Student student) { //SqlSession继承了AutoCloseable接口,所以可以自动关闭 try(SqlSession sqlSession = MyBatisUtil.getSqlSession()) { //新增数据操作 sqlSession.insert("insertStudent", student); //提交SqlSession sqlSession.commit(); } } }
SqlSession继承了AutoCloseable接口,所以可以将其放到try后面自动关闭。
从配置文件中读取数据库的信息
一般情况下为了便于管理,都会将数据库的一些信息放到配置文件中,mybatis.xml配置文件会从该配置文件中读取相关的信息。
在resources目录下创建db.properties配置文件,里面填写下面内容:
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/learnmybatis?useSSL=false jdbc.user=root jdbc.password=monkey1024
将以上配置文件注册到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> <!--注册配置文件--> <properties resource="db.properties"/> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.user}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <mappers> <!--注册映射文件--> <mapper resource="com/monkey1024/dao/StudentMapper.xml"/> </mappers> </configuration>
mybatis配置文件主要作用
- 注册db.properties属性文件,以便使用
- 注册实体类(JavaBean)的全限定性类名的别名
- 配置MyBatis运行环境,即数据源与事务管理器
- 注册映射文件mapper
基本上mybatis的配置文件主要作用是上面的这些内容。
1.注册db.properties属性文件
我们在mybatis.xml文件中添加了下面配置:
<properties resource="db.properties"/>
这个配置的作用就是注册db.properties属性文件,这样子就可以获取里面的数据库信息了。
2.注册实体类(JavaBean)的全限定性类名的别名
因为在写mapper配置文件的时候,需要写上一些javabean类的全限定名,这样子就不太方便,此时就可以使用typeAliases标签设置该javabean类的别名,这样子就不用再写包名了,减少冗余。
<typeAliases> <typeAlias type="com.monkey1024.bean.Student" alias="student"/> </typeAliases>
这样子,在mapper配置文件中就可以直接使用student来代替之前的com.monkey1024.bean.Student。
上面的是第一种方式,倘若有个多个javabean的话,需要写多个typeAlias,此时我们可以使用package指定一个包名,mybatis会在这个包名下搜索需要的JavaBean。
<typeAliases> <package name="com.monkey1024.bean"/> </typeAliases>
默认情况下,会将com.monkey1024.bean包下的类名首字母小写作为别名,例如:com.monkey1024.bean.Student的别名就是student。
我们还可以在Student类上使用@Alias注解来手动给他取一个别名:
@Alias("stu")
public class Student {
private int id;
private String name;
private int age;
private double score;
}
mybatis已经为一些常见的类内建了别名:
别名 映射的类型 _byte byte _long long _short short _int int _integer int _double double _float float _boolean boolean string String byte Byte long Long short Short int Integer integer Integer double Double float Float boolean Boolean date Date decimal BigDecimal bigdecimal BigDecimal object Object map Map hashmap HashMap list List arraylist ArrayList collection Collection iterator Iterator
3.配置MyBatis的运行环境
-
运行环境的切换
一个稍具规模的项目在开发的时候都会有多个环境,即多个数据库,在开发阶段连接数据库A(或者是本地的数据库),集成测试阶段使用数据库B,项目上线后使用数据库C,此时在mybatis中配置选择哪个数据库。<!--生产环境--> <environment id="online"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.online.driver}"/> <property name="url" value="${jdbc.online.url}"/> <property name="username" value="${jdbc.online.user}"/> <property name="password" value="${jdbc.online.password}"/> </dataSource> </environment>
在environments标签中有两个environment子标签表示了两个数据库,此时可以在environments中使用default属性来指定使用哪一个数据库,这样子,在切换环境的时候,只需要修改default的属性即可。
-
transactionManager标签
该标签用于指定MyBatis所使用的事务管理器。 MyBatis 支持两种事务管理器类型:-
JDBC
该事务器就是我们之前通过Connection的commit()方法提交,通过rollback()方法回滚,默认是需要手动提交的。 -
MANAGED
由容器来管理事务的整个事务的生命周期,默认情况下会关闭连接,将来学习spring框架之后,就不用在配置事务管理器了,spring会使用自带的管理器。
-
-
dataSource标签
该项主要用于配置数据源和数据库连接基本属性,有以下三种内建的数据源类型:- UNPOOLED
该配置表示不使用连接池,每次请求都会创建一个数据库连接,使用完毕后再关闭。当项目对数据库性能要求不大的时候,可以使用该配置。 - POOLED
改配置表示使用mybatis自带的数据库连接池,可以在dataSource下的property属性中设置数据库连接池的基本信息,该部分可以在mybatis的官网中看到。 - JNDI
配置外部数据源
- UNPOOLED
4.mapper映射器
映射器的作用就是在告诉mybatis.xml配置文件我们编写的mapper所在的路径,一共有四种写法:
第一种:
<mappers> <!--使用相对于类路径的资源引用--> <mapper resource="com/monkey1024/dao/StudentMapper.xml"/> </mappers>
第二种:
<mappers> <!--使用完全限定资源定位符(URL)--> <mapper url="F:///monkey1024/StudentMapper.xml"/> </mappers>
第三种:
该方式的使用,需要满足以下几个要求:
(1)映射文件名要与 Dao 接口名称相同
(2)映射文件要与接口在同一包中
(3)映射文件中的 namespace 属性值为 Dao 接口的全类名
<mappers> <!--使用映射器接口实现类的完全限定类名--> <mapper class="com.monkey1024.dao.StudentDao"/> </mappers>
第四种:
这种方式的使用需要满足以下几个条件:
(1)dao 使用 mapper 动态代理实现(后面再将)
(2)映射文件名要与 Dao 接口名称相同
(3)映射文件要与接口在同一包中
(4)映射文件中的 namespace 属性值为 Dao 接口的全类名
<mappers> <!--将包内的映射器接口实现全部注册为映射器--> <package name="com.monkey1024.dao"/> </mappers>
转载仅供个人学习,谢谢分享!
来源:链接