MyBatis框架相关知识点总结与实战

什么是MyBatis?

       MyBatis是一个支持普通SQL查询、存储过程和高级映射的优秀持久层框架。MyBatis除了绝大部分JDBC代码,简化了手工设置SQL参数,以及对结果集的检索进行了封装。MyBatis可以使用简单的XML或注解方式来配置映射,将POJO(普通的Java对象、实体对象)映射成数据库中的记录。

通过配置文件xml获取java和resources中的org.lanqiao中的dao和entity

       在resources下导入4个配置文件:

generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
	<!-- 配置文件路径 -->
	<properties resource="mybatis.properties" />

	<!--数据库驱动包路径 -->
	<classPathEntry location="${drive.class.path}" />

	<context id="MySQLTables" targetRuntime="MyBatis3">
		<!--关闭注释 -->
		<commentGenerator>
			<property name="suppressAllComments" value="true" /><!-- 是否取消注释 -->
			<property name="suppressDate" value="true" /> <!-- 是否生成注释代时间戳 -->
		</commentGenerator>

		<!--数据库连接信息 -->
		<jdbcConnection driverClass="${jdbc.driver}"
			connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}">
		</jdbcConnection>

		<!--生成的model 包路径 -->
		<javaModelGenerator targetPackage="${model.package}"
			targetProject="${target.project.java}">
			<property name="enableSubPackages" value="true" />
			<property name="trimStrings" value="true" />
		</javaModelGenerator>

		<!--生成xml mapper文件 路径 -->
		<sqlMapGenerator targetPackage="${xml.mapper.package}"
			targetProject="${target.project.resources}">
			<property name="enableSubPackages" value="true" />
		</sqlMapGenerator>

		<!-- 生成的Dao接口 的包路径 -->
		<javaClientGenerator type="XMLMAPPER"
			targetPackage="${dao.package}" targetProject="${target.project.java}">
			<property name="enableSubPackages" value="true" />
		</javaClientGenerator>

		<!--对应数据库表名 -->
		<!-- <table tableName="msgboard" domainObjectName="Msg"
			enableCountByExample="false" enableDeleteByExample="false"
			enableSelectByExample="false" enableUpdateByExample="false">
			如果设置为true,生成的entity类会直接使用column本身的名字,而不会再使用驼峰命名方法,比如BORN_DATE_Time,生成的属性名字就是BORN_DATE,而不会是bornDateTime
			<property name="useActualColumnNames" value="true" />
			忽略列,不生成bean 字段
			<ignoreColumn column="FRED" />
			指定列的java数据类型
			<columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" />
		</table> -->
		<!--<table tableName="message" domainObjectName="User"-->
			<!--enableCountByExample="false" enableDeleteByExample="false"-->
			<!--enableSelectByExample="false" enableUpdateByExample="false">-->
			<!--<property name="useActualColumnNames" value="true" />-->
		<!--</table>-->
		<table tableName="teacher" domainObjectName="Teacher"
			enableCountByExample="false" enableDeleteByExample="false"
			enableSelectByExample="false" enableUpdateByExample="false">
			<property name="useActualColumnNames" value="true" />
		</table>
		<table tableName="student" domainObjectName="Student"
			enableCountByExample="false" enableDeleteByExample="false"
			enableSelectByExample="false" enableUpdateByExample="false">
			<property name="useActualColumnNames" value="true" />
		</table>
		<table tableName="classes" domainObjectName="Classes"
			   enableCountByExample="false" enableDeleteByExample="false"
			   enableSelectByExample="false" enableUpdateByExample="false">
			<property name="useActualColumnNames" value="true" />
		</table>
	</context>
</generatorConfiguration>

log4j.properties

log4j.rootLogger=DEBUG,stdout
### console ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
#log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
 
### mybatis ###
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=ERROR
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

mybatis.properties    注意要改url的地址,  java和resources的路径,在目录上右键copy path。

# jdbc
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=123

#dbcp 
initialSize=0   
maxActive=10  
maxIdle=10   
minIdle=1  
maxWait=60000 

