如何优雅设计mybtis工具类及实现分页查询,动态SQL&mybatis+struts组合使用

本文涉及的产品
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MyBatis工具类&mybatis+struts2整合

前提:主要内容

读者

本教程是为需要详细了解 MyBatis 框架及其架构和实际应用的 Java 程序员准备的。

教程中通俗易懂的讲解了 MyBatis 开发过程中涉及的各种知识,并且为每个知识点都提供了实例,以帮助读者快速入门学习。

  1. 1.Mybatis工具类
  2. 2.动态sql语句(if/foreach)
  3. 3.mybatis实现分页
  4. 4.mybatis实现分页ResultSet结果集
  5. 5.mybatis+struts2+mybatis+jsp整合
  6. 6.解决Mybatis报错问题

MyBatis 简介

MyBatis 是一个开源、轻量级的数据持久化框架,是 JDBC 和 Hibernate 的替代方案。

MyBatis 前身为 IBatis,2002 年由 Clinton Begin 发布。2010 年从 Apache 迁移到 Google,并改名为 MyBatis,2013 年又迁移到了 Github。

MyBatis 内部封装了 JDBC,简化了加载驱动、创建连接、创建 statement 等繁杂的过程,开发者只需要关注 SQL 语句本身。

MyBatis 支持定制化 SQL、存储过程以及高级映射,可以在实体类和 SQL 语句之间建立映射关系,是一种半自动化的 ORM 实现。

MyBatis、Hibernate 和 JDBC

和 Hibernate 相比,MyBatis 封装性低于 Hibernate,但性能优秀、小巧、简单易学、应用广泛。

和 JDBC 相比,MyBatis 减少了 50% 以上的代码量,并且满足高并发和高响应的要求。


一、MyBatisUtil工具类的封装

快捷键:castvar:强转快捷键

1.png


借鉴jdbcUtil工具类的封装。
1.冗余问题
封装:
1、获取链接
class xxx{
//工具方法 获取sqlSession对象
   public static SqlSession openSession(){
      InputStream is=Resources.getResourceAsStream("mybatis-confug.xml");
      SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is);
       SqlSession sqlSession=factory.onenSession();
   }
}
2、关闭资源

MybatisUtil工具类

package com.tjcu.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
/**
 * @author 王恒杰
 * @version 1.0
 * @date 2021/10/11 20:53
 * @email 1078993387@qq.com
 * @Address 天津
 * @Description:
 */
