Mybatis--进阶

MyBatis--2.进阶

MyBatis的Dao层实现

传统开发方式

Dao中的接口类:

public interface UserMapper {
    public List<User> findAll() throws IOException;

}

Dao中接口的实现类:

public class UserMapperImpl implements UserMapper {
    @Override
    public List<User> findAll() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<User> userList = sqlSession.selectList("userMapper.findAll");
        return userList;
    }
}

再在其他类需要进行数据库操作时调用UserMapperImpl的findAll方法

代理开发方式

编写接口:

测试代理:

parameterType类型就按照正常类型,不按照泛型

至于不同的返回类型resulttype如何写需要按照泛型,参考:

mybatis的resultType_mybatis resulttype_beidaol的博客-CSDN博客

MyBatis映射文件深入

动态sql语句

动态sql字面意思就是传递参数不同sql语句动态变化

动态sql语句的重要表情发标签

  • if

    下面#{}用到的是传入参数的属性

        <select id="findAll" resultType="com.xxx.User" parameterType="com.xxx.User">
            select  * from user where  username=#{username} and password=#{password}
    --         判断如果id!=0执行后面的
            <if test="id!=0">
                and id=#{id}
            </if>
        </select>
    
  • choose(when,otherwise)

  • trim(where,set)

        <select id="findAll" resultType="com.xxx.User" parameterType="com.xxx.User">
            select  * from user
    --         和之前的where相同
            <where>
    --         判断如果id!=0执行后面的
            <if test="id!=0">
                and id=#{id}
            </if>
                <if test="password!=null">
                    and password=#{password}
                </if>
            </where>
        </select>
    
  • foreach

   
<select id="findAll" resultType="com.xxx.User" parameterType="list">
        select  * from user
        <where>
--         本处传递的是一个list,如果是数组参数collection为array,open表示以什么开始,
--             close表示以什么结束,item是变量负责接收集合的每一个
--             separator是封装符,通过它拼接使用的item;另外sql语句in和or类似
            <foreach collection="list" open="id in(" close=")" item="id" separator=","></foreach>
--             这就是item
             #{id}
        </where>
    </select>

sql片段的抽取

<!--    抽取-->
     <sql id="selectUser">select * from user </sql>
<!--    引入-->
    <select id="das">
        <include refid="selectUser"></include>
    </select>

MyBatis核心配置文件深入

typeHandlers标签

默认的类型转换器

当默认的转换器不符合需求时,我们使用该标签自定义转换器

开发步骤:

  1. 定义转换继承类BaseTypeHandler

  2. 覆盖四个未实现的方法,其中setNonNullParameter为java程序设置数据到数据库的回调方法,getNullableResult为查询时mysql的字符串类型转换为java的Type类型方法

    public class DateHandler extends BaseTypeHandler<Date> {
        //    将java类型转换成数据库需要的类型
        @Override
        public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
            long time = date.getTime();
            preparedStatement.setLong(i,time);
    
        }
        // 数据库类型转java类型
        //String参数是要转换的字段名称
        //resultset是查询的结果集
        @Override
        public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
    //        获得结果集需要的数据(long)转换为date类型返回
            long aLong = resultSet.getLong(s);
            Date date = new Date(aLong);
            return date;
        }
        // 数据库类型转java类型
        @Override
        public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
            long aLong = resultSet.getLong(i);
            Date date = new Date(aLong);
            return date;
        }
        // 数据库类型转java类型
        @Override
        public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
            long aLong = callableStatement.getLong(i);;
            Date date = new Date(aLong);
            return date;
        }
    
    }
    
  3. 在MyBatis核心配置文件中进行注册

    <!--    自定义类型处理器-->
        <typeHandlers>
            <typeHandler handler="com.xxx.handler.DateHandler"></typeHandler>
        </typeHandlers>
    
  4. 测试转换是否正确

plugins标签

