MyBatis

目录

MyBatis核心配置文件:

自定义映射resultMap

MyBatis添加功能获取自增的主键

1.resultMap处理字段和属性的映射关

2、多对一映射处理

3、一对多映射处理

方式二:分步式查询,同多对一association 改为collection

动态SQL

批量添加:

批量删除:

MyBatis的逆向工程 

分页插件


MyBatis核心配置文件:

<?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?,settings?,typeAliases?,typeHandlers?,
        objectFactory?,objectWrapperFactory?,reflectorFactory?,
        plugins?,environments?,databaseIdProvider?,mappers?
    -->

    <!--引入properties文件-->
    <properties resource="jdbc.properties"/>
    <settings>
        <!--将下划线映射为驼峰-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!--开启延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--按需加载-->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
    <!--设置类型别名-->
    <typeAliases>
        <!--以包为单位,将包下所有的类型设置默认的类型别名-->
        <package name="com.gr.mybatis.pojo"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <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>
        <!--以包为单位引入映射文件
            要求:
            1.mapper接口所在的包要和映射文件所在的包一致
            2.mapper接口要和映射文件的名字一致
        -->
        <package name="com.gr.mybatis.mapper"/>
    </mappers>
</configuration>

自定义映射resultMap

MyBatis添加功能获取自增的主键

/**

* 添加用户信息

* useGeneratedKeys:设置使用自增的主键

* keyProperty:因为增删改有统一的返回值是受影响的行数,因此只能将获取的自增的主键放在传输的参 数user对象的某个属性中

*/

int insertUser(User user);
     <!--int insertUser(User user);-->
    <insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
        insert into t_user values (0,#{username},#{password},#{age},#{gender},#{email})
    </insert>

1.resultMap处理字段和属性的映射关

     <!--
        resultMap:设置自定义映射关系
        id:唯一标识,不能重复
        type:设置映射关系中的实体类类型
            子标签:
            id:设置主键的元素关系
            result:设置普通字段的映射关系
            属性:
            property:设置映射关系中的属性名,必须是type属性所设置的实体类类型中的属性名
            column:设置映射关系中的字段名,必须是sql语句查询出的字段名
     -->   
     <resultMap id="empResultMap" type="Emp">
        <id property="empId" column="emp_id"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="aeg"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>
    </resultMap>

    <!--List<Emp> getAllEmp();-->
    <select id="getAllEmp" resultMap="empResultMap">
        select * from t_emp
    </select>

核心配置文件设置内容:

    <!-- 设置全局配置-->     
    <settings>
        <!--将下划线映射为驼峰-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!--开启延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--按需加载-->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>

2、多对一映射处理

方式一:级联属性赋值

 <!--处理多对一映射关系方式一:级联属性赋值-->
    <resultMap id="empAndDeptResultMapOne" type="Emp">
        <id property="eid" column="eid"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>
        <result property="dept.did" column="did"></result>
        <result property="dept.deptName" column="dept_name"></result>
    </resultMap>

方式二:association 

  <!--处理多对一映射关系方式二:association-->
    <resultMap id="empAndDeptResultMapTwo" type="Emp">
        <id property="eid" column="eid"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>
        <!--
            association:处理多对一的映射关系
            property:需要处理多对一的映射关系的属性名
            javaType:该属性的类型
        -->
        <association property="dept" javaType="Dept">
            <id property="did" column="did"></id>
            <result property="deptName" column="dept_name"></result>
        </association>
    </resultMap>
<!--    Emp getEmpAndDept(@Param("eid") Integer eid);-->
    <select id="getEmpAndDept" resultMap="empAndDeptResultMapTwo">
        select * from t_emp e left join t_dept d on e.did = d.did where e.eid=#{eid}
    </select>

 方式三:分步式查询

 <!--处理多对一映射关系方式三:分步式查询-->
<resultMap id="empAndDeptByStepResultMap" type="Emp">
    <id property="eid" column="emp_id"></id>
    <result property="empName" column="emp_name"></result>
    <result property="age" column="age"></result>
    <result property="sex" column="sex"></result>
    <result property="email" column="email"></result>
    <!--
        select:设置分布查询sql的唯一标识(namespace.SQLId或mapper接口的全类名.方法名)
        column:设置分布查询的条件
        fetchType:当开启了全局的延迟加载之后,可通过此属性手动控制延迟加载的效果
            fetchType="lazy|eager":lazy表示延迟加载,eager表示立即加载
    -->
    <association property="dept"
                 select="com.gr.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
                 column="dept_id"
                 fetchType="eager"></association>
</resultMap>

<!--Emp getEmpAndDeptByStepOne(@Param("did") Integer did);-->
<select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">
    select * from t_emp where eid = #{eid}
</select>
    <!--Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);-->
    <select id="getEmpAndDeptByStepTwo" resultType="Dept">
        select * from t_dept where did = #{did}
    </select>

