Java SE MyBatis框架(详解)

Java SE MyBatis框架

目录

通用框架

1.lib

 导包

2、src

2.1、mybatis.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--dtd约束: 核心配置文件中内容的定义-->
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--根节点-->
<configuration>

    <!-- 加载外部的properties文件 -->
    <properties resource="DateBase.properties" />
    <!-- settings标签 -->
    <settings>
        <!-- 设置MyBatis使用log4j日志支持 -->
        <setting name="logImpl" value="LOG4J"/>
    </settings>

    <typeAliases>
            <!--<typeAlias type="com.xxxx.pojo.Dept" alias="dept"/>-->  <!--不区分大小写-->
            <!--<typeAlias type="com.xxxx.pojo.Dept"/> --> <!--默认类型别名为类名,不区分大小写-->

        <package name="mybatis.week.pojo"/> <!-- 包下所有的类默认类名 -->
<!--    <package name="mybatis.week2.pojo"/>-->
    </typeAliases>

    <!--环境的配置
            default : 选择当前要使用的环境->不同环境的id-->
    <environments default="dev">
        <!--环境的定义 id : 当前环境的唯一标识 -->
        <environment id="dev">
        <!--transactionManager : 事务管理器
                    type : 当前mybatis使用哪种事务管理机制
                        JDBC : 与JDBC相同的事务管理方式 -->
            <transactionManager type="JDBC"/>
            <!--
                dataSource: 数据库连接参数的配置|连接池
                type : 是否使用数据库连接池
                POOLED : 使用连接池技术
            -->
            <dataSource type="POOLED">
                <!--property : 连接参数选项的配置-->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--SQL映射文件的加载配置: -->
    <mappers>
        <!--resource : sql映射文件的路径-->
<!--        <mapper resource="mybatis/week/mapper/DeptMapper.xml"/>-->

        <!--指定接口绑定方案中的接口: 接口的权限定名: 包名.接口名-->
<!--        <mapper class="mybatis.week.mapper.StudentMapper0"/>-->
        <!--配置指定包下的所有接口-->
        <package name="mybatis.week.mapper"/>

       <!-- <mapper resource="mybatis/week2/mapper/StudentMapper.xml"/>-->
    </mappers>

</configuration>
2.2、DateBase.properties
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:ORCL
username=SCOTT
password=TIGER
2.3、log4j.properties
# Set root category priority to INFO and its only appender to CONSOLE.
#additivity="false"
log4j.rootCategory=ERROR,CONSOLE
log4j.logger.mybatis.week.mapper=DEBUG
# log4j.rootCategory=INFO, CONSOLE, LOGFILE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=- %m%n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:/test.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=- %m %l%n
2.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>
  <!--数据库驱动 --> 
  <context id="Tables" targetRuntime="MyBatis3"> 
  	<!-- 生成的Java文件的编码 -->
  	<property name="javaFileEncoding" value="UTF-8" /> 
  	<!-- JavaBean 实现 序列化 接口 --> 
  	<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/> 
  	<commentGenerator>
      	<property name="suppressDate" value="true" />
      	<!-- 是否去除自动生成的注释 true:是 : false:否 --> 
      	<property name="suppressAllComments" value="false" />
  	</commentGenerator> 
  	<!--数据库链接地址账号密码 -->
  	<jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver" 		
       connectionURL="jdbc:oracle:thin:@localhost:1521:xe" userId="SCOTT" password="TIGER"> 
    </jdbcConnection> 
    <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true 时把 JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal -->
    <javaTypeResolver>
      <property name="forceBigDecimals" value="false" /> 
    </javaTypeResolver>
    <!--生成 Model 类存放位置 --> 
    <javaModelGenerator targetPackage="com.xxxx.pojo" targetProject="mybatis12\src"> 
      <property name="enableSubPackages" value="true" /> 
      <property name="trimStrings" value="true" /> 
    </javaModelGenerator> <!--生成映射文件存放位置 --> 
    <sqlMapGenerator targetPackage="com.xxxx.mappers" targetProject="mybatis12\src"> 
      <property name="enableSubPackages" value="true" /> 
    </sqlMapGenerator> <!--生成接口类存放位置(Dao|Mapper) --> 
    <javaClientGenerator type="XMLMAPPER" targetPackage="com.xxxx.mappers" targetProject="mybatis12\src"> 
      <property name="enableSubPackages" value="true" /> 
    </javaClientGenerator> <!-- 参考数据库中需要生成的对应表信息 --> 
    <table tableName="dept" domainObjectName="Dept" 
           enableCountByExample="false" enableUpdateByExample="false" 
           enableDeleteByExample="false" enableSelectByExample="false" 
           selectByExampleQueryId="false">
    </table> 
    <table tableName="emp" domainObjectName="Emp" 
           enableCountByExample="false" enableUpdateByExample="false" 
           enableDeleteByExample="false" enableSelectByExample="false" 
           selectByExampleQueryId="false">
    </table> 
  </context> 
</generatorConfiguration>
2.5、mapper包

 SQL映射文件(mapper).xml

 所对应的mapper.xml的接口文件

2.6、pojo包

 Javabean文件

2.7、utils包

 封装工具类

1、框架介绍

  MyBatis 本是apache的一个开源项目iBatis,后迁移到了 google code,并且改名为MyBatis 。2013年11月迁移到Github。

   iBATIS是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO) MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。

  MyBatis消除了几乎所有的 JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和 原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。

  Mybatis不是一个完全的orm框架,Mybatis需要程序员自己写sql,但是也存在映射(输入参数映射,输 出结果映射),学习门槛mybatis比hibernate低;同时灵活性高,特别适用于业务模型易变的项目,使 用范围广。

简单概括:

  更加简化jdbc代码简化持久层sql语句从代码中分离,利用反射,将表中数据与java bean 属性一一 映射 即 ORM(Object Relational Mapping 对象关系映射)

使用范围:

  在日常的开发项目中,如中小型项目,例如ERP,需求与关系模型相对固定建议使用Hibernate,对于需 求不固定的项目,比如:互联网项目,建议使用mybatis,因为需要经常灵活去编写sql语句。总之, mybatis成为当下必须学习掌握的一个持久层框架。

2、Mybatis特点

属于持久层ORM框架

1.持久层: 讲内存中对象数据,转移到数据库中的过程持久层

​   Mybatis ;Hibernate; Spring-jpa

2、ORM Object Relational Mapping 对象关系映射框架

  • 类—》 表
  • 属性—》 字段
  • 对象—》 记录

3、半自化 自动化

  • Mybatis 半自动化

    • 表需要手动进行设计
    • 提供sql
    • 表需要手动进行设计提供sql
    • 依赖与数据库平台
    • 优点:学习使用简单(基与原声jdbc封装),优化灵活,适合做互联网项目
  • Hibernate 自动化ORM框架

    • 表可以通过框架自动创建省略一些基本的sql
    • 不依赖与数据库平台
    • 缺点: 学生成本高,优化难度大,适合与传统框(OA|图书管理系统…),不适合做大型互联网项目

My Batis功能架构图:

Mybatis架构图

3、Mybatis环境搭建

官网: https://mybatis.org/mybatis-3/zh/index.html