public class MybatisUtil {
    private static final ThreadLocal<SqlSession> t=new ThreadLocal<>();
    private static  SqlSessionFactory factory;
    /**
     * 静态代码块只加载一次
     */
    static{
        //1.Resources加载Mybatis核心配置文件[只加载一次]
        InputStream is = null;
        try {
            is = Resources.getResourceAsStream("mybatis-config.xml");
            //2.sqlSessionFactoryBuilder
            factory = new SqlSessionFactoryBuilder().build(is);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    public static SqlSession openSession() throws IOException {
       SqlSession sqlSession=t.get();
        //工厂开启sqlSession
        if(sqlSession==null){
            sqlSession = factory.openSession();
            t.set(sqlSession);
        }
        return sqlSession;
    }
    public static void close(SqlSession sqlSession){
        if(sqlSession!=null){
            sqlSession.close();
            t.remove();
        }
    }
}


测试方法

 

    @Test
    public void selectLikeUsername() throws IOException {
        SqlSession sqlSession = MybatisUtil.openSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        String str="恒";
        List<User> users = mapper.selectUserLikeUsername("%" +str + "%");
        for (User user : users) {
            System.out.println(user);
        }
        MybatisUtil.close(sqlSession);
    }


mapper.xml

   

  <select id="selectUserLikeUsername" resultType="user">
        select * from t_user where username like #{username}
    </select>


2、MybatisUtil工具类升级版

package com.tjcu.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
/**
 * @author 王恒杰
 * @version 1.0
 * @date 2021/10/12 9:52
 * @email 1078993387@qq.com
 * @Address 天津
 * @Description:
 */
public class MybatisUtil {
    /**
     * 线程绑定对象,保证是同一个对象
     */
    private static final ThreadLocal<SqlSession> t1 = new ThreadLocal<>();
    private static SqlSessionFactory factory;
    static {
        InputStream is = null;
        try {
            is = Resources.getResourceAsStream("mybatis-config.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        factory = new SqlSessionFactoryBuilder().build(is);
    }
    /**
     * 创建SqlSession
     * @return sqlSession
     */
    public static SqlSession openSession() {
        SqlSession sqlSession = t1.get();
        if (sqlSession == null) {
            sqlSession = factory.openSession();
            t1.set(sqlSession);
        }
        return sqlSession;
    }
    /**
     * 调用功能方法
     * @param clazz
     * @return Object
     */
    public static Object getMapper(Class clazz) {
        return openSession().getMapper(clazz);
    }
    /**
     * 提交事务,关闭资源
     */
    public static void commit(){
        //1、提交事务
        openSession().commit();
        //2、关闭资源
        openSession().close();
        t1.remove();
    }
    /**
     * 关闭资源
     */
    public static void close(){
        if(openSession()!=null){
            openSession().close();
        }
        t1.remove();
    }
}


二、接口代理方式实现Dao

1、代理开发方式介绍

采用 Mybatis 的代理开发方式实现 DAO 层的开发,这种方式是我们后面进入企业的主流。


Mapper 接口开发方法只需要程序员编写Mapper 接口(相当于Dao 接口),由Mybatis 框架根据接口定义


创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。


Mapper 接口开发需要遵循以下规范

1) Mapper.xml文件中的namespace与mapper接口的全限定名相同
2) Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3) Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
4) Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同


总结:

接口开发的方式: 程序员只需定义接口,就可以对数据库进行操作,那么具体的对象怎么创建?

1.程序员负责定义接口

2.在操作数据库,mybatis框架根据接口,通过动态代理的方式生成代理对象,负责数据库的crud操作


2、源码分析

  • 分析动态代理对象如何生成的?
通过动态代理开发模式,我们只编写一个接口,不写实现类,
我们通过 getMapper() 方法最终获取到 org.apache.ibatis.binding.MapperProxy 代理对象,
然后执行功能,而这个代理对象正是 MyBatis 使用了 JDK 的动态代理技术,
帮助我们生成了代理实现类对象。从而可以进行相关持久化操作。 


分析方法是如何执行的?

动态代理实现类对象在执行方法的时候最终调用了 mapperMethod.execute() 方法,
这个方法中通过 switch 语句根据操作类型来判断是新增、修改、删除、查询操作,
最后一步回到了 MyBatis 最原生的 SqlSession 方式来执行增删改查。  

3、知识小结

接口代理方式可以让我们只编写接口即可,而实现类对象由 MyBatis 生成。

实现规则 :

1.映射配置文件中的名称空间必须和 Dao 层接口的全类名相同。

2.映射配置文件中的增删改查标签的 id 属性必须和 Dao 层接口的方法名相同。

3.映射配置文件中的增删改查标签的 parameterType 属性必须和 Dao 层接口方法的参数相同。

4.映射配置文件中的增删改查标签的 resultType 属性必须和 Dao 层接口方法的返回值相同。 

5.获取动态代理对象 SqlSession 功能类中的 getMapper() 方法。

三、动态sql语句

1、动态sql语句概述

M  Mybatis 的映射文件中,前面我们的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了。

2、动态 SQL 之

我们根据实体类的不同取值,使用不同的 SQL语句来进行查询。比如在 id如果不为空时可以根据id查询,如果username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。

如下图:

UserDao接口

 /**
     * 多条件查询 condition:情况
     * @param user
     * @return User
     */
    public List<User> selectCondition(User user);


