1

一.初步搭建Mbatis和使用

我当前使用的是:IDEA 2019, jdk 1.8 , mysql 5.1

1.需要的jar包

image.png

2.搭建结构

image.png

(a).mybatis-config.xml文件是配置运行环境,数据源,事务,等

 <!--mybatis配置文件主要编写:连接数据库配置、加载映射文件,整合spring之后,该配置文件可以不用编写-->
 <settings>
     <!-- 配置log4j日志信息 -->
     <setting name="logImpl"             value="log4j"/>
 </settings>
 
  <!--配置插件-->
 <plugins>
     <!--配置分页插件-->
     <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
 </plugins>
 
 <!--连接数据库-->
 <environments default="mysql">
     <!--该配置环境可以有多个-->
     <environment id="mysql">
         <!--事务管理器类型:JDBC,Manager-->
         <transactionManager type="JDBC"></transactionManager>
         <!--数据源:POOLED、jndi、unpooled-->
         <dataSource type="POOLED">
             <property name="driver" value="com.mysql.jdbc.Driver"></property>
             <property name="url" value="jdbc:mysql://localhost:3306/smbms?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=UTC"></property>
             <property name="username" value="root"></property>
             <property name="password" value=""></property>
         </dataSource>
     </environment>
 </environments>


 <!--加载映射文件-->
 <mappers>
     <mapper resource="com/bdqn/dao"/>
 </mappers>

(b).log4j.properties是日志

log4j.rootLogger=DEBUG,CONSOLE,file
#log4j.rootLogger=ERROR,ROLLING_FILE
log4j.logger.cn.smbms.dao=debug
log4j.logger.com.ibatis=debug 
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug 
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug 
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug 
log4j.logger.java.sql.Connection=debug 
log4j.logger.java.sql.Statement=debug 
log4j.logger.java.sql.PreparedStatement=debug 
log4j.logger.java.sql.ResultSet=debug 
log4j.logger.org.tuckey.web.filters.urlrewrite.UrlRewriteFilter=debug

######################################################################################
# Console Appender  \u65e5\u5fd7\u5728\u63a7\u5236\u8f93\u51fa\u914d\u7f6e
######################################################################################
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=error
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern= [%p] %d %c - %m%n


######################################################################################
# DailyRolling File  \u6bcf\u5929\u4ea7\u751f\u4e00\u4e2a\u65e5\u5fd7\u6587\u4ef6\uff0c\u6587\u4ef6\u540d\u683c\u5f0f:log2009-09-11
######################################################################################
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.DatePattern=yyyy-MM-dd
log4j.appender.file.File=log.log
log4j.appender.file.Append=true
log4j.appender.file.Threshold=error
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-M-d HH:mm:ss}%x[%5p](%F:%L) %m%n


log4j.logger.com.opensymphony.xwork2=error  