开发步骤:

  1. 导入PageHelper的坐标

    <!--    导入通用PageHlper坐标-->
        <dependency>
          <groupId>com.github.pagehelper</groupId>
          <artifactId>pagehelper</artifactId>
          <version>3.7.5</version>
        </dependency>
        <dependency>
          <groupId>com.github.jsqlparser</groupId>
          <artifactId>jsqlparser</artifactId>
          <version>0.9.1</version>
        </dependency>
    
  2. 再mybatis核心配置文件中配置PageHelper插件

    <!--    配置分页助手插件-->
        <plugins>
            <plugin interceptor="com.github.pagehelper.PageHelper">
    <!--            指定参数,指定数据库方言-->
                <property name="dialect" value="mysql"/>
            </plugin>
        </plugins>
    
  3. 测试分页数据获取

        public  void  test1() throws IOException {
    
    //        获取配置文件Resources是ibatis包下的
            InputStream resourceAsFile = Resources.getResourceAsStream("sqlMapConfig.xml");
    //        获得session工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsFile);
    //        获得session会话对象
            SqlSession sqlSession = sqlSessionFactory.openSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    //        设置分页相关参数
            PageHelper.startPage(1,2);
    
            List<User> userList = mapper.findAll();
            for (User user : userList) {
                System.out.println(user);
            }
    //        获得与分页相关的参数
            PageInfo<User> pageInfo = new PageInfo<User>(userList);
            System.out.println("当前页:"+pageInfo.getPageNum());
            System.out.println("每页条数:"+pageInfo.getPageSize());
            System.out.println("总条数:"+pageInfo.getTotal());
            System.out.println("总页数:"+pageInfo.getPages());
            System.out.println("上一页:"+pageInfo.getPrePage());
            System.out.println("下一页:"+pageInfo.getNextPage());
            System.out.println("是否是第一个:"+pageInfo.isIsFirstPage());
            System.out.println("是否是最后一个:"+pageInfo.isIsLastPage());
    
    //        释放资源
            sqlSession.close();
        }
    

结果:

MyBatis的多表操作

一对一查询

第一种配置方式:

orders类:

public class Order {
    private  int id;
    private Date ordertime;
    private  double total;
    //当前订单属于那个用户
    private User user;
    其他get和set方法。。。
    }

映射文件中:

<?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.xxx.Mapper.OrderMapper">
    <resultMap id="orderMap" type="com.xxx.Order">
<!--        手动指定字段与实体属性的映射关系
            column:数据库字段名称
            property:实体属性名
            id:是主键-->
        <id column="oid" property="id"></id>
        <result column="ordertime" property="ordertime"></result>
        <result column="total" property="total"></result>
        <result column="uid" property="user.id"></result>
        <result column="username" property="user.username"></result>
        <result column="password" property="user.password"></result>
        <result column="birthday" property="user.birthday"></result>
    </resultMap>
<select id="findAll" resultMap="orderMap">
    select *,o.id oid from orders o,user u where o.uid=u.id
</select>
</mapper>

另外一种映射文件写法:

<resultMap id="orderMap" type="com.xxx.Order">
<!--        手动指定字段与实体属性的映射关系
            column:数据库字段名称
            property:实体属性名
            id:是主键-->
        <id column="oid" property="id"></id>
        <result column="ordertime" property="ordertime"></result>
        <result column="total" property="total"></result>
<!--        两个参数:前者是order中的user属性,后者是属性类型-->
        <association property="user" javaType="com.xxx.User">
            <id column="uid" property="id"></id>
            <result column="username" property="username"></result>
            <result column="password" property="password"></result>
            <result column="birthday" property="birthday"></result>
        </association>
   

一对多

<resultMap id="userMap" type="user">
    <id column="uid" property="id"></id>
    <result column="username" property="username"></result>
    <result column="password" property="password"></result>
<!--    配置集合信息
        property类集合属性名称
        ofType当前集合的数据类型-->
    <collection property="orderList" ofType="order">
        <id column="oid" property="id"></id>
        <result column="ordertime" property="ordertime"></result>
    </collection>

</resultMap>

其他和一对一查询类似

多对多

  <resultMap id="userRoleMap" type="user">
        <id column="userId" property="id"></id>
        <result column="username" property="username"></result>
<!--        user内部的roleList信息-->
        <collection property="roleList" ofType="role">
            <id column="role" property="id"></id>
            <result column="roleName" property="roleName"></result>

        </collection>
    </resultMap>
    <select id="findUserAndRoleAll" resultMap="userRoleMap">
        select  * from user u, sys_user_role ur,sys_role r where  u.id=ur.userId and ur.roleId = r.id
    </select>

自定义别名

核心配置文件

posted @ 2023-08-13 16:15  云归处、  阅读(7)  评论(0编辑  收藏  举报