UserDaoImpl.xml

   <!-- 多条件查询-->
    <select id="selectCondition" resultType="user" parameterType="user">
        select * from t_user
        <where>
            <if test="id!=0">and id=#{id}</if>
            <if test="username!=null">and username=#{username}</if>
        </where>
    </select>


1.当查询条件id和username都存在时,控制台打印的sql语句如下:

  public void selectByCondition() throws IOException {
        SqlSession sqlSession = MybatisUtil.openSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        User user = new User();
        user.setId(1);
        user.setUsername("王恒杰");
        List<User> users = mapper.selectCondition(user);
        for (User user1 : users) {
            System.out.println(user1);
        }
        MybatisUtil.close(sqlSession);
    }


2.png


当查询条件只有id存在时,控制台打印的sql语句如下:

    @Test
    public void selectByCondition() throws IOException {
        SqlSession sqlSession = MybatisUtil.openSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        User user = new User();
        user.setId(1);
        user.setUsername("杨福君");
        List<User> users = mapper.selectCondition(user);
        for (User user1 : users) {
            System.out.println(user1);
        }
        MybatisUtil.close(sqlSession);
    }
}


3.png

总结语法:

<where>:条件标签。如果有动态条件,则使用该标签代替 where 关键字。
<if>:条件判断标签。
<if test=“条件判断”>
  查询条件拼接
</if>


3、动态 SQL 之<foreach>

循环执行sql的拼接操作,例如:SELECT * FROM student WHERE id IN (1,3,4)。

  • UserDao
    /**
     * foreach查询多个id
     * @param id
     * @return  List<User>
     */
    public List<User> selectByIds(List<Integer> id);


UserDaoImpl.xml配置

   

 <!--
    foreach查询多个id
      collection:参数容器类型, (list-集合, array-数组)。
      open:开始的 SQL 语句。
      close:结束的 SQL 语句。
      item:参数变量名。
      separator:分隔符。
    -->
    <select id="selectByIds" resultType="user">
        select * from t_user
        <where>
            <foreach collection="list" open="id in(" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </where>
    </select>

           

测试类

 @Test
    public void selectByIts() throws IOException {
        SqlSession sqlSession = MybatisUtil.openSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(3);
        list.add(4);
        List<User> users = mapper.selectByIds(list);
        for (User user : users) {
            System.out.println(user);
        }
        MybatisUtil.close(sqlSession);
    }

总结语法:

<foreach>:循环遍历标签。适用于多个参数或者的关系。
    <foreach collection=“”open=“”close=“”item=“”separator=“”>
    获取参数
  </foreach>


属性

collection:参数容器类型, (list-集合, array-数组)。

open:开始的 SQL 语句。

close:结束的 SQL 语句。

item:参数变量名。

separator:分隔符。


4、 include 实现SQL片段抽取

Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的

<!--抽取sql片段简化编写-->
<sql id="selectStudent"> select * from student</sql>
<select id="findById" parameterType="int" resultType="student">
    <include refid="selectStudent"></include> 
    where id=#{id}
</select>
<select id="findByIds" parameterType="list" resultType="student">
    <include refid="selectStudent"></include>
    <where>
        <foreach collection="array" open="id in(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </where>
</select>


总结语法:

我们可以将一些重复性的 SQL 语句进行抽取,以达到复用的效果。

<sql>:抽取 SQL 语句标签。 
<include>:引入 SQL 片段标签。 
<sql id=“片段唯一标识”>抽取的 SQL 语句</sql> <include refid=“片段唯一标识”/>

5、知识小结

MyBatis映射文件配置:

<select>:查询
<insert>:插入
<update>:修改
<delete>:删除
<where>:where条件
<if>:if判断
<foreach>:循环
<sql>:sql片段抽取

四、分页插件