3、一对多映射处理

    <resultMap id="deptAndEmpResultMap" type="Dept">
        <id property="did" column="did"></id>
        <result property="deptName" column="dept_name"></result>
        <!--
            collection:处理一对多的映射关系
                ofType:表示该属性所对应的集合中存储数据的类型
        -->
        <collection property="emps" ofType="Emp">
            <id property="empId" column="emp_id"></id>
            <result property="empName" column="emp_name"></result>
            <result property="age" column="age"></result>
            <result property="sex" column="sex"></result>
            <result property="email" column="email"></result>
        </collection>
    </resultMap>
    <!--Dept getDeptAndEmp(@Param("did") Integer did);-->
    <select id="getDeptAndEmp" resultMap="deptAndEmpResultMap">
        select * from t_dept d left join t_emp e on d.did = e.did where d.did = #{did}
    </select>

方式二:分步式查询,同多对一association 改为collection

    <resultMap id="deptAndEmpResultMapByStep" type="Dept">
        <id column="dept_id" property="deptId"></id>
        <result column="dept_name" property="deptName"></result>
        <collection property="emps"
                    select="com.gr.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"
                    column="dept_id"> </collection>
    </resultMap>

    <!--Dept getDeptAndEmpByStepOne(@Param("deptId") Integer deptId);-->
    <select id="getDeptAndEmpByStepOne" resultMap="deptAndEmpResultMapByStep">
        select * from t_dept where dept_id = #{deptId}
    </select>
    <!--List<Emp> getDeptAndEmpByStepTwo(@Param("deptId") Integer deptId);-->
    <select id="getDeptAndEmpByStepTwo" resultType="Emp">
        select * from t_emp where dept_id = #{deptId}
    </select>

动态SQL

1、if: 通过test属性中的表达式判断标签中的内容是否有效(是否会拼接到sql中)

2、where  
        a.若where标签中有条件成立,会自动生成where关键字
        b.会自动将where标签中内容前多余的and去掉,但是其中内容后多余的and无法去掉
        c.若where标签中没有任何一个条件成立,则where没有任何功能

3、trim  必须搭配标签使用
        prefix、suffix:在标签中内容前面或后面添加指定内容
        prefixOverrides、suffixOverrides:在标签中内容前面或后面去掉指定内容

    <!-- List<Emp> getEmpByCondition(Emp emp);-->
    <select id="getEmpByCondition" resultType="Emp">
        select * from t_emp
        <trim prefix="where" suffixOverrides="and">
            <if test="empName!=null and empName!= '' ">
                emp_name = #{empName} and
            </if>
            <if test="age!=null and age!= '' ">
                age = #{age} and
            </if>
            <if test="gender!=null and gender!= '' ">
                gender = #{gender}
            </if>
        </trim>
    </select>

​​​​4、choose、when、otherwise 
        相当于java中的if...else if...else    其中有任何一个条件满足,之后的就不再执行
        when至少设置一个,otherwise最多设置一个  when = else if    otherwise = else

    <!--List<Emp> getEmpByChoose(Emp emp);-->
    <select id="getEmpByChoose" resultType="Emp">
        select * from t_emp
        <where>
            <choose>
                <when test="empName!=null and empName!= ''">
                    emp_name = #{empName}
                </when>
                <when test="age!=null and age!= ''">
                    age = #{age}
                </when>
                <when test="gender!=null and gender!= ''">
                    gender = #{gender}
                </when>
                <otherwise>emp_id = 2</otherwise>
            </choose>
        </where>
    </select>

 5、foreach
        collection:设置要循环的数组或集合
        item:用一个字符串表示数组或集合中的每一个数据
        separator:设置每次循环的数据之间的分隔符
        open:循环的所有内容以什么开始
        close:循环的所有内容以什么结束