3.1、新建Java项目

  新建Java项目,导入核心java包与mybatis依赖jar包

3.2、导入jar包

jar包

  选中所有的jar包,右键build path->add to build path 管理外部的jar资源

3.3、Mybatis配置文件

mybatis提供两种配置文件:

  • 核心配置文件 mybatis-config.xmlmybatis.xml
  • SQL映射文件mapper.xml

  核心配置文件是一个xml文件,命名无要求,位置无要求,一般成为mybatis.xml,放在src路径下

3.3.1、dtd
  • \1. 解压mybatis核心jar包,找到本地dtd文件
  • \2. ide工具中关联mybatis配置文件的dtd约束
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
3.3.2、mybatis.xml文件配置内容:

硬解码:

<?xml version="1.0" encoding="UTF-8" ?>
<!--dtd约束: 核心配置文件中内容的定义-->
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--根节点-->
<configuration>

    <!-- settings标签 -->
    <settings>
        <!-- 设置MyBatis使用log4j日志支持 -->
        <setting name="logImpl" value="LOG4J"/>
    </settings>

    <typeAliases>
            <!--<typeAlias type="com.xxxx.pojo.Dept" alias="dept"/>-->  <!--不区分大小写-->
            <!--<typeAlias type="com.xxxx.pojo.Dept"/> --> <!--默认类型别名为类名,不区分大小写-->
            <package name="mybatis.week.pojo"/> <!-- 包下所有的类默认类名 -->
            <package name="mybatis.week2.pojo"/>
    </typeAliases>


    <!--
        环境的配置
            default : 选择当前要使用的环境->不同环境的id
    -->
    <environments default="dev">
        <!--环境的定义 id : 当前环境的唯一标识 -->
        <environment id="dev">
            <!--
                transactionManager : 事务管理器
                    type : 当前mybatis使用哪种事务管理机制
                        JDBC : 与JDBC相同的事务管理方式
            -->
            <transactionManager type="JDBC"/>
            <!--
                dataSource: 数据库连接参数的配置|连接池
                type : 是否使用数据库连接池
                POOLED : 使用连接池技术
            -->
            <dataSource type="POOLED">
                <!--
                    property : 连接参数选项的配置
                -->
                <property name="driver" value="oracle.jdbc.driver.OracleDriver"/> 
                <property name="url" value="jdbc:oracle:thin:@localhost:1521:XE"/> 
                <property name="username" value="SCOTT"/> 
                <property name="password" value="TIGER"/>
            </dataSource>
        </environment>
    </environments>

    <!--SQL映射文件的加载配置: -->
    <mappers>
        <!--resource : sql映射文件的路径-->
        <mapper resource="mybatis/week/mapper/DeptMapper.xml"/>
        <mapper resource="mybatis/week/mapper/DeptMapper2.xml"/>
        <mapper resource="mybatis/week/mapper/EmpMapper.xml"/>


        <mapper resource="mybatis/week2/mapper/StudentMapper.xml"/>
    </mappers>
</configuration>
3.3.2.2、通过properties标签实现软编码

src下定义配置文件db.properties

driver=oracle.jdbc.driver.OracleDriver 
url=jdbc:oracle:thin:@localhost:1521:XE 
username=SCOTT 
password=TIGER

  mybatis核心配置文件中添加properties标签,指定加载外部的properties文件,注意定义位置

<!-- 加载外部的properties文件 --> 
<properties resource="db.properties" />

 获取properties文件中数据时候,要通过${}的方式获取

ironments default="even"> 
	<environment id="even"> 
		<transactionManager type="JDBC"></transactionManager>
			<dataSource type="POOLED"> 
				<property name="driver" value="${driver}"/> 
				<property name="url" value="${url}"/> 
				<property name="username" value="${username}"/>
				<property name="password" value="${password}"/> 
			</dataSource>
		</environment> 
	</environments>

s

3.3.3、 SQL映射文件 mapper.xml

  在Mybatis中,推荐使用mappers作为包名,我们只需要写一个映射配置文件就可以,Mapper.xml,用于定义要执行的sql语句,同时可以设置参数|返回值结果类型。

注意:不要忘记mybatis核心xml文件中的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="com.xxxx.mappers.UserMapper">
  <!--查询标签: select 用于编写查询语句 
  		id : 当前文件中保证唯一 
  		resultType : 结果的类型 
  		parameterType : 入参类型 
  --> 
  <select id="queryAll" resultType="com.xxxx.pojo.User"> 
  		select * from t_user 
  </select> 
</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">
        <!--
         namespace : 命名空间
                在当前项目下,namespace的值是唯一的,不能重复的,SQL映射文件的唯一标识
                定义:
                    1.任意定义,不重复,唯一即可
                    2.建议: 包名.文件名 (不加后缀名) ->推荐
        -->
<mapper namespace="mybatis.week.mapper.DeptMapper">
    <!--
    select标签: 定义查询sql语句 ->Statement
                id : 在当前命名空间中,不能存在2个标签的id属性值相同,标签的唯一标识
                resultType : 结果类型
                    引用数据类型: 类型的权限定名  包名.类名
                    集合: 泛型类型
                parameterType : 入参类型
                    基本数据类型|包装类 javabean 数组,list,map
    -->
    <select id="queryAll" resultType="Dept">
        SELECT * FROM DEPT
    </select>
    <!--根据部门编号查询部门信息-->
    <select id="queryDeptToNo" parameterType="int" resultType="Dept">
        SELECT DEPTNO,DNAME,LOC FROM DEPT WHERE DEPTNO = #{DEPTNO}
    </select>

</mapper>
3.4、测试
public class TestUser { 
		public static void main(String[] args) throws IOException { 
				//1.加载mybatis全局核心配置文件 
				InputStream is = Resources.getResourceAsStream("mybatis.xml"); 
				//2.构建SqlSessionFactory对象 
      	SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); 
				//3.通过工厂获取会话
				SqlSession SqlSession session = factory.openSession(); 
				//4.通过session调用方法执行查询 
				//selectList() 查到的数据返回一个list集合,没查到返回空的list 
				//selectList 的第一个参数为statement: 命名空间+id 
				List<User> list = session.selectList("com.xxxx.mappers.UserMapper.queryAll"); 						System.out.println(list); 
				//5.关闭会话资源 
				session.close(); } }
import mybatis.week.pojo.Dept;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.*;
import org.apache.log4j.lf5.util.Resource;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.util.*;

public class DeptCode01 {
    public static void main(String[] args) throws IOException {
        //加载执行核心配置文件
        InputStream ips =Resources.getResourceAsStream("mybatis.xml");

        //2.构建SqlSessionFactory
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(ips);

        //3根据工厂获取回话
        SqlSession session=factory.openSession();

        //4、执行指定的sql
        //selectList("命名空间.id")
        List<Dept> list =session.selectList("mybatis.week.mapper.DeptMapper.queryAll");

        //根据部门 编号查询部门信息
        //selectOne("命名空间.id")
        //selectOne("命名空间.id",入参)
        Dept dept=session.selectOne("mybatis.week.mapper.DeptMapper.queryDeptToNo",10);

        //selectMap("命名空间.id","作为key的字段名")
        //selectMap("命名空间.id",入参,"作为key的字段名")
        Map<Integer,Dept> map=session.selectMap("mybatis.week.mapper.DeptMapper.queryAll","deptno");

        //5.处理数据
        list.forEach(System.out::println);
        System.out.println("___________________");
        System.out.println(dept);
        System.out.println("____________________");
        System.out.println(map);

        //6.关闭回话
        session.close();

    }
}