1、分页插件介绍

  • 分页可以将很多条结果进行分页显示。
  • 如果当前在第一页,则没有上一页。如果当前在最后一页,则没有下一页。
  • 需要明确当前是第几页,这一页中显示多少条结果。
  • MyBatis分页插件总结

  • 2.1.在企业级开发中,分页也是一种常见的技术。而目前使用的 MyBatis 是不带分页功能的,如果想实现分页的 功能,需要我们手动编写 LIMIT 语句。但是不同的数据库实现分页的 SQL 语句也是不同的,所以手写分页 成本较高。这个时候就可以借助分页插件来帮助我们实现分页功能。

   PageHelper:第三方分页助手。将复杂的分页操作进行封装,从而让分页功能变得非常简单。


2、分页插件的使用

MyBatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据

  • 开发步骤:

①导入与PageHelper的jar包

jsqlparser-3.1.jar

pagehelper-5.1.10.jar

②在mybatis核心配置文件中配置PageHelper插件

  <!--
    注意:分页助手的插件 配置在通用Mapper之前
    interceptor:拦截器
     -->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageHelper">
           <!-- 指定方言 dialect:方言 -->
         <property name="dialect" value="mysql"/>
        </plugin>
    </plugins>


③测试分页数据获取

public void  testPageHelper() throws IOException {
        SqlSession sqlSession = MybatisUtil.openSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        //通过分页助手来实现分页功能
        // 第一页:显示3条数据
        //PageHelper.startPage(1,3);
        // 第二页:显示3条数据
        //PageHelper.startPage(2,3);
        // 第三页:显示3条数据
        PageHelper.startPage(1,2);
        //调用实现类的方法,接收结果
        List<User> users = mapper.selectUserAll();
        // 处理结果
        for (User user : users) {
            System.out.println(user);
        }
        //获取分页相关参数
     PageInfo<User> info = new PageInfo<>(users);
     System.out.println("总条数"+info.getTotal());
     System.out.println("总页数"+info.getPages());
     System.out.println("当前页面"+info.getPageNum());
     System.out.println("每页显示条数"+info.getPageSize());
     System.out.println("上一页"+info.getPrePage());
     System.out.println("下一页"+info.getNextPage());
     System.out.println("是否是第一页"+info.isIsFirstPage());
     System.out.println("是否是最后一页"+info.isIsLastPage());
     MybatisUtil.close(sqlSession);
 }
}

3、分页插件的参数获取

//其他分页的数据
PageInfo<User> pageInfo = new PageInfo<User>(select);
System.out.println("总条数:"+pageInfo.getTotal());
System.out.println("总页数:"+pageInfo.getPages());
System.out.println("当前页:"+pageInfo.getPageNum());
System.out.println("每页显示长度:"+pageInfo.getPageSize());
System.out.println("是否第一页:"+pageInfo.isIsFirstPage());
System.out.println("是否最后一页:"+pageInfo.isIsLastPage());

4、分页插件知识小结

分页:可以将很多条结果进行分页显示。

  • 分页插件 jar 包: pagehelper-5.1.10.jar jsqlparser-3.1.jar
  • :集成插件标签。
  • 分页助手相关 API
  •   1. PageHelper:分页助手功能类。

    2. startPage():设置分页参数

    3. PageInfo:分页相关参数功能类。

     4. getTotal():获取总条数

    5. getPages():获取总页数

    6. getPageNum():获取当前页

     7. getPageSize():获取每页显示条数

    8. getPrePage():获取上一页

    9. getNextPage():获取下一页

      10. isIsFirstPage():获取是否是第一页

    11. isIsLastPage():获取是否是最后一页


五、结果映射ResultMap

1、简化开发步骤 mapper.xml
2、自动进行ORM映射 前提:表中字段名和实体类中的属性名一致
3、查询优化 缓存Cache

1、Mybatis自动封装(ORM映射)

  • Mybatis自动ORM映射时,表中的字段名和实体类名一致

 

2、手工实现封装(ORM映射)mapResult

多表-->Mybatis不自动映射,可以匹配对应关系结果映射
作用:用于查询结果和实体类不匹配时,完成列名和属性名对应关系的映射
主键映射用id,其他用result

UserDaoImpl.xml实现手工映射(ORM映射)