批量添加:

    <!--void insertMoreEmp(@Param("emps") List<Emp> emps);-->
    <insert id="insertMoreEmp">
        insert into t_emp values
        <foreach collection="emps" item="emp" separator=",">
            (null,#{emp.empName},#{emp.age},#{emp.gender},null)
        </foreach>
    </insert>

批量删除:

    <!--void deleteMoreEmp(@Param("empids") Integer[] empids);-->
    <delete id="deleteMoreEmp">
        delete from t_emp where emp_id in
        <foreach collection="empids" item="empid" separator="," open="(" close=")">
            #{empid}
        </foreach>
    </delete>
    <!--void deleteMoreEmp(@Param("empids") Integer[] empids);-->
    <delete id="deleteMoreEmp">
        delete from t_emp where
        <foreach collection="empids" item="empid" separator="or">
            emp_id = #{empid}
        </foreach>
    </delete>

6、sql片段
       
可以记录一段sql,在需要用的地方使用include标签进行引用

<sql id="empColumns">
eid,ename,age,sex,did
</sql>
select <include refid="empColumns"></include> from t_emp

MyBatis的逆向工程 

添加依赖和插件

<packaging>jar</packaging>
    <!-- 依赖MyBatis核心包 -->
    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
        <!-- junit测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- log4j日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>
    </dependencies>
    <!-- 控制Maven在构建过程中相关配置 -->
    <build>
        <!-- 构建过程中用到的插件 -->
        <plugins>
            <!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 -->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.0</version>
                <!-- 插件的依赖 -->
                <dependencies>
                    <!-- 逆向工程的核心依赖 -->
                    <dependency>
                        <groupId>org.mybatis.generator</groupId>
                        <artifactId>mybatis-generator-core</artifactId>
                        <version>1.3.2</version>
                    </dependency>
                    <!-- MySQL驱动 -->
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>8.0.16</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

 ②创建MyBatis的核心配置文件

③创建逆向工程的配置文件  文件名必须是: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>
    <!--
    targetRuntime: 执行生成的逆向工程的版本
    MyBatis3Simple: 生成基本的CRUD(清新简洁版)
    MyBatis3: 生成带条件的CRUD(奢华尊享版)
    -->
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!-- 数据库的连接信息 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC"
                        userId="root"
                        password="abc123">
        </jdbcConnection>
        <!-- javaBean的生成策略-->
        <javaModelGenerator targetPackage="com.gr.mybatis.pojo"
                            targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!-- SQL映射文件的生成策略 -->
        <sqlMapGenerator targetPackage="com.gr.mybatis.mapper"
                         targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <!-- Mapper接口的生成策略 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.gr.mybatis.mapper" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
        <!-- 逆向分析的表 -->
        <!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName -->
        <!-- domainObjectName属性指定生成出来的实体类的类名 -->
        <table tableName="t_emp" domainObjectName="Emp"/>
        <table tableName="t_dept" domainObjectName="Dept"/>
    </context>
</generatorConfiguration>

④执行MBG插件的generate目标 :

Maven-->包名-->Plugins-->mybatis-generator-->双击mybatis-generator:generate 

测试功能:

public class MBGTest {
    @Test
    public void testMBG(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        
        //根据id查询数据
//        Emp emp = mapper.selectByPrimaryKey(5);
//        System.out.println(emp);
        
        //查询所有数据
//        List<Emp> list = mapper.selectByExample(null);
//        list.forEach(System.out::println);
        
        //根据条件查询数据
//        EmpExample example = new EmpExample();
//        example.createCriteria().andEmpNameEqualTo("田七").andAgeGreaterThanOrEqualTo(20);
//        example.or().andGenderEqualTo("男");
//        List<Emp> list = mapper.selectByExample(example);
//        list.forEach(System.out::println);
        
        //测试普通修改功能
        Emp emp = new Emp(3,"小黑",null,"女");
//        mapper.updateByPrimaryKey(emp);
        
        //选择性修改
        mapper.updateByPrimaryKeySelective(emp);
    }
}

 

分页插件

配置:

①添加依赖

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.0</version>
</dependency>

②配置分页插件   在MyBatis的核心配置文件中配置插件

<plugins>
    <!--设置分页插件-->
    <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>

分页功能的使用:

public class PageTest {
    @Test
    public void testPage(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        //查询功能之前开启分页功能
        //pageNum:当前页的页码
        //pageSize:每页显示的条数
        Page<Object> page = PageHelper.startPage(3, 4);
        List<Emp> list = mapper.selectByExample(null);
        //在查询功能之后可以获取分页相关的所有数据
        //list:分页之后的数据
        //navigatePages:导航分页的页码数
        PageInfo<Emp> pageInfo = new PageInfo<>(list,5);
        list.forEach(System.out::println);
        System.out.println(pageInfo);
    }
}

PageInfo中的属性:

pageNum:当前页的页码

pageSize:每页显示的条数

size:当前页显示的真实条数

total:总记录数

pages:总页数

prePage:上一页的页码

nextPage:下一页的页码

isFirstPage/isLastPage:是否为第一页/最后一页

hasPreviousPage/hasNextPage:是否存在上一页/下一页

navigatePages:导航分页的页码数

navigatepageNums:导航分页的页码,[1,2,3,4,5]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值