什么是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,可以使用第三插件
第三方缓存:性能高、效率高(开发软件常用)