Mybatis动态sql、Mybatis-Generator插件、Mybatis 缓存以及Spring整合Mybatis

本文详细介绍了Mybatis的动态SQL配置,包括XML标签和注解方式,以及关系映射查询的一对一、一对多和多对多处理。同时,讲解了Spring整合Mybatis的步骤,Mybatis分页插件的集成,Mybatis-Generator插件的使用,以及Mybatis缓存机制的一级和二级缓存。通过对这些内容的实践,可以提升开发效率并优化查询性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Mybatis 动态SQL 配置

1. XML 标签配置

if 标签

逻辑判断标签 判断表达式 true

<if test="表达式"></if>    <!-- and | or  --> 

使用

<!-- 01 --> 
<select id="queryAccountsByParams01" parameterType="AccountQuery" resultType="Account">
    select <include refid="account_columns"/>
    from account
    where 1=1
    <if test="aname !=null and aname !=''">
        and  aname like concat('%',#{aname},'%')
    </if>
    <if test="type !=null and type !=''">
        and type=#{type}
    </if>
    <if test="userId=null">
        and user_id=#{userId}
    </if>
    <if test="time !=null and time !=''">
        and create_time &gt;=#{time}
    </if>
</select>

<!-- 02 -->
<select id="queryAccountsByParams02" parameterType="AccountQuery" resultType="Account">
    select <include refid="account_columns"/>
    from account
    where 1=1
    <if test="@Ognl@isNotEmpty(aname)">
        and  aname like concat('%',#{aname},'%')
    </if>
    <if test="@Ognl@isNotEmpty(type)">
        and type=#{type}
    </if>
    <if test="userId !=null">
        and user_id=#{userId}
    </if>
    <if test="@Ognl@isNotEmpty(time)">
        and create_time &gt;=#{time}
    </if>
</select>
where 标签

记录过滤标签

<where>
  ...
</where>

使用 记录过滤 | 条件过滤 如果紧跟where 后第一个逻辑判断条件成立时 and|or 单词被忽略

<select id="queryAccountsByParams" parameterType="AccountQuery" resultType="Account">
    select <include refid="account_columns"/>
    from account
    <where>
        <if test="@Ognl@isNotEmpty(aname)">
            and  aname like concat('%',#{aname},'%')
        </if>
        <if test="@Ognl@isNotEmpty(type)">
            and type=#{type}
        </if>
        <if test="userId !=null">
            and user_id=#{userId}
        </if>
        <if test="@Ognl@isNotEmpty(time)">
            and create_time &gt;=#{time}
        </if>
    </where>
</select>
choose when otherwise 标签

对结果 条件判断 执行二选一 类似 if-else

<choose>
    <when test=""></when>
    <otherwise></otherwise>
</choose>
<select id="queryAccountsByParams04" parameterType="AccountQuery" resultType="Account">
    select id, aname, user_id as userId, create_time as createTime, update_time as updateTime, remark,
    <choose>
        <when test="userId !=null">
            money
        </when>
        <otherwise>
            type
        </otherwise>
    </choose>
    from account
    <where>
        <if test="aname !=null and aname !=''">
            and  aname like concat('%',#{aname},'%')
        </if>
        <if test="type !=null and type !=''">
            and type=#{type}
        </if>
        <if test="userId !=null">
            and user_id=#{userId}
        </if>
        <if test="time !=null and time !=''">
            and create_time &gt;=#{time}
        </if>
    </where>
</select>

<!--
     动态sql 标签-choose when otherwise   if-else  二选一
   -->
<select id="queryAccountsByParams05" parameterType="AccountQuery" resultType="Account">
    select <include refid="account_columns"/>
    from account
    <where>
        <choose>
            <when test="userId != null">
                <if test="aname != null and aname != ''">
                    aname like concat('%',#{aname},'%')
                </if>
            </when>
            <otherwise>
                <if test="type != null and type != ''">
                    type=#{type}
                </if>
            </otherwise>
        </choose>
    </where>
</select>
trim 标签

可以替代where(update) 标签类似功能

<trim prefix=" "  prefixOverrides=" " suffixOverrides=" " suffix=" "></trim>

使用

<select id="queryAccountsByParams06" parameterType="AccountQuery" resultType="Account">
    select <include refid="account_columns"/>
    from account
    <trim prefix="where"  prefixOverrides="and |or" >
        <if test="aname !=null and aname !=''">
            and  aname like concat('%',#{aname},'%')
        </if>
        <if test="type !=null and type !=''">
            and type=#{type}
        </if>
        <if test="userId !=null">
            and user_id=#{userId}
        </if>
        <if test="time !=null and time !=''">
            and create_time &gt;=#{time}
        </if>
    </trim>
</select>
set 标签
<!--用于更新 如果最后一个字段出现, 该字符会被自动忽略-->
<set></set>

使用

<update id="updateAccountById" parameterType="Account">
     update account
     <set>
         <if test="aname !=null">
             aname=#{aname},
         </if>
         <if test="type !=null">
             type=#{type},
         </if>
         <if test="money !=null">
             money=#{money}
         </if>
     </set>
     where id=#{id}
</update>
foreach 标签

用于批量操作(批量添加 更新 删除)

批量添加

<insert id="saveUserBatch" parameterType="list">
    insert into  user(user_name, user_pwd, flag, create_time) values
    <foreach collection="list" item="item" separator=",">
        (#{item.userName},#{item.userPwd},#{item.flag},#{item.createTime})
    </foreach>
</insert>

批量更新

<update id="updateUserPwdByIdsBatch" parameterType="map">
    update user set user_pwd=#{userPwd}
    where id in
    <foreach collection="ids" item="item" open="(" separator="," close=")" >
        #{item}
    </foreach>
</update>

批量删除

<delete id="deleteUsersByIds03"  parameterType="map">
    delete from user where id in
    <!--
           collection:array|list
              如果参数类型为map  map key对应的value 为数组或list  此时collection值为key 名称
        -->
    <foreach collection="ids" item="item" open="(" separator="," close=")">
        #{item}
    </foreach>
</delete>

2. 基于注解sql 配置

添加注解

@Insert

@InsertProvider

@Insert("insert into account(aname,type,money,remark,create_time,update_time,user_id) values(#{aname},#{type},#{money},#{remark},#{createTime},#{updateTime},#{userId})")
// @InsertProvider()
public int saveAccount(Account account);
查询注解

@Select

@Select("select  id, aname, type, money, user_id as userId, create_time as createTime, update_time as updateTime, remark from account where id=#{id}")
public Account queryAccountById(Integer id);

@SelectProvider

  • type:Class 产生Sql字符串的Java 类
  • method:方法名称
@SelectProvider(type = AccountProvider.class, method = "getQueryAccountsByParamsSql01")
public List<Account> queryAccountsByParams01(AccountQuery accountQuery);
public class AccountProvider {
     public String getQueryAccountsByParamsSql01(AccountQuery accountQuery){
       return new SQL(){
            {
                SELECT("id, aname, type, money, user_id as userId, create_time as createTime, update_time as updateTime, remark ");
                FROM("account");
                WHERE(" 1=1 ");
                if(StringUtils.isNotBlank(accountQuery.getAname())){
                    WHERE(" aname like concat('%',#{aname},'%') ");
                }
                if(StringUtils.isNotBlank(accountQuery.getType())){
                    WHERE("  type=#{type} ");
                }
                if(StringUtils.isNotBlank(accountQuery.getTime())){
                    WHERE("  create_time >=#{time}") ;
                }
                if(accountQuery.getUserId()!=null){
                    WHERE(" user_id=#{userId}");
                }
            }
        }.toString();
    }
}
@SelectProvider(type = AccountProvider.class,method = "getQueryAccountsByParamsSql02")
public List<Account> queryAccountsByParams02(AccountQuery accountQuery);
public class AccountProvider {  
	public String getQueryAccountsByParamsSql02(AccountQuery accountQuery){
        StringBuffer stringBuffer=new StringBuffer("select id, aname, type, money, user_id as userId, create_time as createTime, update_time as updateTime, remark " +
                " from account where 1=1 ");
        if(StringUtils.isNotBlank(accountQuery.getAname())){
            stringBuffer.append(" and aname like concat('%',#{aname},'%')  ");
        }
        if(StringUtils.isNotBlank(accountQuery.getType())){
            stringBuffer.append(" and type=#{type}  ");
        }
        if(StringUtils.isNotBlank(accountQuery.getTime())){
            stringBuffer.append(" and create_time >=#{time}  ");
        }
        if(accountQuery.getUserId()!=null){
            stringBuffer.append(" and user_id=#{userId}  ");
        }
        return stringBuffer.toString();
	}   
}
更新注解

@Update

@UpdateProvider

@Update("update account set aname=#{aname}, type=#{type} where id=#{id}")
//@UpdateProvider()
public int updateAccount(Account account);
删除注解

@Delete

@DeleteProvider

@Delete("delete from account where id=#{id}")
//@DeleteProvider()
public int deleteAccountById(Integer id);

二、Mybatis 关系映射查询

  • 关系型数据库(ORM):主键-外键
    • 实体 - 实体 对应关系

一对一

例如:学校-校长、用户-身份证、国家-总统、用户-购物车 (t_user | t_cart(user_id))…

​ 用户-身份证

​ 国家-总统

​ 用户-购物车 (t_user | t_cart(user_id))

resultType
  • 方法1:dto接收结果
// 接口定义查询方法  结果使用dto 接收
public UserDto queryUserCardInfoByUserId(Integer userId);

public class UserDto {
    private Integer userId;
    private String userName;
    private String userPwd;
    private String flag;
    private Date createTime;
    private String num;// 身份证编号
    private Integer cardId;// 身份证id
    
    .......
}
<!--
       一对一关联查询 resultType
    -->
<select id="queryUserCardInfoByUserId" parameterType="int" resultType="UserDto">
    select
    u.id as userId, user_name as userName, user_pwd as userPwd, flag, create_time as createTime,c.id as cardId,c.num
    from
    user u left  join  id_card  c on u.id = c.user_id
    where u.id=#{userId}
</select>
  • 方法2:使用map
public Map<String, Object> queryUserCardInfoByUserId02(Integer userId);
<select id="queryUserCardInfoByUserId" parameterType="int" resultType="map">
    select u.id as userId, user_name as userName, user_pwd as userPwd, flag, create_time as createTime,c.id as cardId,c.num
    from user u left  join  id_card  c on u.id = c.user_id
    where u.id=#{userId}
</select>
resultMap
public User queryUserCardInfoByUserId03(Integer userId);
<resultMap id="user_map" type="User">
    <!--
         主表结果映射
            id:主键映射配置  
        -->
    <id column="userId" property="id"></id>
    <result column="userName" property="userName"></result>
    <result column="userPwd" property="userPwd"></result>
    <result column="flag" property="flag"></result>
    <result column="createTime" property="createTime"></result>
</resultMap>

<resultMap id="user_card_map" type="User" extends="user_map">
    <!--
         一对一 映射配置
        -->
    <association property="idCard" javaType="IdCard">
        <!--
             从表主键映射配置
            -->
        <id column="cardId" property="id"></id>
        <result column="num" property="num"></result>
    </association>
</resultMap>
<select id="queryUserCardInfoByUserId"  parameterType="int" resultMap="user_card_map">
    select
    u.id as userId, user_name as userName, user_pwd as userPwd, flag, create_time as createTime,c.id as cardId,c.num
    from
    user u left  join  id_card  c on u.id = c.user_id
    where u.id=#{userId}
</select>

一对多 | 多对一

例如:班级-学生、用户-订单(t_user |t_order(user_id))、公司-员工…

resultMap
public  User queryUserCardAccountInfoByUserId(Integer userId);
<resultMap id="user_account_map" type="User" extends="user_card_map">
     <!--
           一对多映射
               property:多的一方 属性名
               ofType:集合中元素的类型
               id:多的一方主键值的映射配置
        -->
     <collection property="accounts" ofType="Account">
         <id column="aid" property="id"></id>
         <result column="aname" property="aname"></result>
         <result column="type" property="type"></result>
         <result column="money" property="money"></result>
         <result column="ctime" property="createTime"></result>
         <result column="update_time" property="updateTime"></result>
         <result column="remark" property="remark"></result>
     </collection>
</resultMap>

<select id="queryUserCardAccountInfoByUserId" parameterType="int" resultMap="user_account_map">
    select u.id as userId, user_name as userName, user_pwd as userPwd, flag,
    u.create_time as createTime,c.id as cardId,c.num,
    a.id as aid, aname, a.type, a.money, a.create_time as ctime, a.update_time, a.remark
    from user u
    left  join  id_card  c on u.id = c.user_id
    left join  account  a on u.id=a.user_id
    where u.id=#{userId}
</select>

多对多

  • 例如:教师 - 课程、学生 - 课程 (t_student | t_course 中间表:t-grade(id sid cid grade) )、用户 - 角色(t_user | t_role 中间表:t_user_role)

  • 解决方案:拆分为一对多进行处理

    • s01 c01

      学生 成绩 课程

      –> 学生-成绩:一对多

      ​ 课程-成绩:一对多

三、Spring 整合Mybatis

1. 创建Maven工程

2. 添加坐标依赖

<!-- junit 测试 -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

<!-- spring 核心jar -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.2.RELEASE</version>
</dependency>

<!-- spring 测试jar -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.3.2.RELEASE</version>
</dependency>

<!-- spring jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.2.RELEASE</version>
</dependency>

<!-- spring事物 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>4.3.2.RELEASE</version>
</dependency>

<!-- aspectj切面编程的jar -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.9</version>
</dependency>

<!-- c3p0 连接池 -->
<dependency>
    <groupId>c3p0</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.1.2</version>
</dependency>

<!-- mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.1</version>
</dependency>

<!-- 添加mybatis与Spring整合的核心包 -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.0</version>
</dependency>

<!-- mysql 驱动包 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.39</version>
</dependency>

<!-- 日志打印相关的jar -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.2</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.2</version>
</dependency>

3. 添加资源文件

  • spring.xml 、 mybatis.xml、jdbc.properties、log4j.properties
    • spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--
       配置扫描器
    -->
    <context:component-scan base-package="com.xyz"/>

    <!--
       配置 加载jdbc.properties
    -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--
      数据源c3p0 配置
    -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <!--
       事物控制
    -->
    <aop:aspectj-autoproxy/>

    <!--
      事物管理器
    -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--
       声明事物通知
    -->
    <tx:advice id="txAdvice"  transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="save*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="del*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="cut" expression="execution(* com.xyz.service..*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="cut"></aop:advisor>
    </aop:config>

    <!--
       mybatis 整合spring
    -->
    <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:mybatis.xml"></property>
        <property name="mapperLocations" value="classpath:com/xyz/mappers/*.xml"></property>
    </bean>

    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 扫描com.xyz.dao这个包以及它的子包下的所有映射接口类 -->
        <property name="basePackage" value="com.xyz.dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean" />
    </bean>

</beans>
    • mybatis.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>
    <typeAliases>
        <package name="com.xyz.query"/>
        <package name="com.xyz.vo"/>
        <package name="com.xyz.dto"/>
    </typeAliases>

</configuration>
    • jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=root
    • log4j.properties
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

4. 编写代码

​ 以用户模块查询为主 进行测试

  • UserDao.java
import com.xyz.vo.User;

public interface UserDao {
    public User queryUserByUserId(Integer userId);
}
  • UserMapper.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="com.xyz.dao.UserDao">
    <select id="queryUserByUserId" parameterType="int" resultType="User">
        select id, user_name as userName, user_pwd as userPwd, flag, create_time as createTime from user where id=#{userId}
    </select>
</mapper>
  • UserService.java
import com.xyz.dao.UserDao;
import com.xyz.vo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    public User queryUserByUserId(Integer userId){
        return userDao.queryUserByUserId(userId);
    }
}

5. 添加单元测试

import com.xyz.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpringMybatis {

    @Test
    public void test(){
        ApplicationContext ac =new ClassPathXmlApplicationContext("spring.xml");
        UserService userService= (UserService) ac.getBean("userService");
        System.out.println(userService.queryUserByUserId(75));
    }
}
import com.xyz.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring.xml")
public class TestSpringMybatis02 {

    @Resource
    private UserService userService;

    @Test
    public void test(){
        System.out.println(userService.queryUserByUserId(75));
    }
}

四、Mybatis 分页插件整合

  1. 添加分页插件坐标

    <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>5.1.10</version>
    </dependency>
    
  2. 添加分页插件标签-mybatis.xml

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>
    
  3. 添加分页查询dao 方法 与sql 配置

    public interface AccountDao extends BaseMapper<Account,Integer> {
    
        public List<Account> queryAccountsByParams(AccountQuery accountQuery);
    
    }
    
     <sql id="account_columns">
         id, aname, type, money, user_id as userId, create_time as createTime, update_time as updateTime, remark
    </sql>
    <!--
            动态sql 标签-if  条件判断标签
        -->
    <select id="queryAccountsByParams" parameterType="AccountQuery" resultType="Account">
        select <include refid="account_columns"/>
        from account
        where 1=1
        <if test="aname !=null and aname !=''">
            and aname like concat('%',#{aname},'%')
        </if>
        <if test="type !=null and type !=''">
            and type=#{type}
        </if>
        <if test="userId=null">
            and user_id=#{userId}
        </if>
        <if test="time !=null and time !=''">
            and create_time &gt;=#{time}
        </if>
    </select>
    
  4. AccountService 实现分页查询

    @Service
    public class AccountService extends BaseService<Account, Integer> {
    
        @Autowired
        private AccountDao accountDao;
    
        public List<Account> queryAccountsByParams(AccountQuery accountQuery){
            PageHelper.startPage(accountQuery.getPageNum(),accountQuery.getPageSize());
            return accountDao.queryAccountsByParams(accountQuery);
        }
    
        public PageInfo<Account> queryAccountsByParams02(AccountQuery accountQuery){
            PageHelper.startPage(accountQuery.getPageNum(),accountQuery.getPageSize());
            List<Account> accounts=accountDao.queryAccountsByParams(accountQuery);
            return new PageInfo<Account>(accounts);
        }
    }
    
  5. 执行测试

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = "classpath:spring.xml")
    public class TestAccountService {
    
        @Resource
        private AccountService accountService;
    
        @Test
        public  void test01(){
            AccountQuery accountQuery=new AccountQuery();
            accountQuery.setType("1");
            accountQuery.setPageNum(3);
            accountService.queryAccountsByParams(accountQuery).forEach(a->{
                System.out.println(a);
            });
        }
    }
    

五、Mybatis-Generator 插件生成代码

1. 添加插件

<plugins>
    <plugin>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>1.3.2</version>
        <configuration>
            <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
            <verbose>true</verbose>
            <overwrite>true</overwrite>
        </configuration>
    </plugin>
</plugins>

2. 准备generatorConfig.xml 配置文件

  1. 驱动 jar 包路径:classPathEntry

  2. 连接数据库配置:jdbcConnection

  3. javaBean dao接口 xml 映射文件:javaModelGenerator

  4. table 标签配置(可以配置多个)

<?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>
    <!--数据库驱动-->
    <classPathEntry location="C:/m2/repository/mysql/mysql-connector-java/5.1.39/mysql-connector-java-5.1.39.jar"/>
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--数据库链接地址账号密码-->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://127.0.0.1:3306/mybatis"
                        userId="root"
                        password="root">
        </jdbcConnection>
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!--生成Model类存放位置-->
        <javaModelGenerator targetPackage="com.xyz.vo" targetProject="C:\java\idea_32\spring_mybatis\src\main\java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!--生成映射文件存放位置-->
        <sqlMapGenerator targetPackage="com.xyz.mappers" targetProject="C:\java\idea_32\spring_mybatis\src\main\java">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <!--生成Dao类存放位置-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.xyz.dao" targetProject="C:\java\idea_32\spring_mybatis\src\main\java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <table tableName="id_card" domainObjectName="IdCard" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
        <table tableName="xx_product_category" domainObjectName="ProductCategory" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
    </context>
</generatorConfiguration>

3. 配置执行插件的命令

  • 复习 idea 下 maven 基本命令配置:

    • clean 清除编译命令(删除target 目录)
    • clean compile 先执行清除操作 再重新编译源代码到target 目录
    • clean compile package 先执行清除操作 再重新编译源代码到target 目录 再执行打包 打包后文件(.jar .war )存放在 服务器的webapps目录
    • clean compile install -Dmaven.test.skip=true 先执行清除操作 再重新编译源代码到target 目录 在执行安装(在maven 本地仓库目录) 执行安装 跳过(忽略) 单元测试
    • tomcat7:run
    • jetty:run -Djetty.port=xxxx
  • 配置 生成文件命令 mybatis-generator:generate

六、MyBatis Base代码封装

  • 封装目的:简化代码;提高代码复用率;提高开发效率

1. BaseMapper 接口方法定义

import org.springframework.dao.DataAccessException;

import java.util.List;
import java.util.Map;

/*
   T:实体类 泛型参数
   ID:表主键类型
*/
public interface BaseMapper<T, ID> {
    /**
     * 添加记录返回影响行数
     */
    public int save(T entity) throws DataAccessException;

    /**
     * 添加记录返回主键
     */
    public  ID  saveHasKey(T entity) throws DataAccessException;

    /**
     * 批量添加记录
     */
    public  int  saveBatch(List<T> entities) throws DataAccessException;

    /**
     * 详情查询
     * @param id
     * @return
     */
    public T queryById(ID id) throws DataAccessException;

    /**
     * 多条件列表查询
     * @param baseQuery
     * @return
     */
    public List<T> queryByParams(BaseQuery baseQuery) throws DataAccessException;

    /**
     * 更新单条记录
     * @param entity
     * @return
     */
    public int update(T entity) throws DataAccessException;

    /**
     * 批量更新
     * @param map
     * @return
     */
    public int updateBatch(Map<String,Object> map) throws DataAccessException;

    /**
     * 删除单条记录
     * @param id
     * @return
     */
    public int delete(ID id) throws DataAccessException;

    /**
     * 批量删除
     * @param ids
     * @return
     */
    public int deleteBatch(ID[] ids) throws DataAccessException;

}

2. 子接口继承BaseMapper

这里以账户模块为例

import com.xyz.base.BaseMapper;
import com.xyz.vo.Account;

public interface AccountDao extends BaseMapper<Account,Integer> {

}

账户CRUD(sql) 通过Sql 映射文件体现

<?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="com.xyz.dao.AccountDao">
    <sql id="account_columns">
        id, aname, type, money, user_id as userId, create_time as createTime, update_time as updateTime, remark
    </sql>
    <!--
        动态sql 标签-if  条件判断标签
    -->
    <select id="queryByParams" parameterType="AccountQuery" resultType="Account">
        select <include refid="account_columns"/>
        from account
        where 1=1
        <if test="aname !=null and aname !=''">
            and  aname like concat('%',#{aname},'%')
        </if>
         <if test="type !=null and type !=''">
             and type=#{type}
         </if>
         <if test="userId=null">
             and user_id=#{userId}
         </if>
         <if test="time !=null and time !=''">
             and create_time &gt;=#{time}
         </if>
    </select>
</mapper>

3. BaseService 封装

封装了service 业务类基本的CRUD 方法

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

public abstract class BaseService<T, ID> {

    @Autowired
    private BaseMapper<T, ID> baseMapper;

    public int save(T entity){
        return baseMapper.save(entity);
    }

    public ID saveHasKey(T entity)  {
        baseMapper.saveHasKey(entity);
        try {
            Method method= entity.getClass().getDeclaredMethod("getId",null);
            return (ID) method.invoke(entity,null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public  int saveBatch(List<T> entities){
        return baseMapper.saveBatch(entities);
    }

    public T queryById(ID id){
        return baseMapper.queryById(id);
    }

    public List<T> queryByParams(BaseQuery baseQuery){
        return baseMapper.queryByParams(baseQuery);
    }

    public  int update(T entity){
        return baseMapper.update(entity);
    }

    public  int updateBatch(Map<String,Object> map){
        return baseMapper.updateBatch(map);
    }

    public int delete(ID id){
        return baseMapper.delete(id);
    }

    public  int deleteBatch(ID[] ids){
        return baseMapper.deleteBatch(ids);
    }

    /**
     * 分页查询
     * @param baseQuery
     * @return
     */
    public PageInfo<T> queryForPage(BaseQuery baseQuery){
        PageHelper.startPage(baseQuery.getPageNum(), baseQuery.getPageSize());
        return new PageInfo<T>(queryByParams(baseQuery));
    }

}

4. 子类继承BaseService

import com.xyz.base.BaseService;
import com.xyz.vo.Account;
import org.springframework.stereotype.Service;

@Service
public class AccountService extends BaseService<Account, Integer> {

}

七、Mybatis 缓存

  • 作用:提高应用查询效率

  • 查找顺序:

    • 二级开启,从二级缓存找
    • 二级缓存未开启,从一级缓存(Map)查找

一级缓存

  • 特点:
    • 同一个会话(SqlSession)
    • 默认开启
    • 基于内存存储
    • 关闭会话,一级缓存数据被清除或者显式调用清空缓存方法

二级缓存

  • 特点:
    • 同一个namespace, 进程缓存
    • 基于内存+硬盘
    • 默认不开启,需要手动开启
  • 二级缓存实现:Mybatis 框架内部实现 | 第三方实现(分布式Ehcache)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值