<mapper namespace="com.tjcu.dao.UserDao">
    <!--结果映射 id:唯一标识 type:要映射的实体类名 全限定名,可以书写别名-->
    <resultMap id="UserResultMap" type="user">
        <!--主键映射比较特殊 column:数据库列 property:实体类属性名-->
        <id column="id" property="id1"></id>
        <result column="username" property="username1"></result>
        <result column="password" property="password1"></result>
        <result column="age" property="age1"></result>
        <result column="birthday" property="birthday1"></result>
    </resultMap>
    <!--查询所有 resultMap映射-->
    <select id="selectUserAll" resultMap="UserResultMap">
        select *
        from t_user;
    </select>
</mapper>


3、单表起别名实现ORM自动封装【简化操作】

单表操作简化写法,通过列名对应实体属性名

  • 给数据库中表的列名取别名

9.png


 

   </select>
    <!--查询所有  单表简化方式-->
    <select id="selectUserAll" resultType="user">
        select id as id1,
         username as username1, 
         password as password1, 
         age as age1,
         birthday as birthday1
        from t_user;
    </select>

五、mybatis+Struts2整合开发

1、分析框架的特点
2、根据框架特点完成整合
3、开发


1、编码流程

1、建表
2、实体
3、dao接口【Mybatis框架】
4、service接口
5、service实现类
6、action【Struts2框架】
7、jsp


2、Struts2框架+Mybatis框架整合

1、搭建开发环境

1、搭建开发环境
a、引入jar包
   struts2 核心jar 三方依赖jar包 Servlet包 jstl jsp 验证码
   mybatis  核心jar包 三方依赖jar包 数据库驱动jar包 Junit测试jar包
   注意:
     (1)jar包存放WEB-INF的lib目录中
     (2)jar包冲突 避免相同Jar包出现多次 选择依据:就高不就低
 b、引入配置文件
    Struts2 核心配置文件 struts.xml 名字固定 位置固定:src下
    Mybatis: 核心配置文件 mybatis-config.xml 名字随意 位置随意 建议 src下
    日志相关配置文件 log4j.properties 名字随意 位置随意 建议 src下
    mapper文件模型 xxxDaoImpl.Xml 名字随意 建议:dao层
    数据库链接参数配置文件:jdbc.properties
c、初始化配置 让框架生效
   Struts2 Web.xml中核心过滤器配置 拦截所有请求交由Struts2处理
   Mybatis 数据库链接配置


mybatis+struts2整合开发jar包+环境配置:

gitee文件夹名:mybatis+struts2整合开发jar包环境配置:

https://gitee.com/wanghengjie563135/mybatis_struts2.git


2、编程步骤

1、建表
2、创建实体类
3、实体类起别名
4、创建Dao接口
5、书写Dao接口 书写Dao接口对应的mapper文件
6、注册Mapper 在mybatis-config.xml配置完成mapper文件路径注册
7、测试 用Mybatis中的Dao接口实现
8、创建Service接口
9、实现Service接口 MybatisUtil工具类
10、测试Service  测试业务方法是否正确 创建业务实现对象调用业务方法查看结果
11、Action 接收数据 调用业务 跳转页面
     (1)写类 服务方法
     (2)在struts.xml中进行配置
12、jsp展示数据 EL表达式+EL标签库


六、案例实战(mybatis+struts2+jsp)

注:全部源代码在githee仓库:详细源代码见文章底部

(1)搭建开发环境

1、jar包

jar包Gitee位置:https://gitee.com/wanghengjie563135/mybatis_struts2.git

10.png


2、初始化配置

初始化配置Gitee位置:https://gitee.com/wanghengjie563135/mybatis_struts2.git

11.png



1、web.xml

struts2核心过滤器配置 拦截所有请求交由Struts2处理

 

  <filter>
        <filter-name>struts</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


2、struts.xml

<struts>
  <package name="user" extends="struts-default" namespace="/user">
  <action name="queryAll" class="com.tjcu.action.UserAction">
    <result name="success">/queryAll.jsp</result>
  </action>
  </package>