#mybatis generator
drive.class.path=D:/maven/.m2/repository/mysql/mysql-connector-java/5.1.19/mysql-connector-java-5.1.19.jar
model.package=org.lanqiao.entity
dao.package=org.lanqiao.dao
xml.mapper.package=org.lanqiao.dao
target.project.java=D:/myBatis/src/main/java
target.project.resources=D:/myBatis/src/main/resources

mybatis-Config.xml

设置了下面这段代码就不需要在type里面写全称了:

<typeAliases>
   <package name="org.lanqiao.entity"/>
   <package name="org.lanqiao.dao"/>
</typeAliases>

设置了下面这段代码是为了延迟加载用的

<settings>
   <setting name="logImpl" value="LOG4J"/>
   <!--懒加载设置-->
   <setting name="lazyLoadingEnabled" value="true"/>
   <!--侵入懒加载,设置为false则按需加载,否则会全部加载-->
   <setting name="aggressiveLazyLoading" value="false"/>
</settings>
<?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>
	<!-- 引用mybatis.properties配置文件 -->
	<properties resource="mybatis.properties" />

	<settings>
		<setting name="logImpl" value="LOG4J"/>
		<!--懒加载设置-->
		<setting name="lazyLoadingEnabled" value="true"/>
		<!--侵入懒加载,设置为false则按需加载,否则会全部加载-->
		<setting name="aggressiveLazyLoading" value="false"/>
	</settings>
	<typeAliases>
		<package name="org.lanqiao.entity"/>
		<package name="org.lanqiao.dao"/>
	</typeAliases>
    <!--<settings>  -->
        <!--<setting name="logImpl" value="LOG4J" />    -->
    <!--</settings> -->
	<!-- development : 开发模式 work : 工作模式 -->
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<!-- 配置数据库连接信息 -->
			<dataSource type="POOLED">
				<!-- value属性值引用db.properties配置文件中配置的值 -->
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	<!-- 映射文件 -->
	<mappers>
		<!--<mapper resource="org/lanqiao/dao/UserMapper.xml" />-->
        <mapper resource="org/lanqiao/dao/ClassesMapper.xml" />
        <mapper resource="org/lanqiao/dao/StudentMapper.xml" />
        <mapper resource="org/lanqiao/dao/TeacherMapper.xml" />
	</mappers>
</configuration>

设置完这些配置文件后,就配置好tomcat然后在tomcat上再设置好maven,在配置maven的时候要在第二行输入命令:

mybatis-generator:generate -e

再点击一下OK,然后启动,MyBatis逆向工程就会生成。

得到了文件以后生成目录如下:

java

     org.lanqiao

               dao

                     ClassesMapper

                     StudentMapper

                     TeacherMapper

               entity

                     Classes

                     Student

                     Teacher

resources

     org.lanqiao.dao

                     ClassesMapper.xml

                     StudentMapper.xml

                     TeacherMapper.xml

    generatorConfig.xml
    log4j.properties
    mybatis.properties
    mybatis-Config.xml             

MyBatis的3大部分总结:关联映射、延迟加载、缓存。

一、关联映射:目的是查询数据

步骤:1、修改实体类(对象)

        2、手动在映射文件中添加resultMap(告知过程)

        3、在select中写sql语句来查询

一对一:唯一属性

一对多:一方添加多方的集合为属性:Set

多对一:多方修改外界为一方为对象。

多对多:关系表

结果集列名:AS  别名(所见即所得)

resultMap下定义:一个对象:association

                              多个对象:collection

注意:1、resultMap中的个数=查询结果集

           2、column表示查询结果集的别名,不是表中列名

案例:一对多的案例:一个班级里有多个学生

1、在Classes的实体类中添加

private Set<Student> students;

     并且右键点击Generate生成get和set方法

public Set<Student> getStudents(){
         return students;
    }

    public void setStudents(Set<Student> students){
        this.students=students;
    }

2、在ClassesMapper.xml手动添加resultMap和select中的sql语句

<resultMap id="ClassesResultMap" type="org.lanqiao.entity.Classes" >
    <id column="cid" property="cid" jdbcType="INTEGER" />
    <result column="className" property="className" jdbcType="VARCHAR" />
    <!--<association property="teacher" javaType="org.lanqiao.entity.Teacher">-->
      <!--<result column="name" property="name" jdbcType="VARCHAR" />-->
    <!--</association>-->
    <collection property="students" ofType="org.lanqiao.entity.Student">
      <result column="name" property="name"/>
    </collection>
  </resultMap>