4、Mybatis配置文件详解

4.1、Mybatis.xml核心配置文件

1、configuration

​    配置文件的根元素,所有其他的元素都要在这个标签下使用(dtd文件规定)

2、environments default="environment"

​   用于管理所有环境, 并可以指定默认使用那个环境,通过defualt属性来指定

3、environment

  ​ 用来配置环境,id属性用于唯一标识当前环境

4、transactionManager type="JDBC"

​   用户配置事务管理器

 type属性

  • ​ 用来指定Mybatis采用何种方式管理事务

  • ​ JDBC : 表示采用与原生JDBC一致方式管理事务

  • ​ MANAGED: 表示讲事务管理交给其他容器进行, Spring

5、dataSource type="POOLED"

​    用于配置数据源, 设置Myabtis是否使用连接池技术,并且配置数据库的四个连接参数

type属性:

  • ​ POOLED : 表示采用连接池技术

  • ​ UNPOOLED: 表示每次都会开启和关闭连接, 不采用连接池技术

  • ​ JNDI : 使用其他容器提供数据源

6、property

​   用于配置数据库连接参数 (driver,url,username,password)

7、Mappers

  ​ 用于配置扫描sql映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!--dtd约束: 核心配置文件中内容的定义-->
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--根节点-->
<configuration>

    <!-- 加载外部的properties文件 -->
    <properties resource="DateBase.properties" />
    <!-- settings标签 -->
    <settings>
        <!-- 设置MyBatis使用log4j日志支持 -->
        <setting name="logImpl" value="LOG4J"/>
    </settings>

    <typeAliases>
            <!--<typeAlias type="com.xxxx.pojo.Dept" alias="dept"/>-->  <!--不区分大小写-->
            <!--<typeAlias type="com.xxxx.pojo.Dept"/> --> <!--默认类型别名为类名,不区分大小写-->

        <package name="mybatis.week.pojo"/> <!-- 包下所有的类默认类名 -->
<!--    <package name="mybatis.week2.pojo"/>-->
    </typeAliases>


    <!--
        环境的配置
            default : 选择当前要使用的环境->不同环境的id
    -->
    <environments default="dev">
        <!--环境的定义 id : 当前环境的唯一标识 -->

        <environment id="dev">
        <!--
                transactionManager : 事务管理器
                    type : 当前mybatis使用哪种事务管理机制
                        JDBC : 与JDBC相同的事务管理方式
            -->
            <transactionManager type="JDBC"/>

            <!--
                dataSource: 数据库连接参数的配置|连接池
                type : 是否使用数据库连接池
                POOLED : 使用连接池技术
            -->
            <dataSource type="POOLED">
                <!--
                    property : 连接参数选项的配置
                -->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--SQL映射文件的加载配置: -->

    <mappers>
        <!--resource : sql映射文件的路径-->
<!--        <mapper resource="mybatis/week/mapper/DeptMapper.xml"/>-->

        <!--指定接口绑定方案中的接口: 接口的权限定名: 包名.接口名-->
<!--        <mapper class="mybatis.week.mapper.StudentMapper0"/>-->
        <!--配置指定包下的所有接口-->
        <package name="mybatis.week.mapper"/>

       <!-- <mapper resource="mybatis/week2/mapper/StudentMapper.xml"/>-->
    </mappers>

</configuration>

4.2、SQL映射文件(mapper)

  MyBatis 的真正强大在于它的映射语句,也是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好。

  SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序):

  resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。

  • insert – 映射插入语句
  • update – 映射更新语句
  • delete – 映射删除语句
  • select – 映射查询语句

查询语句是 MyBatis 中最常用的元素之一(映射文件配置见代码)

1、mapper

SQL映射文件的根元素

namespace 属性:

  • 用于指定命名空间, 通过namespace+id的方式用来定位sql语句

  • namespace的值是唯一的,SQL映射文件的唯一标识

  • 定义:
    1.任意定义,不重复,唯一即可
    2.建议: 包名.文件名 (不加后缀名) ->推荐

<mapper namespace="mybatis.week.mapper.DeptMapper">
2.select

用来定义查询语句 update insert delete

  • id 属性
  • 用阿里唯一表示当前sql语句,在当前的命名空间中唯一,不能重复 , 类型方法名resultType 属性
  • 用于设定查询返回的结果的数据类型,要写类型的权限定名(包名+类名),如果返回值的是集合类型,要定义集合的泛型类型
<?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">
        <!--
         namespace : 命名空间
                在当前项目下,namespace的值是唯一的,不能重复的,SQL映射文件的唯一标识
                定义:
                    1.任意定义,不重复,唯一即可
                    2.建议: 包名.文件名 (不加后缀名) ->推荐
        -->
<mapper namespace="mybatis.week.mapper.DeptMapper">

    <!--
    select标签: 定义查询sql语句 ->Statement
                id : 在当前命名空间中,不能存在2个标签的id属性值相同,标签的唯一标识
                resultType : 结果类型
                    引用数据类型: 类型的权限定名  包名.类名
                    集合: 泛型类型
                parameterType : 入参类型
                    基本数据类型|包装类 javabean 数组,list,map
    -->
    <select id="queryAll" resultType="Dept">
        SELECT * FROM DEPT
    </select>
    <!--根据部门编号查询部门信息-->
    <select id="queryDeptToNo" parameterType="int" resultType="Dept">
        SELECT DEPTNO,DNAME,LOC FROM DEPT WHERE DEPTNO = #{DEPTNO}
    </select>

</mapper>
2.1、三个查询方法
  • selectList(“命名空间.id”) 用户查询多条数据情况,返回一个List集合, 没有查到数据返回空集合,不是null
  • selectOne(“命名空间.id”) 用于查询单条数据,返回一个数据, 如果没有查到返回null
  • selectMap(“命名空间.id”,key的字段名) 用于查询多条记录情况, 返回Map集合, 需要指定那个属性作为key, sql查询结果作为value,指定的字段值作为key, 如果查不到, 返回一个空map集合,不是null
 //加载执行核心配置文件
        InputStream ips =Resources.getResourceAsStream("mybatis.xml");

        //2.构建SqlSessionFactory
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(ips);

        //3根据工厂获取回话
        SqlSession session=factory.openSession();

        //4、执行指定的sql
        //selectList("命名空间.id")
        List<Dept> list =session.selectList("mybatis.week.mapper.DeptMapper.queryAll");

        //根据部门 编号查询部门信息
        //selectOne("命名空间.id")
        //selectOne("命名空间.id",入参)
        Dept dept=session.selectOne("mybatis.week.mapper.DeptMapper.queryDeptToNo",10);

        //selectMap("命名空间.id","作为key的字段名")
        //selectMap("命名空间.id",入参,"作为key的字段名")
        Map<Integer,Dept> map=session.selectMap("mybatis.week.mapper.DeptMapper.queryAll","deptno");

        //5.处理数据
        list.forEach(System.out::println);
        System.out.println("___________________");
        System.out.println(dept);
        System.out.println("____________________");
        System.out.println(map);

        //6.关闭回话
        session.close();

