一、整体架构
数据源配置文件+SQL映射配置文件+会话工厂
+会话+执行器+底层封装对象
1、数据源配置文件
SqlMapConfig.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-->
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/firstdatabase?characterEncoding=utf-8"></property>
<property name="username" value="root"></property>
<property name="password" value=""></property>
</properties>
<!--配置环境-->
<environments default="mysql">
<!-- 配置mysql的环境-->
<environment id="mysql">
<!-- 配置事务 -->
<transactionManager type="JDBC"></transactionManager>
<!--配置连接池-->
<dataSource type="POOLED">
<property name="driver" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
</dataSource>
</environment>
</environments>
<!-- 注册类型处理器的位置 -->
</configuration>
2、SQL映射配置文件
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指定了命名空间-->
<mapper namespace="test">
<!--验证用户登录-->
<select id="findUserById" parameterType="int" resultType="cn.com.mybatis.po.User">
SELECT * FROM course WHERE course_id=#{id}
</select>
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.com.mybatis.po.User">
select * from course where course_name like '%${value}%'
</select>
<insert id="insertUser" parameterType="cn.com.mybatis.User">
insert into user(course_id,course_name,credit)
value(#{course_id},#{course_name),#{credit})
</insert>
<delete id="deleteUser" parameterType="cn.com.mybatis.User">
delete from course where course_id=#{id}
</delete>
<update id="updateUsername" parameterType="cn.com.mybatis.User">
update course set course_name=#{course_name} where course_id=#{course_id}
</update>
</mapper>
select标签对中包含了SQL语句,其中的parameterType指定了输入参数的类型,resultType指定了输出结果映射的java对象类型(这里是一个JavaBean封装类),结果参数配置表示将单条记录映射成一个Java对象。Mapper.xml的文件路径一般会配置在数据源配置文件SqlMapConfig.xml中,随着数据库配置参数一起被加载。
<!-- 配置映射文件的位置 -->
<mappers>
<mapper resource="sqlmap/UserMapper.xml"></mapper>
</mappers>
3、会话工厂与会话
读取加载配置文件。
会话工厂:SqlSessionFactory类(该类会根据Resources资源信息加载对象,获取开发人员配置的数据库连接池配置文件SqlMapConfig.xml的信息,从而产生一种可以和数据库交互的会话实例类)
二、MyBatis运行流程
首先会话工厂通过Resource资源信息加载对象获取SqlMapConfig.xml配置文件信息,然后产生可以和数据库交互的会话实例类SqlSession。SqlSession可以根据Mapper配置文件中的SQL配置去执行相应的增删查改操作。而在SqlSession类内部,是通过执行器Executor(分为基本执行器和缓存执行器)对数据库进行操作的。执行器和数据库交互,依靠的是底层封装对象(Mappered Statement,它封装了从Mapper文件中读取的信息(包括SQL语句、输入参数、输出结果类型)。通过执行器和底层封装对象的结合,就实现了与数据库进行交互的功能。
三、编写日志输出环境配置文件
log4j.rootLogger = debug,stdout
#日志输出级别
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
#设置输出端载体类型为控制台
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
#输出载体的界面布局类型
log4j.appender.stdout.layout.ConversionPattern = %5p [%t] - %m%n
#指定打印信息的具体格式
四、创建和配置
编写数据库连接池配置文件
编写SQL映射配置文件
编写实体类
编写数据库交互类
编写测试类
关于parameterType:执行SQL配置时,需要指定输入参数的类型。使用parameterType可以指定参数为基本数据类型、包装数据类型以及用户自己编写的JavaBean封装类。
关于“#{}”:在SQL配置文件中,输入参数需要占位符来标识对应的位置。该符号接受输入参数,在大括号中编写参数名称来接受对应参数。
关于${}:拼接SQL语句.如模糊查询.
关于selectOne和selectList:在加载SQL映射文件中的某个SQL配置时,可以调用SqlSession类提供的方法.多条数据用"selectList"查.
在properties标签中引入的配置文件信息以及property子标签中配置的信息,在其他标签中可以使用占位符的方式来获取.
setting 配置常常用来实现缓存,延迟加载和分页设置.
tapeAliases配置分析:通过设置全局配置文件
SqlMapConfig中的typeAliases属性就可以为SQL映射文件的输入输出参数设置类型别名,然后在SQL映射配置文件中指定输入输出参数类型时使用别名.配置:
<typeAliases>
<typeAlias alias="user" type="cn.com.mybatis.po.User"/>
<typeAlias alias="str" type="java.lang.String"/>
</typeAliases>
一般会将JavaBean类型的封装放置在一个包下面,一个一个配置别名很繁琐,MyBatis提供了批定义别名的方法,指定包名即可.定义别名的规范就是对应包装类的类名首字母变为小写.
<typeAliases>
<package name="cn.com.mybatis.po">
</typeAliases>
别名也可以使用注解来实现:
@Alias("user")
public class User{
...
}
typeHandlers:类型处理器,将从数据库获取的值以合适的方式转换为Java类型,或者将Java类型的参数转换为数据库对应的类型.
使用typeHandlers标签配置一个自己的类型处理器:
1.编写类型处理器类
2.在MyBatis全局配置文件中配置该类型处理器
3.在SQL映射配置文件中使用
objectFactory:对象工厂,是用来创建实体对象的类.在MyBatis中,默认的对象工厂要做的就是实例化查询结果对应的目标类,一种是通过目标类的默认构造方法,一种是通过目标类的有参构造方法.
改写默认的对象工厂,可以继承DefaultObjectFactory来创建自己的对象工厂.
plugin:对某种方法进行拦截调用的机制.使用场景由:日志记录,权限控制,缓存控制.
environments:放置有关数据库连接数据的配置标签,所有与外部数据库进行交互的数据都配置在该标签中.在environments标签中可以配置多个数据库连接环境,以便SQL语句可以适用于多个数据库环境.
在environments中可以配置一个个单独的environment,他们代表多个数据库环境的配置信息.每一个都包含事务管理器transactionManager和数据源DataSource信息.
事务管理器有两种类型:JDBC和MANAGED.配置为JDBC相当于直接使用JDBC提交和回滚设置,配置为MANAGED则不提交和回滚,而是由容器来管理事物的生命周期
数据源有三种:UNPOOLED(设置每次请求时打开和关闭连接),POOLED(设置一个管理数据库连接的资源池,用来合理控制数据库的连接和关闭次数),JNDI(配置连接外部数据源信息).
Mappers:配置需要加载的SQL映射配置文件的路径的.配置方式有四种:
1.相对路径:
<mappers>
<mapper resource="org/mybatis/mappers/UserMapper.xml"/>
</mappers>
2.绝对路径
<mappers>
<mapper url="file:///var/mappers/UserMapper.xml"/>
</mappers>
3.使用接口信息
<mappers>
<mapper class="org.mybatis.mappers.UserMapper"/>
</mappers>
4.使用接口所在包
<mappers>
<package name="org.mybatis.mappers"/>
</mappers>
Mapper自动映射:有三种模式:NONE(不启用),PARTIAL(只对非嵌套的resultMap进行自动映射),FULL(对所有的resultMap进行自动映射).默认为PARTIAL.
<setting name="autoMappingBehavior" value="PARTIAL"/>
resultMap映射:
一对一
一对多:association和collocation,一个映射单一实体对象,一个映射集合对象.(p90)
多对多(p92)
延迟加载:可以做到做到先从单表查询,需要时再从关联表关联查询.善用延迟加载可以大大提高系统查询效率.
<!--延迟加载的 resultMap-->
<resultMap id="BatchUserLazyLoadingResultMap" type="cn.com.mybatis.po.BatchItem">
<-- 对订单信息进行映射配置-->
<id column="batch_ id" property ="batch_id" />
<result column="cus_id" property="cus_id" />
<result column="number" property="number" />
<result column="create_time" property=”"create_time" javaType="java.util.Date" />
<result column="note" property="note" />
<!--实现延迟加载用户信息-->
<association property="customer" javaType="cn.com mybat.po.Customer"
select="findCustomerById" column="cus_id" >
</association>
</resultMap>
<select id="findCustomerByid" parameterType="int" result Type="cn.com.mybatis.po.Customer">
SELECT * FROM CUSTOMER WHERE cus id=#{id}
</select>
使用 select 和column 延迟加载用户信息。select 用来
指定延迟加载所需要执行的 SQL 语句,也就是指定 Mapper.xml 置文件中的某个 select 标签对的
id.column 是指订单信息中关联用户信息查询的列,这里关联的是用户的主键,即cus_id.
在编写测试方法之前,首先开启延迟加载功能。这需要在 MyBatis 的全局配置文件
SqlMapConfig.xml 配置 件中配 setting 属性,将延迟 载( lazyLoadingEnable )的开关设置成
true ”。
<configuration>
<!--其他配置-->
< !-- settings-->
<settings>
<!--打开延迟加载的开关-->
<setting name="lazyLoadingEnable" value="true" />
<!--将积极加载改为消极加载,即按需加载-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<!--其他配置 -->
</configuration>
五、MyBatis缓存结构
一级缓存:SqlSession级别的缓存.在操作数据库时,每个SqlSession类的实例对象中有一个数据结构(HashMap)可以用于存储缓存数据,不同的SqlSession类的实例对象缓存的数据区域时互不影响的.
工作原理:
二级缓存:Mapper级别的缓存,多个SqlSession类的实例对象操作同一个Mapper配置文件中的SQL语句,多个SqlSession类的实例对象可以共用二级缓存,二级缓存是跨SqlSession的.
运行原理:
二级缓存比一级缓存范围大.一个Mapper有一个自己的二级缓存区域(按照namespace划分),两个Mapper的namespace如果相同,那么这两个Mapper执行的SQL查询会被缓存在同一个二级缓存中.
开启二级缓存:
1.在MyBatis的全局配置文件中配置setting属性,设置名为"cacheEnabled"的属性值为"true".
<setting name="cacheEnabled" value="true"/>
2.在需要开启的二级缓存的具体Mapper.xml中开启二级缓存.
<!--开启本Mapper的namespace下的二级缓存-->
<cache/>
六、Spring+MyBatis
1.建工程
2.导jar包(MyBatis的包,Spring的包,MyBatis和Spring的整合包)
3.编写Spring配置文件applicationContext.xml
加载数据库连接文件中的数据,建立数据源,配置sqlSessionFactory会话工厂对象.
<!--加载配置文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!--数据源,使用DBCP-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!--指定连接池的最大数据库连接数-->
<property name="maxActive" value="${jdbc.maxActive }"/>
<!--指定连接池中最大等待的数量-->
<property name="maxidle" value="${jdbc.maxidle }"/>
</bean>
<!--sqlSession-->
<bean id="sqlSesionFactory" class="org.mybatis.spring.SqlSessionFactory">
<!--注入两个参数:全局配置文件和数据源-->
<!--加载MyBatis的配置文件-->
<property name="configLocation" value="mybatis/SqlMapConfig.xml"/>
<!--数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
context:property-placeholder 用于读取工程中的静态属性文件,然后在其他配置中使用时就可以采用"${属性名}"方式获取该属性文件中的配置参数值.
4.编写MyBatis配置文件SqlMapSession.xml
<?xml version 1. encoding =” UTF ”?〉
<! DOCTYPE configuration
PUBLIC ”-//mybatis.org//DTD Config 3 . 0//EN”
http //mybatis org/dtd/mybat config dtd
<configuration>
<!-- settings-->
<settings>
<!--打开延迟加载的开关-->
<setting name="lazyLoadingEnable" value="true" />
<!--将积极加载改为消极加载,即按需加载-->
<setting name="aggressiveLazyLoading" value="false"/>
<! 打开全局缓存开关( 级缓存)默认值就是 true--〉
<setting name="cacheEnabled" value="true" />
</settings>
<!--别名定义-->
<typeAliases>
<package name="cn.com.sm.po"/>
</typeAliases>
<!--加载映射文件-->
<mappers>
<!--通过 resource 方法一次加载一个映射文件-->
<mapper resource="sqlmap/UserMapper.xml"/>
<--批量加载mapper-->
<package name="cn.com.sm.mapper" />
</mappers>
</configuration>
5.编写Mapper及其他配置文件
<?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指定了命名空间-->
<mapper namespace="test">
<!--验证用户登录-->
<select id="findUserById" parameterType="int" resultType="user">
SELECT * FROM course WHERE course_id=#{id}
</select>
</mapper>
创建Java实体类User:
package cn.com.sm.po;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable{
private int id;
private String username;
private String password;
private String gender;
private String email;
private String province;
private String city;
private Date birthday;
//get set 方法省略
}
数据库资源文件db.properties:
jdbc.driver=org.git.mm.mysql.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis_test?characterEncoding=utf-8
jdbc.username=root
jdbc.password=l234
6.编写Dao层
创建接口
创建接口实现类
Dao的实现类继承了SqlSessionDaoSupport父类后就无需自己定义获取SqlSession会话实例类的方法了,该父类会默认加载数据源信息并提供获取SqlSession类的方法.
7.测试.
8.使用Mapper代理
在Spring的全局配置文件中添加Spring的Mapper扫描器:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.com.sm.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
Mapper 扫描配置对象需要的参数是要扫描的包的路径和 sqlSessionFactory 对象,这些都可以使用注入的方式设置。
Mapper 配置文件要和 Mapper代理接口位于一个包下,且名称一样.创建 UserQueryMapper.xml 配置文件,其中配置以 查询用户的 SQL 配置,而namespace 为即将要创建的 Mapper 代理对象接口的路径.
<?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="cn.com.sm .mapper.UserQueryMapper">
<select id="findUserByid" parameterType ="int" resultType="user"/>
SELECT * FROM USER WHERE id=#{id}
</select>
</mapper>
package cn.com.sm.mapper;
import cn.com.sm.po.User;
public interface UserQueryMapper {
//根据 id 查询用户信息
public User findUserById (int id) throws Exception;
}
测试:
private ApplicationContext applicationContext;
//首先获取Spring配置文件对象
@Before
public void setup() throws Exception{
applicationContext=new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
}
public void tesrFindUserById() throws Exception{
UserQueryMapper userQueryMapper=(UserQueryMapper)applicationContext.getBean("userQueryMapper");
User user=userQueryMapper.findUserById(1);
System,out.println(user.getId()+user.getUsername());
}
七、MyBatis逆向工程
可以针对数据库中的表单自动生成MyBatis执行所需要的代码(包括Java实体类,Mapper映射配置及Mapper代理接口).
待补…