<select id="getClasses" resultMap="ClassesResultMap" parameterType="java.lang.Integer">
    select c.cid,c.className,s.name from classes c,student s where s.classId=c.cid and c.cid=#{cid};
  </select>

3、在ClassesMapper中添加getClasses方法

Classes getClasses(Integer cid);

4、编写测试类:

package org.lanqiao.dao;
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 org.junit.Before;
import org.junit.Test;
import org.lanqiao.entity.Classes;
import org.lanqiao.entity.Student;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;

public class OneToManyTest {
    @Test
    public void beforeLoadXML(){
        SqlSessionFactory sqlSessionFactory;
        Reader reader;
        SqlSession session=null;
        try{
            //加载MyBatis的配置文件
            reader = Resources.getResourceAsReader("mybatis-Config.xml");
            //构建SqlSession的工厂
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            //创建能执行SQL映射文件中SQL语句的SQLSession对象
            session = sqlSessionFactory.openSession();
            ClassesMapper classesMapper = session.getMapper(ClassesMapper.class);


            //一对多嵌套结果方式:根据班级id插叙班级所有学生的信息
            Classes classes=classesMapper.getClasses(1);
            System.out.println(classes.getClassName());
            for(Student student:classes.getStudents()){
                System.out.println(student.getName());
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(session!=null){
                session.close();
            }

        }
    }
}

运行结果后会出现一个班级和多个学生。

二、延迟加载

和非延迟加载的区别是:在多了个settings设置

作用:1、子查询

           2、默认执行第一条select

步骤:1、实体类不变

           2、手动在映射文件中添加ResultMap

           3、写sql语句来查询,有两句。第二个是sql中的是#{ _ }相等于第一句的 _ =...

           4、写测试类

案例:

1、在maven的pom.xml中导入cglib包,目前使用率最高的是3.2.4版本

<dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>3.2.4</version>
</dependency>

2、在mybatis-Config.xml中设置settings再在resultMap中添加fetchType=“egar”

<resultMap id="ClassesStuResultMap" type="Classes">
    <id column="cid" property="cid" jdbcType="INTEGER"/>
    <result column="className" property="className" jdbcType="VARCHAR"/>
    <collection property="students" column="cid" select="selectStudentById" fetchType="eager">
    </collection>
  </resultMap>

3、在ClassesMapper.xml中写select中的sql语句

<select id="selectClassesById" resultMap="ClassesStuResultMap">
    select * from classes where cid=#{id}
  </select>
  <select id="selectStudentById" resultType="Student">
    select * from student where classId=#{cid}
  </select>

4、然后写测试类

package org.lanqiao.dao;

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 org.junit.Test;
import org.lanqiao.entity.Classes;
import org.lanqiao.entity.Student;

import java.io.Reader;

public class DelayLoadTest {
    @Test
    public void beforeLoadXML(){
        SqlSessionFactory sqlSessionFactory;
        Reader reader;
        SqlSession session=null;
        try{
            //加载MyBatis的配置文件
            reader = Resources.getResourceAsReader("mybatis-Config.xml");
            //构建SqlSession的工厂
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            //创建能执行SQL映射文件中SQL语句的SQLSession对象
            session = sqlSessionFactory.openSession();
            ClassesMapper classesMapper = session.getMapper(ClassesMapper.class);


            //延迟加载
            Classes classes=classesMapper.selectClassesById(1);
            System.out.println(classes.getClassName());
            for(Student student:classes.getStudents()){
                System.out.println(student.getName());
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(session!=null){
                session.close();
            }

        }
    }
}

结果是延迟生成一个班级和多个学生

三、缓存:有限制,根据命中率来清楚缓存,使用次数少的清除

一级缓存:默认打开的,存在session中,不能关,关闭就会使用不了

二级缓存:默认不开启。映射文件加一个catch,存在硬盘中,可以关闭session,可以使用第三插件

第三方缓存:性能高、效率高(开发软件常用)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值