3、insert – 映射插入语句
4、update – 映射更新语句
5、delete – 映射删除语句

增删改需要提交事务,session.commit();

mapper.xml

<!-- 测试增删改 : 结果返回的都是影响函数int -->
    <!-- 新增 -->
    <insert id="insertStudent" parameterType="student">
        insert into student values(#{arg0},#{arg1},#{arg2},#{arg3},#{arg4})
    </insert>
    <!-- 修改 -->
    <update id="updateStudent" parameterType="student">
        update student set sage = #{param1} where sno =#{param2}
    </update>
    <!-- 删除 -->
    <delete id="deleteStudent" parameterType="_int">
        delete from student where sno = #{arg0}
    </delete>

test.java

 			//1.获取会话
        SqlSession session= BatisUtils.getSession();
        //2.获取接口的实现类对象
        StudentMapper0 mapper = session.getMapper(StudentMapper0.class);
        //3.调用方法
        //添加信息
        int rows=0;
        //rows =mapper.insertStudent(10001,"张三","男",22,"数学系");

        System.out.println("-------------------------------------------------------");

        //修改信息
        //rows=mapper.updateStudent(20,1000);

        System.out.println("-------------------------------------------------------");

        //删除数据
       /* rows=mapper.deleteStudent(1000);

        if (rows>0){
            System.out.println("成功");
        }else{
            System.out.println("失败");
        }*/

5、Log4j日志

日志是应用软件中不可缺少的部分,Apache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录。

5.1、 日志级别

分为五个级别:

  • DEBUG(人为调试信息)
  • INFO(普通信息)
  • WARN(警告)
  • ERROR(错误)
  • FATAL(系统错误)

  这五个级别是有顺序的,DEBUG < INFO < WARN < ERROR < FATAL,分别用来指定这条日志信息的重要程度。

  Log4j有一个规则:只输出级别不低于设定级别的日志信息,假设Loggers级别设定为INFO,则INFO、WARN、ERROR和FATAL级别的日志信息都会输出,而级别比INFO低的DEBUG则不会输出。

5.2、使用

导包,

在Mybatis.xml中< properties >后添加t

<!-- settings标签 --> 
<settings> <!-- 设置MyBatis使用log4j日志支持 --> 
		<setting name="logImpl" value="LOG4J"/> 
</settings>
5.2.1、配置文件

  可以使用properties或者xml进行配置,使用一个叫 log4j.properties 的配置文件, 会设定 log4j的设置信息, 例如日志级别, 日志输出方式, 日志格式等等

# Set root category priority to INFO and its only appender to CONSOLE. 
log4j.rootCategory=INFO, CONSOLE 
# log4j.rootCategory=INFO, CONSOLE, LOGFILE 

# CONSOLE is set to be a ConsoleAppender using a PatternLayout. 
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender 
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout 
log4j.appender.CONSOLE.layout.ConversionPattern=- %m %c %l %d{yyyy-MMdd HH:mm:ss}%n 

# LOGFILE is set to be a File appender using a PatternLayout. 
log4j.appender.LOGFILE=org.apache.log4j.FileAppender log4j.appender.LOGFILE.File=d:/test.log 
log4j.appender.LOGFILE.Append=true log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout 
log4j.appender.LOGFILE.layout.ConversionPattern=- %m %l%n

局部调整:

# 提高整体日志级别 
log4j.rootCategory=ERROR, CONSOLE 
# 单独设置SQL语句的输出级别为DEBUG级别 
# 方法级别 
# log4j.logger.com.xxxx.mapper.UserMapper.selAll=DEBUG 
# 类级别
# log4j.logger.com.xxxx.mapper.UserMapper=DEBUG 
# 包级别 
log4j.logger.com.xxxx.mapper=DEBUG

5.3、常见日志输出格式

参数描述实例
c <>输出Logger所在的类别(即Logger的名字)。允许使用%c{数字}输出部分的名字(从右边往左边数)。见实例%c将输出com.log4j.Log4jTest %c{1}将输出Log4jTest %c{2}将输出log4j.Log4jTest %c{3}将输出com.log4j.Log4jTest
a输出日期。允许使用%d{yyyy-MM- dd HH:mm:ss}格式化日期。%d不仅支持JDKSimpleDateFormat的日期格式,还支持log4j自己的日期格式,例如ABSOLUTE,DATE,ISO8601等%d将输出2013-06-06 22:24:25,353 %d{yyyy-MM- dd}将输出2013-06-06 %d{ABSOLUTE}将输出22:24:25,353 %d{DATE}将输出06六月201322:24:25,253
F输出所在的类文件名称%F将输出Log4jTest.java
l输出语句所在的行数,包括类名,方法名,文件名,行数等%l将输出com.log4j.test.Log4jTest.main(Log4jTest.java:50)
L输出语句所在的行数,只输出数字%L将输出 50
m输出日志输出日志,即log.info(“”),log.debug(“”)参数
M输出方法名%M将输出main
n换行.Windows下输出\r\n,Linux下输出\n含行
p输出日志级别(prioriry)DEBUG,INFO,ERROR,FITAL等
r输出从程序启动到输出该日志之间的时间间隔,单位毫秒%r将输出300
t输出当前的线程名称%t将输出main,Thread-0,Thread-1等
%%%用来输出百分号

6、typeAliases标签—Mybatis核心文件下

用于给java类型定义别名,方便在配置文件中使用

6.1、使用方式

6.1.1、给类定义别名

<!--mybatis.xml下-->
<typeAliases> 
	<typeAlias type="com.xxxx.pojo.User" alias="u"/> 
</typeAliases> 

6.1.2、 省略alias属性,表示类别名为类名,大小写不敏感

<!--mybatis.xml下-->
<typeAliases> 
	<typeAlias type="com.xxxx.pojo.User"/> alias属性不写,默认类名,不区分大小写 
</typeAliases> 

6.1.3、可以通过package标签给整个包下的所有类定义别名,别名为类名

<!--mybatis.xml下-->
<typeAliases> 
		<package name="com.xxxx.pojo"/> <!-- 包下所有的类默认类名 --> 
</typeAliases> 

6.2. Mybatis的内建别名

下面是一些为常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。

<!-- mapper.xml 下-->
<select id="queryAll" resultType="u"> 
		select id,uname,upwd,birthday from t_user 
</select> 
<select id="queryById" resultType="User"> 
		select id,uname,upwd,birthday from t_user where id=125 
</select>
别名映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
decimalBigDecimal
bigdecimalBigDecimal
objectObject
mapMap
hashmapHashMap
listList
arraylistArrayList
collectionCollection
iteratorIterator

7、parameterType入参类型—mapper.xml

如果执行的是条件查询,DML,需要在调用方法的时候传递参数,此时, 可以在sql标签中通过parameterType属性指定参数的类型(别名|权限定名). 而在sql语句,通过#{}的方式获取参数

7.1、一个入参

<!--mapper.xml-->
<!--根据部门编号查询部门信息-->
    <select id="queryDeptToNo" parameterType="int" resultType="Dept">
        SELECT DEPTNO,DNAME,LOC FROM DEPT WHERE DEPTNO = #{DEPTNO}
    </select>
//test.java
//selectOne("命名空间.id",入参)
Dept dept=session.selectOne("mybatis.week.mapper.DeptMapper.queryDeptToNo",10);

7.2、多个参数查询

  多个参数传递时, 由于sqlSession中提供的查询方法,只允许传递一个sql参数, 因此可以对多个参数进行封装,可以对象,集合,数

<!--mapper.xml-->
<!--Javabean 根据部门编号,部门名称 来查询部门名称-->
    <select id="queryDeptToDept" parameterType="dept" resultType="Dept">
                select * from dept where deptno = #{deptno} and dname= #{dname} /*占位符的名字匹配入参对象的同名属性值*/
        </select>

    <!--数组 根据部门编号,来查询部门名称-->
    <select id="queryDeptToDname" resultType="string">
                    select dname from dept where deptno in (
                     /*遍历集合|数组,获取到每一个数据,拼接到sql当前位置()中*/
                   <foreach collection="array" item="item" separator=",">  #{item}  </foreach>
                    )
    </select>
/**test.java
*/
//对象 查询30编号,sales部门的
        dept=session.selectOne("mybatis.week.mapper.DeptMapper2.queryDeptToDept",new Dept(30,"SALES",null));
        System.out.println(dept);

        System.out.println("___________________");
        //数组 查询多个部门
        List<String> str=session.selectList("mybatis.week.mapper.DeptMapper2.queryDeptToDname",new int[]{10,20});
        str.forEach(System.out::println);

7.3、入参类型

入参类型:
    基本数据类型|包装类 
    String Javabean 
    Date 数组 
    List Map

7.3.1、基本数据类型|包装类

<!-- 入参类型: 基本数据类型int|Integer -->
<!-- 根据用户id查询用户信息 --> 
<select id="queryById" resultType="string" parameterType="int"> 
   SELECT * FROM emp WHERE empno = #{empno}
</select>
/* 参数基本数据类型 int->Integer 
* 根据id查询用户名 第二个参数为sql传递的参数 
*/
String name=session.selectOne("com.xxxx.mapper.UserMapper.queryById", 126); 
System.out.println(name);
7.3.3. JavaBean
<!--Javabean 根据部门编号,部门名称 来查询部门名称-->
<select id="queryDeptToDept" parameterType="dept" resultType="Dept">
            select * from dept where deptno = #{deptno} and dname= #{dname} /*占位符的名字匹配入参对象的同名属性值*/
    </select>
//对象 查询30编号,sales部门的
        dept=session.selectOne("mybatis.week.mapper.DeptMapper2.queryDeptToDept",new Dept(30,"SALES",null));
        System.out.println(dept);
7.3.4. Map
<!--Map: 根据部门名称或者部门位置查询部门信息-->
    <select id="queryDeptByMap" parameterType="map" resultType="Dept">
        select * from dept where dname = #{dname} or loc = #{loc} 
      /*站位符的名字匹配map集合中兼职对的key值*/
    </select>
 //Map
        Map<String,Object>  map = new HashMap<>();
        map.put("dname","OPERATIONS");
        map.put("loc","boss办公室");
        List<Dept> list = session.selectList("mybatis.week.mapper.DeptMapper2.queryDeptByMap",map);
        list.forEach(System.out::println);

9、工具类的封装 utils

package com.xxxx.utils; 
import java.io.IOException; 
import org.apache.ibatis.io.Resources; 
import org.apache.ibatis.session.SqlSession; 
import org.apache.ibatis.session.SqlSessionFactory; 
import org.apache.ibatis.session.SqlSessionFactoryBuilder; 
public class MybatisUtils { 
private static SqlSessionFactory factory = null; 
  static { 
    try {
      factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis.xml")); 
    } catch (IOException e) { 
      e.printStackTrace(); 
    } 
  }
  /** 返回一个会话 */ 
  public static SqlSession getSession() { 
    SqlSession session =null; 
    if(factory!=null) { 
      //session = factory.openSession();
      //默认手动提交事务 
      session = factory.openSession(true); //自动提交 
    }
    return session; 
  }
  
}

10、事务

  • 事务是数据库操作的最小单位,有着ACID的特性,应该保证一个事务下的多条SQL语句要么都成功,要么都失败.
  • Mybatis中配置了事务管理器,type属性设置JDBC,表示Mybatis采用和原生JDBC相同的事务管理机制
  • 在Myabatis执行操作的开始,将自动提交功能关闭了,需要我们在执行DML操作时候,手动提交设置|设置自动提交

手动提交:

session.commit(); //事务提交
session.rollback(); //事务回滚

自动提交:

public static SqlSession getSession() { 
		SqlSession session =null; 
		if(factory!=null) { 
				//session = factory.openSession(); //默认手动提交事务 
				session = factory.openSession(true); //自动提交 
		}
		return session; 
}

11、接口绑定方案

  Myabtis中,提供了一套接口绑定方案,程序员可以提供一个接口,然后提供一个与接口所对应的mapper.xml文件

  Myabaits会自动讲接口与xml文件进行绑定,实际上就是Mybatis互根据接口和对应的xml文件创建一个接口的实现类,换言之,就是可以得到接口类型的一个对象,方便方法的调用

11.1、实现方式

11.1.1、定义接口
/** 接口 定义了对用户的操作 */ 
public interface UserMapper { 
  //查询所有用户 
  public List<User> queryAll(); 
}
11.1.2、映射文件

注意:

  • \1. xml文件名要与接口名保持一致
  • \2. namespace属性值 必须与接口的权限定名
  • \3. id属性必须与抽象方法名保持一致
  • \4. 返回值类型和参数类型与方法的返回值和参数保持一致
<?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">
		<!--namespace: 对应的接口的权限定名相同 --> 
		<mapper namespace ="com.xxxx.mapper.UserMapper">
      
      <!-- id 与 方法名一致 -->
      <select id="queryAll" resultType="User"> 
        select * from t_user 
      </select> 
</mapper>

11.1.3、在核心配置文件中扫描接口

  1. 扫描单个接口,可以使用mapper标签的class属性
<!-- mapper 配置扫描接口 --> 
<mappers>
		<mapper class="com.xxxx.mapper.UserMapper"/> 
				<!--配置某个接口 --> 
		</mappers>

2) 扫描多个接口,可以简化配置,使用package标签,表示扫描对应包下的所有接口