</struts>


3、mybatis-config.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>
    <!--引入数据库链接的配置文件jdbc.properties-->
    <properties resource="jdbc.properties"></properties>
    <!--起别名优化-->
    <typeAliases>
        <typeAlias type="com.tjcu.entity.User" alias="user"></typeAlias>
<!--        !给实体类所在的包下所有类起别名 name:书写实体类所在的包 自动取别名 默认:类名或类首字母小写 User/user-->
        <package name="com.tjcu.entity"/>
    </typeAliases>
    <!--
      注意:分页助手的插件 配置在通用Mapper之前
      interceptor:拦截器
       -->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>
            <!--POOLED:OOMybatis框架默认连接池-->
            <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>
    <!--将mapper文件路径注册到mybatis核心配置文件中-->
    <mappers>
        <mapper resource="com/tjcu/dao/UserDaoImpl.xml"></mapper>
    </mappers>
</configuration>

 4、UserDaoImpl.xml

 

<mapper namespace="com.tjcu.dao.UserDao">
    <select id="selectUserAll" resultType="user">
        select * from t_user;
    </select>
</mapper>


5、jdbc.properties

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC
username=root
password=root

6、log4j.properties

log4j.rootLogger=DEBUG, stdout
# SqlMap logging configuration...
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.cache.CacheModel=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientImpl=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.builder.xml.SqlMapParser=DEBUG
log4j.logger.com.ibatis.common.util.StopWatch=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
# 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

(2)编程

1、建表12.png

2、创建实体类

 

    private Integer id;
    private String username;
    private String password;
    private int age;
    private Date birthday;

3、实体类起别名

 

    <!--配置别名-->
<typeAliases>
     <typeAlias type="com.tjcu.entity.User" alias="user"></typeAlias>
 </typeAliases>

4、创建Dao接口

 

    /**
     * 查询所有
     * @return用户集合
     */
    public List<User> selectUserAll();

5、书写Dao接口mapper.xml实现

 

<mapper namespace="com.tjcu.dao.UserDao">
    <select id="selectUserAll" resultType="user">
        select * from t_user;
    </select>
</mapper>


6、注册Mapper mybatis-config.xml中实现

  <!--  配置mappers-->
    <mappers>
        <mapper resource="com/tjcu/dao/UserDaoImpl.xml"></mapper>
    </mappers>


7、创建Service接口

  /**
     *  查询所有
     * @return
     */
    public List<User> queryAll();

8、实现Service接口

13.png

  @Override
    public List<User> queryAll() {
        //调用DAO
        UserDao mapper = (UserDao) MybatisUtil.getMapper(UserDao.class);
        List<User> users = mapper.selectUserAll();
        MybatisUtil.close();
        return  users;
    }


9、测试Service

   @Test
    public void testSelectAll() throws IOException {
        UserDao userDAO = (UserDao) MybatisUtil.getMapper(UserDao.class);
        List<User> users = userDAO.selectUserAll();
        for (User user : users) {
            System.out.println(user);
        }
        MybatisUtil.close();
    }


10、Action 接收数据 调用业务 跳转页面

(1)写类 服务方法

package com.tjcu.action;
import com.opensymphony.xwork2.Action;
import com.tjcu.entity.User;
import com.tjcu.service.UserServiceImpl;
import java.util.List;
/**
 * @author 王恒杰
 * @version 1.0
 * @date 2021/10/13 11:11
 * @email 1078993387@qq.com
 * @Address 天津
 * @Description:
 */
public class UserAction {
    //接收数据
    /**
     * 替换request作用域传递数据
     */
    private List<User> users;
    public String execute() throws Exception {
        //调用业务
        UserServiceImpl userService = new UserServiceImpl();
        users = userService.queryAll();
        //跳转页面
        return Action.SUCCESS;
    }
    public List<User> getUsers() {
        return users;
    }
    public void setUsers(List<User> users) {
        this.users = users;
    }
}

 