(c).MaBtisUtil工具类

 private static SqlSessionFactory factory;

    static{//在静态代码块下,factory只会被创建一次
        System.out.println("static factory===============");
        try {
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            factory = new SqlSessionFactoryBuilder().build(is);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static SqlSession createSqlSession(){
        return factory.openSession(false);//true 为自动提交事务
    }

    public static void closeSqlSession(SqlSession sqlSession){
        if(null != sqlSession)
            sqlSession.close();
    }

(d).创建的实体类,映射文件,测试类,工具类

*    在userMapper.xml编写sql
    ```
    <!--        
        mapper:映射文件主要编写sql
        namespace:命名空间(一般填写对应接口的全限定名)
        select标签:查询
        delete标签:删除
        insert标签:添加
        update标签:修改
        id:方法名
        parameterType:参数类型
        resultType:返回值类型
        #{}:占位符,防止sql注入,参数名任意命名
        ${}:会引发sql注入
    -->
    <select id="findList" parameterType="string" resultType="com.bdqn.entity.User">
       select * from smbms_user where userName like concat('%',#{name},'%')
   </select>
```
  • mapper写需要实现的方法
/**
     * 根据名称模糊查询
     * @param name
     * @return
     */
    List<User> findList(String name);
  • userTest 执行

    image.png

二.SQL映射文件

  • 多条件查询(多参数需要使用注解@param)

(a).mapper接口

    /**
     * 根据用户名模糊查询和性别查询
     * @param name
     * @param sex
     * @return
     */
    List<User> findUserList(@Param("name") String name, @Param("sex") int sex);

(b).mapper.xml映射文件

<select id="findUserList" parameterType="string" resultType="user">
        select * from smbms_user where userName like concat('%',#{name},'%') and gender=#{sex}
    </select>

(c).userTest

@Test
    public void test2(){
        SqlSession session=MyBatisUtil.createSqlSession();
        //通过动态代理模式UserMapper
        UserMapper userMapper=session.getMapper(UserMapper.class);
        try{
            //调用查询方法
            List<User> list =userMapper.findUserList("a",1);
            for (User user:list) {
                System.out.println(user);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            MyBatisUtil.closeSqlSession(session);
        }
    }
  • mabtis实现高级结果映射(一对一,一对多,多对多)就需要使用resultMap来作为statement的输出映射类型

(a).mapper接口

        /**
         * 查询所有用户
         * @return
         */
        List<User> findAllUser();

(b).mapper.xml映射

<!--
  查询所有用户
  type:相关类的数据类型,例如:配置user类的属性,type就填写User类的全局路劲
  id:配置主键名
  property:实体类的属性名
  column:数据库字段
-->
  <resultMap id="userResultMap" type="com.bdqn.entity.User">
      <id property="id" column="id"></id>
      <result property="userCode" column="code"></result>
      <result property="userName" column="name"></result>
  </resultMap>
  <!--使用resultMap代替resultType-->
  <select id="findAllUser" resultMap="userResultMap">
      select id,userCode code,userName name from smbms_user
  </select>

(c).userTest

@Test
    public void test8(){
        SqlSession session=MyBatisUtil.createSqlSession();
        //通过动态代理模式UserMapper
        UserMapper userMapper=session.getMapper(UserMapper.class);
        try{
            List<User> list =userMapper.findAllUser();
            for (User user:list) {
                System.out.println(user);
            }
        }catch (Exception e){
            e.printStackTrace();

        }finally {
            MyBatisUtil.closeSqlSession(session);
        }
    }

三.复杂关联关系映射

添加实体类
image.png

  • 一对一

(a)mapper接口

     /**
     * 使用resultMap实现一对一
     * @return
     */
    List<Orders> findOrdersByResultMap();

(b)mapper.xml映射

 <!--resultMap的方式配置一对一-->
   <resultMap id="orderUserResultMap" type="com.bdqn.entity.Orders">
       <id property="id" column="id"/>
       <result column="user_id" property="userId"/>
       <result column="number" property="number"/>
       <result column="createTime" property="createTime"/>
       <result column="note" property="note"/>
       <!--配置关联的用户信息-->
       <association property="user" javaType="com.bdqn.entity.User">
           <!--配置User类的属性-->
           <id column="user_id" property="id"/>
           <result column="user_id" property="id"/>
           <result column="username" property="username"/>
       </association>
   </resultMap>
    <!--u.id user_id:user_id是u.id的别名-->
    <select id="findOrdersByResultMap" resultMap="orderUserResultMap">
        SELECT o.*,u.id user_id,u.username,u.address FROM orders o
        INNER JOIN USER  u ON o.`user_id`=u.`id`
    </select>

(c)UserTest

 @Test
    public void test2(){
        //获取session
        SqlSession session=MyBatisUtil.createSqlSession();
        //通过动态代理模式获取对象
        OrdersMapper mapper= session.getMapper(OrdersMapper.class);
        //调用查询方法
        List<Orders> list=mapper.findOrdersByResultMap();
        System.out.println(list.size());
    }
  • 一对多

(a)mapper

/**
     * 使用resultMap实现一对多
     * @return
     */
    List<Orders> findOrderAndOrderdetailResultMap();

(b)mapper.xml

 <!--配置一对多-->
    <!--定义orderAndOrderdetailResultMap-->
    <resultMap id="orderAndOrderdetailResultMap" type="com.bdqn.entity.Orders" extends="orderUserResultMap">
        <!--配置订单明细-->
        <!--collection:配置一对多,关联订单明细-->
        <!--property:填写实体类的属性名   ofType:填写该属性类的数据类型-->
        <collection property="orderdetailList" ofType="com.bdqn.entity.Orderdetail">
            <!--property:填写实体类的属性名,column:填写数据库的属性名-->
            <id property="id" column="orderdetail_id"></id>
            <result property="ordersId" column="items_id"></result>
            <result property="itemsId" column="items_num"></result>
            <result property="itemsNum" column="orders_id"></result>
        </collection>
    </resultMap>
    <select id="findOrderAndOrderdetailResultMap" resultMap="orderAndOrderdetailResultMap">
        SELECT
          o.*,
          u.username ,
          u.`address`,
          u.`id` user_id,
          d.`id` orderdetail_id,
          d.`items_id`,
          d.`items_num`,
          d.`orders_id`
        FROM
          orders o
          INNER JOIN `user` u  ON o.`user_id` = u.`id`
          INNER JOIN orderdetail d ON d.`orders_id` = o.`id`
    </select>

(c)UserTest

@Test
    public void test3(){
        //获取session
        SqlSession session=MyBatisUtil.createSqlSession();
        //通过动态代理模式获取对象
        OrdersMapper mapper= session.getMapper(OrdersMapper.class);
        //调用查询方法
        List<Orders> list=mapper.findOrderAndOrderdetailResultMap();
        System.out.println(list.size());
    }
  • 多对多
  • (a)mapper
/**
     * 使用result实现多对多
     * @return
     */
    List<User> findUserAndItemsResultMap();

(b)mapper.xml

<!--配置多对多-->
    <!--定义userAndItemsResultMap-->
    <resultMap id="userAndItemsResultMap" type="com.bdqn.entity.User">

        <!--1、配置用户信息-->
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="birthday" column="birthday"></result>
        <result property="sex" column="sex"></result>
        <result property="address" column="address"></result>

        <!--2、用户关联订单信息,一对多-->
        <collection property="ordersList" ofType="com.bdqn.entity.Orders">
           <!--property:这个是放实体类的名称  column:这个是放别名或者数据库名的-->
            <id property="id" column="order_id"/>
            <result property="userId" column="order_user_id"/>
            <result property="number" column="order_number"/>

            <!--3、订单关联明细,一对多-->
            <collection property="orderdetailList" ofType="com.bdqn.entity.Orderdetail">
                <id property="id" column="orderdetail_id"></id>
                <result property="ordersId" column="orders_id"></result>
                <result property="itemsId" column="items_id"></result>
                <result property="itemsNum" column="items_num"></result>
                <!--4、订单明细关联商品信息,一对一-->
                <association property="items" javaType="com.bdqn.entity.Items">
                    <id property="id" column="items_item_id"></id>
                    <result property="name" column="items_name"></result>
                    <result property="price" column="items_price"></result>
                </association>
            </collection>
        </collection>
    </resultMap>
    <select id="findUserAndItemsResultMap" resultMap="userAndItemsResultMap">
        select
          u.*,
          o.`id` order_id,
          o.`user_id` order_user_id,
          o.`number` order_number,
          d.`id` orderdetail_id,
          d.`items_id`,
          d.`items_num`,
          d.`orders_id`,
          i.`id` items_item_id,
          i.`name` items_name,
          i.`price` items_price
         from User u
        inner join orders o on u.`id`=o.`user_id`
        inner join orderdetail d on  d.`orders_id`=o.`id`
        inner join items i on i.`id`=d.`items_id`
    </select>

(c)UserTest

 @Test
    public void test4(){
        //获取session
        SqlSession session=MyBatisUtil.createSqlSession();
        //通过动态代理模式获取对象
        OrdersMapper mapper= session.getMapper(OrdersMapper.class);
        //调用查询方法
        List<User> list=mapper.findUserAndItemsResultMap();
        System.out.println(list.size());
    }
  • resultMap总结
resultType:
    作用:
     将查询结果按照sql列名pojo属性名一致性映射到pojo中。
    场合:
     常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)即可。
resultMap:
     使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。
    association:
    作用:
     将关联查询信息映射到一个pojo对象中。
    场合:
     为了方便查询关联信息可以使用association将关联订单信息映射为用户对象的pojo属性中,比如:查询订单及关联用户信息。
     使用resultType无法将查询结果映射到pojo对象的pojo属性中,根据对结果集查询遍历的需要选择使用resultType还是resultMap。
collection:
    作用:
     将关联查询信息映射到一个list集合中。
    场合:
     为了方便查询遍历关联信息可以使用collection将关联信息映射到list集合中,比如:查询用户权限范围模块及模块下的菜单,可使用collection将模块映射到模块list中,将菜单列表映射到模块对象的菜单list属性中,这样的作的目的也是方便对查询结果集进行遍历查询。
     如果使用resultType无法将查询结果映射到list集合中。

四.动态SQl

  • 使用if+where查询,使用if+trim查询,使用if+set修改

(a)mapper

/**
 * 多条件查询 使用 if+where
 * @param map
 * @return
 */
List<User> findUserByCondition(Map<String,Object> map);

/**
 * trim标签动态查询 使用 if+trim
 * @param map
 * @return
 */
List<User> findUserWithTrim(Map<String,Object> map);

/**
 * if + set修改
 * @param user
 * @return
 */
int updateUser(User user);

(b)mapper.xml

<!--1.where标签替换SQL语句中的where关键字-->
    <select id="findUserByCondition" parameterType="map" resultType="com.bdqn.entity.User">
        select * from smbms_user
        <where>
            <if test="userCode!=null and userCode!=''">
                and userCode like concat('%',#{userCode},'%')
            </if>
            <if test="roleId!=null">
                and userRole =#{roleId}
            </if>
        </where>
    </select>

    <select id="findUserWithTrim" parameterType="map" resultType="com.bdqn.entity.User">
        select * from smbms_user
        <!--prefix:前缀  prefixOverrides:剔除前面的and-->
        <trim prefix="where" prefixOverrides="and">
            <if test="userCode!=null and userCode!=''">
                and userCode like concat('%',#{userCode},'%')
            </if>
            <if test="roleId!=null">
                and userRole =#{roleId}
            </if>
        </trim>
    </select>

    <update id="updateUser" parameterType="com.bdqn.entity.User">
        update smbms_user
        <set>
            <if test="userName!=null and userName!=''">
                username=#{userName},
            </if>
            <if test="gender!=null and gender!=''">
                gender=#{gender}
            </if>
        </set>
        where id=#{id}
    </update>

(c)UserTes

@Test
    public void test1(){
        SqlSession session=MyBatisUtil.createSqlSession();
        UserMapper mapper=session.getMapper(UserMapper.class);
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("userCode","1");
        map.put("roleId",2);
        List<User> list=mapper.findUserByCondition(map);
        for (User user: list) {
            System.out.println(user.getUserCode());
        }
    }
    @Test
    public void test2(){
        SqlSession session=MyBatisUtil.createSqlSession();
        UserMapper mapper=session.getMapper(UserMapper.class);
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("userCode","a");
        map.put("roleId",3);
        List<User> list=mapper.findUserWithTrim(map);
        for (User user: list) {
            System.out.println(user.getUserCode());
        }
    }

    @Test
    public void test3(){
        SqlSession session=MyBatisUtil.createSqlSession();
        UserMapper mapper=session.getMapper(UserMapper.class);
        User user=new User();
        user.setUserName("玛丽");
        user.setGender(2);
        user.setId(21);
        int count=mapper.updateUser(user);
        if (count>0){
            System.out.println("成功");
        }else {
            System.out.println("失败");
        }
        session.commit();
    }
  • 小结
if+where

    1. where标签替换SQL语句中的where关键字

    2. where标签能够剔除第一个and或or关键字

    3. 占位符的内容就是条件表达式的变量
    
if+trim
    1.prefix:前缀
    2.prefixoverrides:去掉第一个and或者是or
  • MyBatis分页

(a)maper

/**
     *  分页查询
     * @param map
     * @return
     */
    List<User> findUserListWithPage(Map<String,Object> map);

(b)mapper.xml

   <select id="findUserListWithPage" parameterType="map" resultType="com.bdqn.entity.User">
        select * from smbms_user order by id limit #{start},#{size}
    </select>

(c)UserTest

 @Test
    public void test7(){
        SqlSession session=MyBatisUtil.createSqlSession();
        UserMapper mapper=session.getMapper(UserMapper.class);
        Map<String,Object> map=new HashMap<String,Object>();
           int pageIndex=1;
           int pageSize=5;
           map.put("start",(pageIndex-1)*pageSize);
           map.put("size",pageSize);
        List<User> list=mapper.findUserListWithPage(map);
        for (User user: list) {
            System.out.println(user.getUserCode());
        }
    }
  • 使用PageHelper分页

(a)修改mybatis-config.xml

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

(b)mapper

/**
     * 使用PageHelper做分页
     * @return
     */
    List<User> findAllUserList();

(c)mapper.xml

   <select id="findAllUserList" parameterType="map" resultType="com.bdqn.entity.User">
        select * from smbms_user
    </select>

(d)UserTes

@Test
    public void test8(){
        SqlSession session=MyBatisUtil.createSqlSession();
        UserMapper mapper=session.getMapper(UserMapper.class);

        PageHelper.startPage(1,5);

        List<User> list=mapper.findAllUserList();

        PageInfo<User> page = new PageInfo<User>(list);

        System.out.println("当前页码"+page.getPageNum());
        System.out.println("总页数"+page.getPages());
        System.out.println("总记录数"+page.getTotal());
        System.out.println("每页显示数量"+page.getPageSize());
        for (User user: list) {
            System.out.println(user.getUserCode()+","+user.getUserName());
        }
    }

SuSen
5 声望2 粉丝

下一篇 »
shiro

引用和评论

0 条评论