<!-- mapper 配置扫描接口 --> 
<mappers> 
	<package name="com.xxxx.mapper"/> 
</mappers>

11.1.4、使用

  在使用时,通过SqlSession的getMapper() 方法,返回接口代理对象,从而调用以实现的抽象方法

/** 测试接口绑定 */ 
@Test 
public void test(){ 
		SqlSession session = MybatisUtils.getSession(); 
  //getMapper()获取接口实现类对象,参数为接口的class对象,通过参数指定接口 
  UserMapper mapper =session.getMapper(UserMapper.class); 
  //通过对象调用方法 
  List<User> list = mapper.queryAll(); 
  System.out.println(list); 
  session.close(); 
}
  1. 1、通过接口绑定解决多参数传递问题

方式一

 a)接口中定义方法

User selByUP(String username, String password); 

 b) 映射文件中提供对应的标签. 此时, SQL 语句中获取方式有两种, 通过#{arg+数字}或#{param+数字}的方式.

<select id="selByUP" resultType="user"> 

select * from t_user where username=#{param1} and password=#{param2} 

</select> 

方式二

  a) 接口中定义方法, 参数中使用@Param 注解设定参数名用于在 SQL 语句中使用.

User selByUP(@Param("username") String username, @Param("password") String password);

  b) 映射文件中提供对应的标签. 此时, SQL 语句中获取方式有两种, 通过#{参数名称}或#{param+数字}的方式.