(2)在struts.xml中进行配置

<struts>
  <package name="user" extends="struts-default" namespace="/user">
  <action name="queryAll" class="com.tjcu.action.UserAction">
    <result name="success">/queryAll.jsp</result>
  </action>
  </package>
</struts>


11、jsp展示数据 EL表达式+EL标签库

<%@page contentType="text/html; UTF-8" pageEncoding="utf-8" isELIgnored="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<style>
    td,th {
        /*设置边框*/
        border: 1px solid black;
    }
</style>
<body>
<center>
<table style=" border: 1px solid black;border-collapse: collapse;">
    <%--
       private Integer id;
        private String username;
        private String password;
        private int age;
        private Date birthday;
    --%>
    <tr>
        <td>ID</td>
        <td>NAME</td>
        <td>PASSWORD</td>
        <td>AGE</td>
        <td>BIRTHDAY</td>
        <td>删除</td>
        <td>修改</td>
    </tr>
    <c:forEach var="user" items="${requestScope.users}">
        <tr>
            <td>${user.id}</td>
            <td>${user.username}</td>
            <td>${user.password}</td>
            <td>${user.age}</td>
            <td><fmt:formatDate value="${user.birthday}" pattern="yyyy年MM月dd日"></fmt:formatDate></td>
            <td>删除</td>
            <td>修改</td>
        </tr>
    </c:forEach>
</table>
</center>
</body>
</html>

mybatis+struts2整合案例源代码在githee仓库:

程序员小王Gitee:https://gitee.com/wanghengjie563135/mybatis.git

 

七、解决Mybatis报错问题

1:Type interface com.tjcu.dao.UserDao is not known to the MapperRegistry.

详细可参考链接:https://www.wolai.com/wnaghengjie/ifdVAvtCZ7D47ukWqg22RP?theme=light

JavaWeb项目 jsp页面无法加载样式问题:

详细可参考链接:

https://blog.csdn.net/weixin_44385486/article/details/120735230


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
11天前
|
SQL Java 数据库连接
深入探索MyBatis Dynamic SQL:发展、原理与应用
深入探索MyBatis Dynamic SQL:发展、原理与应用
|
13天前
|
SQL XML 数据库
后端数据库开发高级之通过在xml文件中映射实现动态SQL
后端数据库开发高级之通过在xml文件中映射实现动态SQL
19 3
|
13天前
|
SQL XML Java
后端数据库开发JDBC编程Mybatis之用基于XML文件的方式映射SQL语句实操
后端数据库开发JDBC编程Mybatis之用基于XML文件的方式映射SQL语句实操
28 3
|
13天前
|
SQL Java 数据库连接
2万字实操案例之在Springboot框架下基于注解用Mybatis开发实现基础操作MySQL之预编译SQL主键返回增删改查
2万字实操案例之在Springboot框架下基于注解用Mybatis开发实现基础操作MySQL之预编译SQL主键返回增删改查
24 2
|
9天前
|
SQL 缓存 Java
Java框架之MyBatis 07-动态SQL-缓存机制-逆向工程-分页插件
Java框架之MyBatis 07-动态SQL-缓存机制-逆向工程-分页插件
|
9天前
|
SQL Java 数据库连接
MyBatis动态SQL
MyBatis动态SQL
15 0
|
12天前
|
SQL Java 数据库连接
Mybatis日志SQL解析
Mybatis日志SQL解析
11 0
|
13天前
|
JSON 前端开发 数据格式
MyBatis-Plus动态分页查询
MyBatis-Plus动态分页查询
12 0
|
13天前
|
SQL Java 数据库连接
Mybatis动态SQL语句总结
Mybatis动态SQL语句总结
|
16天前
|
SQL Java 数据库连接
【MyBatis】MyBatis操作数据库(二):动态SQL、#{}与${}的区别
【MyBatis】MyBatis操作数据库(二):动态SQL、#{}与${}的区别
16 0