框架之MyBatis
什么是框架,简单的来说框架就是一个程序的半成品,而我们就是的工作就是根据我们的工作需要将其完善。MyBatis框架的作用就是将我们使用JDBC操作数据库的过程移交给MyBatis,让它来帮我们完成这些复杂,繁琐的(主要是没什么意义)冗余的操作!
在了解MyBatis数据库的前提下,我们首先有必要先了解一下什么是ORM和持久化
持久化:是程序数据,在瞬时状态(内存)向持久状态(数据库)之间转化的过程称为持久化。让对象的生命周期超越所使用对象的程序的运行期。
ORM(Object Relational Mapping):编写程序时以面向对象的方式处理数据(对象)
保存数据时以关系型数据库方式储存数据(表)
MyBatis的核心对象
1:SqlSessionFactoryBuilder :利用XML文件或者Java编码获得资源来构建SqlSessionFactory,通过它可以构建多个SqlSessionFactory,它的作用域仅仅只是在方法上,一旦创建了SqlSessionFactory他就没什么用了(用过即丢)
2:SqlSessionFactory:用来创建SqlSession的,每次访问数据库,我们都要通过SqlSessionFactory来创建SqlSession。它的作用域时应用期间,也就是程序开始,一直到服务器关闭。而且对于同一个数据库我们只需要一个SqlSessionFactory,否则,每次创建的SqlSessionFactory都会打开更多的资源,那么连接资源很快就会被耗尽,于是SqlSessionFactory是唯一的(使用单例模式)
3:SqlSession:SqlSession是一个会话,相当于JDBC中的一个Connection对象,它的生命周期应该是在请求数据库处理事务的过程中,且SqlSession是线程非安全的对象,涉及多线程时要特别的当心,每次创建的SqlSession对象都要及时的关闭它,它长期存在就会使数据库连接池的活动资源减少,对系统性能影响很大!
MyBatis的核心配置文件
案例(在这里我使用的开发工具是idea)
1、导入MyBatis的依赖和连接mysql(JDBC)的依赖
<!--MyBatis的jar文件--> <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.32</version> </dependency>
2、创建表(自行创建)
3、在resource目录下创建configuration.xml文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!-- xml文件的头文件,起到对文件的约束作用(例如:必须存在哪些节点) --> 3 <!DOCTYPE configuration 4 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 5 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 6 <!--根节点,不解释。--> 7 <configuration> 8 <!--指向JDBC连接数据库的核心配置文件(4大连接参数)--> 9 <properties resource="database.properties"/> 10 <!--对MyBatis进行全局配置--> 11 <settings> 12 <!--懒加载,全局设置懒加载,默认为true--> 13 <setting name="lazyLoadingEnabled" value="false"/> 14 <!--MyBatis对resultMao的映射级别 FULL为最高级别,PARTIAL为默认级别,NONE为最低--> 15 <setting name="autoMappingBehavior" value="FULL"/> 16 </settings> 17 <!--为实体类做全局的配置—设置别名,在后续的小配置文件中实体类可以直接写别名,在这里是类名为别名--> 18 <typeAliases> 19 <package name="com.cn.entity"/> 20 </typeAliases> 21 <!--这个是MyBatis插件的配置,这里配置的是分页的插件,就是自动在查询语句中添加limit字句--> 22 <plugins> 23 <plugin interceptor="com.github.pagehelper.PageHelper"> 24 <property name="dialect" value="mysql"></property> 25 <property name="rowBoundsWithCount" value="true"/> 26 <property name="resonable" value="false"/> 27 </plugin> 28 </plugins> 29 <!--一下不做解释,有点JDBC基础的都看得懂--> 30 <environments default="development"> 31 <environment id="development"> 32 <transactionManager type="JDBC"></transactionManager> 33 <dataSource type="POOLED"> 34 <property name="driver" value="${driver}"/> 35 <property name="url" value="${url}"/> 36 <property name="username" value="${username}"/> 37 <property name="password" value="${password}"/> 38 </dataSource> 39 </environment> 40 </environments> 41 <!--指向小配置文件,这种配置方式是写配置文件所在包的全包名,使用mapper节点的话就是文件的相对路径url就是绝对路径 42 还要再最前边加上file:///--> 43 <mappers> 44 <!--<mapper resource="com/cmy/mapper/UserMapper.xml"></mapper>--> 45 <!--<mapper url="file:///E:/com/cmy/mapper/UserMapper.xml"></mapper>--> 46 <package name="com.cn.dao"/> 47 </mappers> 48 </configuration>
5、dao接口,操作数据库的方法
1 package com.cn.dao; 2 3 import com.cn.entity.Tplemp; 4 import org.apache.ibatis.annotations.Insert; 5 6 import java.util.List; 7 8 public interface EmpDao { 9 List<Tplemp>getAll(); 10 void delEmp(int id); 11 void addEmp(Tplemp tplemp); 12 void modify(Tplemp tplemp); 13 }
6、小配置文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 <!--根节点不做解释,namespace属性中为接口的全限定类名--> 6 <mapper namespace="com.cn.dao.EmpDao"> 7 <!--结果集查询操作时使用,该节点下的id随意,type为返回值类型--> 8 <resultMap id="empMap" type="Tplemp"> 9 <!--多对一中的一的类型,这个不配的话,MyBatis没法装配,看需要一般是联表查询时使用--> 10 <association property="tbldept" javaType="Tbldept"/> 11 </resultMap> 12 <!--以下操作就是一些增删改的核心了--> 13 <!--id为dao接口中的方法名(必须)resultMap是上边resultMap的id值,如果不需要联表,可以不适用resultMap 14 节点,直接再select标签中使用resultType指定返回值类型,当然,resultMap和resultType不能同时出现--> 15 <select id="getAll" resultMap="empMap"> 16 SELECT * FROM `tplemp` emp INNER JOIN `tbldept` dept ON emp.`depid`=dept.`deptid` 17 </select> 18 <!--id同理,parameterType是方法中入参的类型,#{id}实体类中属性名,#起到预编译的作用如果是$就是拼接sql不推荐--> 19 <delete id="delEmp" parameterType="int"> 20 delete from tplemp where empid=#{id} 21 </delete> 22 <insert id="addEmp" parameterType="Tplemp"> 23 INSERT INTO `tplemp` VALUE(DEFAULT,#{ename},#{egender},#{depid}) 24 </insert> 25 <!--以下是动态SQl,下一章节介绍--> 26 <update id="modify" parameterType="Tplemp"> 27 UPDATE `tplemp` 28 <set> 29 <if test="ename!=null"> 30 ename=#{ename}, 31 </if> 32 <if test="egender!=-1"> 33 egender=#{egender}, 34 </if> 35 <if test="depid!=-1"> 36 depid=#{depid}, 37 </if> 38 </set> 39 where empid=#{empid} 40 </update> 41 </mapper>
7、创建SqlSessionUtil工具类
package com.cn.util; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.InputStream; public class SqlSessionUtil { private static SqlSessionFactory factory; public static SqlSession getSqlSession(){ if (factory==null){ SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); InputStream is = SqlSessionUtil.class.getResourceAsStream("/configuration.xml"); factory=builder.build(is); } return factory.openSession(); } }
8、创建测试类(在这里我使用的是Junit做的测试)
package com.cn.test; import com.cn.dao.EmpDao; import com.cn.dao.EmpDao2; import com.cn.entity.Tplemp; import com.cn.util.SqlSessionUtil; import com.github.pagehelper.PageHelper; import org.apache.ibatis.session.SqlSession; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.List; public class empTest2 { SqlSession session; EmpDao2 dao; @Before public void before(){ session= SqlSessionUtil.getSqlSession();//获取SqlSession dao=session.getMapper(EmpDao2.class);//通过session中的动态代理创建接口的实现类的对象 /*有这个优越的条件我们就不需要写实现类了,统统都交给容器其处理*/ } @Test public void test(){ PageHelper.startPage(1,3,true); /*上一句感兴趣的可以查一下*/ List<Tplemp> all = dao.getAll(); for (Tplemp item:all){ System.out.println(item.getEname()); } } @After public void after(){ session.commit();//提交事务 session.close();//关闭连接 } }
9、执行效果图
执行时需要使用log4j记录日志才能看到MyBatis创建的sql语句
log4j的依赖
1 <dependency> 2 <groupId>log4j</groupId> 3 <artifactId>log4j</artifactId> 4 <version>1.2.16</version> 5 </dependency> 6 <dependency> 7 <groupId>org.slf4j</groupId> 8 <artifactId>slf4j-api</artifactId> 9 <version>1.7.21</version> 10 </dependency> 11 <dependency> 12 <groupId>ch.qos.logback</groupId> 13 <artifactId>logback-core</artifactId> 14 <version>1.2.3</version> 15 </dependency> 16 <dependency> 17 <groupId>ch.qos.logback</groupId> 18 <artifactId>logback-classic</artifactId> 19 <version>1.2.3</version> 20 </dependency>
log4j的配置文件
1 ### direct log messages to stdout 记录日志信息到控制台### 2 log4j.appender.stdout=org.apache.log4j.ConsoleAppender 3 log4j.appender.stdout.Target=System.out 4 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 5 log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n 6 7 ### direct messages to file log.txt 记录日志信息到硬盘上的文件中 ### 8 log4j.appender.file=org.apache.log4j.FileAppender 9 log4j.appender.file.File=e:/log4j/log.txt 10 log4j.appender.file.layout=org.apache.log4j.PatternLayout 11 log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n 12 ### set log levels - for more verbose logging change 'info' to 'debug' ### 13 log4j.logger.dao=debug, stdout,file