<select id="selByUP" resultType="user"> 
		select * from t_user where username=#{username} and 
		password=#{password} 
</select>

11.2、接口代理开发CRUD

  1. 基本CRUD操作
<mapper namespace="com.xxxx.mappers.UserMapper"> 
  <select id="queryUserByNamePwd" resultType="User"> 
    select * from t_user where username=#{name} or userpwd = #{pwd} 
  </select> 
  
  <!-- 新增用户 --> 
  <insert id="addUser"> 
    INSERT INTO T_USER VALUES(seq_user_id.nextval,#{param1},#{param2}) 
  </insert>
  
  <!-- 修改用户 --> 
  <update id="updateUser" parameterType="User"> 
    update t_user set username=#{username},userpwd=#{userpwd} where id=#{id} 
  </update> 
  
  <!-- 删除用户 --> 
  <delete id="deleteUser" parameterType="int"> 
    delete from t_user where id=#{id} 
  </delete> 
</mapper>
//测试接口绑定方案crud 
public interface UserMapper { 
  //查询所有用于信息 
  public List<User> queryUserByNamePwd(@Param("name") String name,@Param("pwd") int pwd); 
  
  //新增用户 
  public int addUser(String name,int pwd); 
  
  //修改用户信息 
  public int updateUser(User user); 
  
  //删除用户 
  public int deleteUser(int id); 
}
/** 接口实现crud */ 
public class UserTest { 
@Test 
public void testDelete() { 
SqlSession session = MybatisUtils.getSession(); 
  UserMapper userMapper = session.getMapper(UserMapper.class); 
  int rows = userMapper.deleteUser(202);
  if(rows>0) { 
    System.out.println("成功"); 
  }else { 
    System.out.println("失败"); 
  }
  session.close(); 
}
  @Test 
  public void testUpdate() { 
    SqlSession session = MybatisUtils.getSession(); 
    UserMapper userMapper = session.getMapper(UserMapper.class); 
    int rows = userMapper.updateUser(new User(201,"张三丰",1111)); 
    if(rows>0) { 
      System.out.println("成功"); 
    }else { 
      System.out.println("失败"); 
    }
    session.close(); 
  }
  
  @Test 
  public void testInsert() { 
    SqlSession session = MybatisUtils.getSession(); 
    UserMapper userMapper = session.getMapper(UserMapper.class); 
    int rows = userMapper.addUser("林更新", 45678); 
    if(rows>0) { 
      System.out.println("成功"); 
    }else { 
      System.out.println("失败"); 
    }
    session.close(); 
  }
  @Test 
  public void testSelect() { 
    SqlSession session = MybatisUtils.getSession(); 
    UserMapper userMapper = session.getMapper(UserMapper.class); 
    List<User> list = userMapper.queryUserByNamePwd("胡歌", 789); 
    System.out.println(list); 
    session.close(); 
  } 
}
11.2.3、批量操作
<mapper namespace="com.xxxx.mappers.UserMapper2"> 
  <!-- 批量插入 --> 
  <insert id="addUserSome" parameterType="list"> 
    insert into tb_user(id, username, userpwd) select seq_user_id.nextval, uname, upwd from ( 
    <foreach collection="list" item="item" separator="union" > select #{item.username} uname, #{item.userpwd} upwd from dual 
    </foreach> ) 
  </insert> 
  
  <!-- 批量删除 --> 
  <delete id="deleteSomeUser" parameterType="list"> 
    delete from tb_user where id in( 
    <foreach collection="list" item="item" separator=","> #{item} </foreach> ) 
  </delete> 
  
  <!-- 批量更新 --> 
  <update id="updateSomeUser" parameterType="list"> 
    <foreach collection="list" item="item" open="begin" close=";end;" separator=";">update tb_user set userpwd = #{item.userpwd} where id = #{item.id} 
    </foreach> 
  </update> 
</mapper>
//测试批量操作 
public interface UserMapper2 { 
  //批量新增用户 
  public int addUserSome(List<User> user); 
  //批量删除 
  public int deleteSomeUser(List<Integer> id); 
  //批量更新 
  public int updateSomeUser(List<User> list); 
}
public class UserTest2 { 
  @Test 
  public void testUpdateSome() { 
    SqlSession session = MybatisUtils.getSession(); 
    UserMapper2 userMapper = session.getMapper(UserMapper2.class); 
    List<User> list = new ArrayList(); 
    list.add(new User(218,"蓝精灵",88)); 
    list.add(new User(219,"粉精灵",99)); 
    list.add(new User(220,"紫精灵",00)); 
    int rows = userMapper.updateSomeUser(list);
		System.out.println(rows); session.close(); 
  }
  @Test 
  public void testDeleteSome() { 
    SqlSession session = MybatisUtils.getSession(); 
    UserMapper2 userMapper = session.getMapper(UserMapper2.class); 
    List<Integer> list = new ArrayList(); 
    list.add(208); list.add(209); 
    int rows = userMapper.deleteSomeUser(list); 
    if(rows>0) { 
      System.out.println("成功"); 
    }else { 
      System.out.println("失败"); 
    }
    session.close(); 
  }
  @Test 
  public void testInsertSome() { 
    SqlSession session = MybatisUtils.getSession(); 
    UserMapper2 userMapper = session.getMapper(UserMapper2.class); 
    List<User> list = new ArrayList(); 
    list.add(new User(1,"蓝精灵",5)); 
    list.add(new User(2,"粉精灵",6)); 
    list.add(new User(1,"紫精灵",7)); 
    int rows = userMapper.addUserSome(list); 
    if(rows>0) { 
      System.out.println("成功"); 
    }else { 
      System.out.println("失败"); 
    }
    session.close(); 
  } 
}

12、动态SQL

  动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

  使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

12.1、if

  用于进行条件判断, test 属性用于指定判断条件. 为了拼接条件, 在 SQL 语句后强行添加 1=1 的恒成立条件

<select id="sel" resultType="user"> 
  select * from t_user where 1=1 
  <if test="username != null and username != ''"> 
    and username=#{username} </if>
  <if test="password != null and password != ''"> 
    and password=#{password} </if> 
</select>

12.2、where

where ->帮助SQL语句提供where关键字
    如果where标签中存在条件满足,拼接where关键字
    如果没有条件满足,就不拼接where关键字
    帮助把 第一个多余的and去掉
<select id="queryIdNmToStu" resultType="Student">
        select <include refid="allField" /> from student /*where 1=1*/
        <where>
            <if test="sno!=0 and sno!=null" >
                and sno=#{sno}
            </if>
            <if test="sname!=null and sname!=''">
                and sname=#{sname}
            </if>
        </where>
    </select>

12.3、choose…when…otherwise

这是一套标签, 功能类似于 switch…case…

<select id="sel" resultType="user"> 
  select * from t_user 
  <where> 
    <choose> 
      <when test="username != null and username != ''"> 
        and username = #{username} 
      </when> 
      <when test="password != null and password != ''">
        and password = #{password} 
      </when> 
      <otherwise>
        and 1=1 
      </otherwise> 
    </choose> 
  </where> 
</select>

12.4、set

用于维护 update 语句中的 set 子句. 功能如下:

  • \1. 满足条件时, 会自动添加 set 关键字
  • \2. 会去除 set 子句中多余的逗号
  • \3. 不满足条件时, 不会生成 set 关键字
<update id="updUser" parameterType="user"> 
  update t_user 
  <set>id=#{id},<!-- 防止所有条件不成立时的语法错误 --> 
  	<if test="username != null and username != ''"> 
    	username=#{username}, 
  	</if> 
  	<if test="password != null and password != ''"> 
   	 password=#{password}, 
  	</if> 
  	</set> 
 	 where id=#{id} 
</update>

12.5、trim

用于在前后添加或删除一些内容

  • \1. prefix, 在前面添加内容
  • \2. prefixOverrides, 从前面去除内容
  • \3. suffix, 向后面添加内容
  • \4. suffixOverrides, 从后面去除内容
<update id="updUser" parameterType="user"> 
  update t_user 
  <!-- prefix: 前缀, 表示向前面添加内容 prefixOverrides: 从前面删除内容 suffix: 后缀, 表示向后面添加内容 suffixOverrides: 从后面删除内容 -->
  <trim prefix="set" prefixOverrides="user" suffix="hahaha" suffixOverrides=","> 
    username=#{username}, 
  </trim>
  where id=#{id} 
</update>

12.6、bind

用于对数据进行再加工, 用于模糊查询

<select id="sel" resultType="user"> 
  select * from t_user 
  <where> 
    <if test="username!=null and username!=''"> 
      <bind name="username" value="'%' + username + '%'" /> 
      and username like #{username} 
    </if> 
  </where> 
</select>

12.7、foreach

用于在 SQL 语句中遍历集合参数, 在 in 查询中使用

  • \1. collection: 待遍历的集合
  • \2. open: 设置开始符号
  • \3. item: 迭代变量
  • \4. separator: 项目分隔符
  • \5. close: 设置结束符
List<User> selIn(@Param("list") List<Integer> list);
<select id="selIn" parameterType="list" resultType="user"> 
  select * from t_user where id in 
  <foreach collection="list" open="(" separator="," close=")" item="item"> #{item} </foreach> </select>

12.8、sql…include

sql用于提取 SQL 语句, include用于引用 SQL 语句

<sql id="mySql"> id, username, password </sql>
<select id="selIn" parameterType="list" resultType="user"> 
  select <include refid="mySql" /> from t_user where id in 
  <foreach collection="list" open="(" separator="," close=")" item="item"> #{item} </foreach> </select>

13、Mybatis缓存机制

  缓存的重要性是不言而喻的。 使用缓存, 我们可以避免频繁的与数据库进行交互, 尤其是在查询越多、缓存命中率越高的情况下, 使用缓存对性能的提高更明显。

  mybatis 也提供了对缓存的支持, 分为一级缓存和二级缓存。 但是在默认的情况下, 只开启一级缓存。

13.1、一级缓存

  • \1. 默认开启. 线程级别的缓存, SqlSession 的缓存;
  • \2. 在一个 SqlSession 生命周期中有效. SqlSession 关闭,缓存清空;
  • \3. 在同一个 SqlSession 中, Mybatis 会把执行的方法和参数通过算法生成缓存的键值, 将键值和结果存放在一个 Map 中, 如果后续的键值一样, 则直接从 Map 中获取数据;
  • \4. 不同的 SqlSession 之间的缓存是相互隔离的;
  • \5. 用一个 SqlSession, 可以通过配置使得在查询前清空缓存;flushCache=“true”
  • \6. 任何的 UPDATE, INSERT, DELETE 语句都会清空缓存。

13.2、二级缓存

  • \1. 进程级别的缓存, SqlSessionFactory 的缓存
  • \2. 在一个SqlSessionFactory生命周期中有效. 可以在多个SqlSession 生命中期中共享.
  • \3. 默认关闭, 需要使用的时候, 要为某个命名空间开启二级缓存(在 mapper.xml 中配置cache).
  • \4. 由于在更新时会刷新缓存, 因此需要注意使用场合:查询频率很高, 更新频率很低时使用, 即经常使用 select, 相对较少使用delete, insert, update。
  • \5. 缓存是以 namespace 为单位的,不同 namespace 下的操作互不影响。但刷新缓存是刷新整个namespace 的缓存, 也就是你 update 了一个, 则整个缓存都刷新了。
  • \6. 最好在 「只有单表操作」 的表的 namespace 使用缓存, 而且对该表的操作都在这个 namespace中。 否则可能会出现数据不一致的情况

二级缓存应用场景:

  对于访问多的查询请求并且用户对查询结果实时性要求不高的情况下,可采用mybatis二级缓存,降低数据库访问量,提高访问速度,如电话账单查询根据需求设置相应的flushInterval:刷新间隔时间,比如三十分钟,24小时等。。

14、关系映射

数据库中表与表之间的关系:

  • 一对一 (人->身份证)
  • 一对多 (夏令营->学生)
  • 多对一 (学生->班级)
  • 多对多 (学生->课程)

14.1、 resultMap的关联方式实现多表查询(一对一|多对一)

  • \1. 在 StudentMapper.xml 中定义多表连接查询 SQL 语句, 一次性查到需要的所有数据, 包括对应班级的信息.
  • \2. 通过resultMap标签定义映射关系, 并通过association标签指定对象属性的映射关系. 可以把association标签看成一个resultMap标签使用. javaType 属性表示当前对象, 可以写全限定路径或别名.

学生类中添加一个班级类型的属性 :

public class Student implements Serializable{ 
  private int id; 
  private String name; 
  private int age; 
  private String gender; 
  private int cid; 
  private Clazz cls; 
}

StudentMapper:

<resultMap type="student" id="smap"> 
  <id property="id" column="sid" /> 
  <result property="name" column="sname" /> 
  <result property="age" column="age" /> 
  <result property="gender" column="gender" /> 
  <result property="cid" column="cid" /> 
  <association property="cls" javaType="clazz"> 
    <id property="id" column="cid" /> 
    <result property="name" column="cname" /> 
    <result property="room" column="room" /> 
  </association> 
</resultMap> 

<select id="selAll" resultMap="smap"> 
  select s.id sid, s.name sname, s.age, s.gender, c.id cid, c.name cname, c.room from t_student s left join t_class c on s.cid=c.id 
</select>

14.2、resultMap的关联方式实现多表查询(一对 多)

  \1. 在 ClazzMapper.xml 中定义多表连接查询 SQL 语句, 一次性查到需要的所有数据, 包括对应学生的信息.

  \2. 通过resultMap定义映射关系, 并通过collection标签指定集合属性泛型的映射关系. 可以collection标签看成一个resultMap标签使用. ofType 属性表示集合的泛型, 可以写全限定路径或别名.

班级类中添加一个List容器存储学生类型 的数据 :

public class Clazz implements Serializable{ 
	private int id; 
	private String name; 
	private int roomNum; 
	private List<Student> stus; 
}

ClazzMapper.xml:

<mapper namespace="com.xxxx.mapper.ClazzMapper"> 
  <resultMap type="clazz" id="cmap"> 
    <id property="id" column="cid" /> 
    <result property="name" column="cname" /> 
    <result property="room" column="room" /> 
    <collection property="stus" javaType="list" ofType="student"> 
      <id property="id" column="sid" /> 
      <result property="name" column="sname" /> 
      <result property="age" column="age" /> 
      <result property="gender" column="gender" /> 
      <result property="cid" column="cid" /> 
    </collection> 
  </resultMap> 
  
  <select id="selAll" resultMap="cmap"> select c.id cid, c.name cname,c.room, s.id sid, s.name sname, s.age, s.gender from t_student s right join t_class c on s.cid=c.id 
  </select> 
</mapper>

14.3、列名和属性名不一致问题

  如果查询时使用 resultType 属性, 表示采用 MyBatis 的Auto-Mapping(自动映射)机制, 即相同的列名和属性名会自动匹配. 因此, 当数据库表的列名和类的属性名不一致时, 会导致查不到数据. 解决该问题可以

有两种方式:

1.1. 列别名

 查询时, 可以通过列别名的方式将列名和属性名保持一致,继续使用自动映射, 从而解决该问题. 但是较为麻烦.

<select id="selAll" resultType="user"> 
  select id id1, username username1, password password2 from t_user 
</select>

1.2. 使用resultMap

 resultMap用于自定义映射关系, 可以由程序员自主制定列名和属性名的映射关系. 一旦使用 resultMap,表示不再采用自动映射机制.

<resultMap type="user" id="umap"> 
  <!-- id用于映射主键 --> 
  <id column="id" property="id1" /> 
  <!-- 非主键使用result映射 --> 
  <result column="username" property="username1" /> 
  <result column="password" property="password1" /> 
</resultMap> 

<select id="selAll" resultMap="umap"> 
  select * from t_user 
</select>

15、注解开发

 使用注解一般用于简化配置文件. 但是, 注解有时候也不是很友好(有时候反而更麻烦), 例如动态 SQL等,所以注解和配置文件可以配合使用。

15.1、MyBatis中常用的注解

CRUD注解

  • @Select: 类似于select标签
  • @Insert: 类似于insert标签
  • @Update: 类似于update标签
  • @Delete: 类似于delete标签
package com.xxxx.mapper; 
import java.util.List; 
import org.apache.ibatis.annotations.Delete; 
import org.apache.ibatis.annotations.Insert; 
import org.apache.ibatis.annotations.Select; 
import org.apache.ibatis.annotations.Update; 
import com.xxxx.pojo.Student; 
public interface StudentMapper { 
	@Select("select * from t_student") 
  List<Student> selAll(); 
  
  @Insert("insert into t_student values (default, #{name}, #{age}, #{gender}, #{cid})") 
  int insStu(Student student); 
  
  @Update("update t_student set age=#{1} where id=#{0}") 
  int updStu(int id, int age);
  
  @Delete("delete from t_student where id=#{0}") 
  int delStu(int id); }

其他注解

  • @Results: 类似于resultMap标签
  • @Result: 类似<resultMap的子标签
  • @One: 类似于association标签
  • @Many: 类似于collection标签
public interface StudentMapper { 
  @Select("select * from t_student") 
  @Results( 
    value = { @Result(column="id", property="id", id=true),
             @Result(column="name", property="name"), 
             @Result(column="age", property="age"), 
             @Result(column="gender", property="gender"),
             @Result(column="cid", property="cid"), 
             @Result(property="clazz", 
     one=@One(select="com.xxxx.mapper.ClazzMapper.selById"), 
     column="cid") 
     } 
  )
  List<Student> sel(); 
}
public interface ClazzMapper { 
  @Select("select * from t_class where id=#{0}") 
  Clazz selById(int id); 
}

16、逆向工程

 mybatis-generator是一款mybatis自动代码生成工具,可以通过配置,快速生成pojo,mapper和xml文件.

官方网址:http://mybatis.org/generator/configreference/xmlconfig.html

generatorConfig.xml配置,需添加到资源包下 src下

<?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>
  <!--数据库驱动 --> 
  <context id="Tables" targetRuntime="MyBatis3"> 
  	<!-- 生成的Java文件的编码 -->
  	<property name="javaFileEncoding" value="UTF-8" /> 
  	<!-- JavaBean 实现 序列化 接口 --> 
  	<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/> 
  	<commentGenerator>
      	<property name="suppressDate" value="true" />
      	<!-- 是否去除自动生成的注释 true:是 : false:否 --> 
      	<property name="suppressAllComments" value="false" />
  	</commentGenerator> 
  	<!--数据库链接地址账号密码 -->
  	<jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver" 		
       connectionURL="jdbc:oracle:thin:@localhost:1521:xe" userId="SCOTT" password="TIGER"> 
    </jdbcConnection> 
    <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true 时把 JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal -->
    <javaTypeResolver>
      <property name="forceBigDecimals" value="false" /> 
    </javaTypeResolver>
    <!--生成 Model 类存放位置 --> 
    <javaModelGenerator targetPackage="com.xxxx.pojo" targetProject="mybatis12\src"> 
      <property name="enableSubPackages" value="true" /> 
      <property name="trimStrings" value="true" /> 
    </javaModelGenerator> <!--生成映射文件存放位置 --> 
    <sqlMapGenerator targetPackage="com.xxxx.mappers" targetProject="mybatis12\src"> 
      <property name="enableSubPackages" value="true" /> 
    </sqlMapGenerator> <!--生成接口类存放位置(Dao|Mapper) --> 
    <javaClientGenerator type="XMLMAPPER" targetPackage="com.xxxx.mappers" targetProject="mybatis12\src"> 
      <property name="enableSubPackages" value="true" /> 
    </javaClientGenerator> <!-- 参考数据库中需要生成的对应表信息 --> 
    <table tableName="dept" domainObjectName="Dept" 
           enableCountByExample="false" enableUpdateByExample="false" 
           enableDeleteByExample="false" enableSelectByExample="false" 
           selectByExampleQueryId="false">
    </table> 
    <table tableName="emp" domainObjectName="Emp" 
           enableCountByExample="false" enableUpdateByExample="false" 
           enableDeleteByExample="false" enableSelectByExample="false" 
           selectByExampleQueryId="false">
    </table> 
  </context> 
</generatorConfiguration>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值