MyBatis的核心对象
SqlSessionFactory是Mybatis框架中十分重要的对象,他是单个数据库映射关系经过编译后的内存镜像,其主要作用是创建SqlSession.SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象来构建。
代码如下:
//定义配置文件
String resource="mybatis-config.xml";
//读取配置文件
Reader reader = Resources.getResourceAsReader(resource);
//构造工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSessionFactory对象线程是安全的,它一旦被创建,在整个应用执行期间都会存在。通常每个数据库都只会对应一个SqlSessionFactory,所以在构建SqlSessionFactory实例时,建议使用单例模式
SqlSessionFactory对象有个openSession()方法也是很重要的,他会返回一个SqlSession,该实例不可共享;
SqlSession,他是应用程序域持久层之间执行交互操作的一个单线程对象,其主要的作用是执行持久化操作。并且SqlSession中还包含了数据库中所有执行SQL操作方法,由于其底层分装了JDBC链接,所以可以直接使用其实例来执行已映射的SQL语句。
SqlSession的两种用法:
一:字符串形式(本人喜欢用第二种)
// 配置文件路径+selectId值 查询值 返回单一对象
SqlSession.selectOne("edu.gdkm.commern.selectByName","张三")
// 配置文件路径+selectId值 查询值 返回集合对象
SqlSession.selectList("edu.gdkm.commern.selectByNames","张");
二:getMapper(class<T> type)的形式
SqlSession session = MybatisUtils.getSession();
//这里有两个文件 一个是CustomerMapper.java接口 一个是CustomerMapper.xml 名字必须一样并且在同一包下
CustomerMapper mapper = session.getMapper(CustomerMapper.class);
/**
这样CustomerMapper的实例对象mapper就可以调用CustomerMapper接口的方法
不过需要注意的是在CustomerMapper接口中有的方法在CustomerMapper.xml文件中也要设置好同样的id,并且返回值与形参 都要保持一致*/
Mybatis的配置文件
在Mybatis核心配置文件中<configuration>元素是配置文件的根元素。
在<configuration>中有
<properties,<settings>,<typeAliases>,<typeHandlers>,<objectFactory>,<plugins>,<environments>,<databaseIdProvider>,<mappers>
其中<environments>中还有子元素<environment>
<environment>的子元素为:<transactionManager>,<dataSource>
需要注意的是configuration的子元素必须按照顺序进行配置,否则Mybatis在解析XML配置文件会出错.<properties>是第一个,<mappers>是最后一个。
<properties>
配置数据库的连接属性,有两种方式 可以将链接方式直接写入Mybatis配置文件,也可以在外面新建一个properties文件。
方式一:
<environments default="mysql8">
<!--1.2.配置id为mysql的数据库环境 -->
<environment id="mysql5">
<!-- 使用JDBC的事务管理 -->
<transactionManager type="JDBC" />
<!--数据库连接池 -->
<dataSource type="POOLED">
<!-- mysql5.7以下 -->
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=GMT%2B8" />
<property name="username" value="654321" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
方式二:
首先在src下新建一个db.properties
db.properties内容展示:
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=false&serverTimezone=GMT%2B8
jdbc.username=654321
jdbc.password=123456
<properties resource="db.properties"/>
<environments default="mysql8">
<environment id="mysql8">
<!-- 使用JDBC的事务管理 -->
<transactionManager type="JDBC" />
<!--数据库连接池 -->
<dataSource type="POOLED">
<!-- mysql8 -->
<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>
<settings>
主要是用于改变MyBatis运行时的行为,例如开启二级缓存,开启延迟加载.以下是把日志打印在控制台的配置案例.
先新建一个log4j.properties文件写好配置内容
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.edg.gdkm=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - [\u65E5\u5FD7\u4FE1\u606F]%m%n
<settings>
<!-- 使用LOG4J日志 -->
<setting name="logImpl" value="LOG4J" />
</settings>
<typeAliases>
给java类型一个简短的名字,即设置别名;
<typeAliases>
// alias属性是别名 type属性是类型
<typeAlias alias="user" type="com.gdkm.fmt.User"/>
//当POJO类过多时,还可以通过自动扫描包的形式自定义别名
<package name="com.gdkm.fmt"/>
</typeAliases>
如果用包形式,Mybatis会将com.gdkm.fmt包中的POJO类以首字母小写的非限定类名来作为它的别名,比如com.gdkm.fmt.User的别名为user,com.gdkm.fmt.Comment的别名为comment等。
需要注意上述的别名只能在没有使用注解的情况下,注解后需要使用注解名;
<typeHandler>
typeHandler的作用就是将预处理语句中传入的参数中从javaType(JAVA类型)转换为jdbcType(JDBC类型),或者从数据库取出结果时将jdbcType转换为javaType.
1.注册一个类的类型处理器
<typeHandlers>
<--以单个类的形式配置 handler指定在程序中自定义的类型处理器-->
<typeHandler handler="com.gdkm.fmt.User">
</typeHandlers>
2.注册一个包的类型处理器
<typeHandlers>
<!--注册一个包中所有的TYPEHANDLER,系统在启动时会自动扫描包下的所有文件-->
<package name="com.gdkm.fmt"/>
</typeHandlers>
<objectFactory>
自定义工厂//后补
<plugins>
plugins的作用就是配置用户所开发的插件。
<environments>
environments元素对于环境进行配置,MyBatis的环境配置实际上就是数据源的配置,我们还可以通过<environments>元素配置多种数据源,即配置多种数据库
案例如下:
<!--1.配置环境 ,默认的环境id为mysql-->
<environments default="mysql8">
<!--1.2.配置id为mysql的数据库环境 -->
<environment id="mysql5">
<!-- 使用JDBC的事务管理 -->
<transactionManager type="JDBC" />
<!--数据库连接池 -->
<dataSource type="POOLED">
<!-- mysql5.7以下 -->
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=GMT%2B8" />
<property name="username" value="654321" />
<property name="password" value="123456" />
</dataSource>
</environment>
<environment id="mysql8">
<!-- 使用JDBC的事务管理 -->
<transactionManager type="JDBC" />
<!--数据库连接池 -->
<dataSource type="POOLED">
<!-- mysql8 -->
<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>
在Mybatis中可以配置两种类型的事务管理器,分别是JDBC和MANAGED.
JDBC:此配置直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的链接来处理事务的作用域。
MANAGED:此配置从来不提交或回滚一个链接,而是让容器来管理事务的整个生命周期。在默认情况下,他会关闭来链接,但一些容器并不希望这样,为此可以将closeConnection属性设置为false来阻止它默认的关闭行为。
如果项目中使用的是Spring+MyBatis,则没有必要在MyBatis中配置事务管理器,因为实际开发中,会使用Spring自带的管理器来实现事务管理。
数据源的配置有UNPOOLED,POOLED,JNDI
<mappers>
<mappers>配置文件用于指定Mybatis映射文件的位置,一般有以下4种方式
1.使用类路径引入
<mappers>
<mapper resource="com/gdlm/fmt/UserMapper.xml">
</mappers>
2.使用本地文件导入
<mappers>
<mapper url="file:///D:/com/gdlm/fmt/UserMapper.xml">
</mappers>
3.使用接口类引入
<mappers>
<mapper class="com.gdkm.fmt.UserMapper">
</mappers>
4.使用包名引用
<mappers>
<mapper package="com.gdkm.fmt">
</mappers>
根据情况选择使用哪种方法,不过无论怎么看都是第四种方便!(本人觉得)
mapper配置文件
有select,insert,update,delete,sql,cache,cache-ref,resultMap
1.<select>查询
<select id="selectS" parameterType="Integer" resultType="edu.gdkm.po.Customer">
select * from t_tbale where id=#{value}
</select>
2.<insert>插入
<insert id="insertByComm" parameterType="edu.gdkm.po.Customer">
insert into t_tbale(name,age,josh) values ("asdsad",16,"123213")
</insert>
3.<updata>修改
<updata id="updByComm" parameterType="edu.gdkm.po.Customer">
修改的sql语句
</updata>
4.sql用于定义一部分SQL,然后可以被其他语句引用此sql
<!--定义sql-->
<sql id="BMK_LIST">
id,name,age,josh
</sql>
<select id="selectByUser" parameterType="edu.gdkm.po.Customer" resultType="edu.gdkm.po.Customer">
select
<!--调用定义好的sql-->
<include refid="BMK_LIST"/>
from t_tbale where id=#{id}
</select>
其中 include 的refid的属性是sql 的id。
5.cache给命名空间的缓存配置
6.cache-ref其他命名空间缓存配置的引用
7.resultMap用于描述如何从数据库结果中来加载对象
resultMap元素表示结果映射集。它的重要作用是定义映射规则,级联的更新已经定义类型转化器等。
<!--resultMap的元素结构-->
<resultMap type="" id="">
<constructor><!--类的实例化时,用来注入结果到构造方法中-->
<idArg/><!--ID参数;标记结果作为id-->
<arg/><!--注入到构造方法的一个普通结果-->
</constructor>
<id/><!--用于表示那个列是主键-->
<result/><!--注入到字段或javaBean属性的普通结果-->
<association property="" /><!--用于一对一关联-->
<collection property="" /><!--用于一对多关联-->
<discriminator javaType=""><!--使用结果值来决定使用哪个结果映射-->
<case value=""/><!--基于某些值的结果映射-->
</discriminator>
</resultMap>
用法:
<resultMap id="BaseResultMap" type="edu.gdkm.po.Customer">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<!-- column里面填写的是表的列名
property里面填写的是调用的时候别名
-->
<result column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="age" jdbcType="INTEGER" property="age" />
<result column="josh" jdbcType="VARCHAR" property="josh" />
</resultMap>
动态SQL
<if>
判断语句,用于单条件判断
<select id="sele">
select * from t_table where 1=1
<if test="username !=null and username!=''">
and username like concat('%',#{username},'%')
</if>
</select>
<choose>(<when>,<otherwise>)
相当于java中的switch....case....default语句,用于多条件分支判断
当一个条件符号要求,其他都不运行!
<select id="sele">
select * from t_table where 1=1
<choose>
<when test="username !=null">
and username like concat('%',#{username},'%')
</when>
<when test="jobs!=null">
and jobs=#{jobs}
</when>
<otherwise>
and phone is not null
</otherwise>
</choose>
</select>
<where>,<trim>,<set>
辅助元素,用于处理一些sql拼装,特殊字符问题
<where>替换掉了where 1=1
<select id="sele">
select * from t_table
<where>
<if test="username !=null">
and username like concat('%',#{username},'%')
</if>
<if test="jobs!=null">
and jobs =#{jobs}
</if>
</where>
</select>
除了where元素外,还可以通过<trim>元素来定制需要的功能
<select id="sele">
select * from t_table
<trim prefix="where" prefixOverrides="and">
<if test="username !=null">
and username like concat('%',#{username},'%')
</if>
<if test="jobs!=null">
and jobs =#{jobs}
</if>
</trim>
</select>
prefix属性代表的是语句的前缀
而prefixOverrides属性代表的是需要去除的那些特殊字符串
<set>
用于更新某条数据,将多余的","删除
<update id="upd">
update t_table
<set>
<if test="username!=null">
username=#{username},
</if>
<if test="username!=null">
password=#{password},
</if>
<if test="username!=null">
number=#{number},
</if>
</set>
where id=#{id}
</update>
<foreach>
循环语句,常用于in语句等列举条件中
<select id="selectByIDList" parameterType="List" resultType="edu.gdkm.po.Customer">
select * from t_tbale where id in
<foreach item="id" index="index" collection="list" open="(" separator="," close=")">
#{id}
</foreach>
</select>
item:配置的是循环中当前的元素
index:配置的是当前元素在集合的位置下标
collection:配置的list是传递过来的参数类型(首字母小写),它可以是一个array,list或collection,map集合的键,pojo包装类中的宿主或集合类型的属性名等。
open和close:配置的是以什么符号将这些元素包装起来
separator:配置的是这个元素的间隔符
调用:
SqlSession session = MybatisUtils.getSession();
CustomerMapper mapper = session.getMapper(CustomerMapper.class);
List<Integer> is=new ArrayList<Integer>();
is.add(1);
is.add(4);
is.add(2);
is.add(3);
List<Customer> cs=mapper.selectByIDList(is);
for (Customer customer : cs) {
System.out.println(customer);
}
session.close();
<bind>
从OGNL表达式中创建一个变量,并将其绑定到上下文,常用于查询到的sql中
为了防止SQL注入
<select id="selectByIDList" parameterType="List" resultType="edu.gdkm.po.Customer">
<bind name="pattern_username" value="'%'+username+'%'"/>
select * from t_tbale
where
username like #{pattern_username}
</select>
mybatis的关系映射