Mybatis框架-第一篇

第一章:认识框架

1.1-什么是框架

​ 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种 定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面而后者是从目的方面给出的定义。

​ 简而言之,框架其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统。简单说就是使用别 人搭好的舞台,你来做表演。而且,框架一般是成熟的,不断升级的软件。

1.2-框架要解决的问题

框架要解决的最重要的一个问题是技术整合的问题,在 J2EE 的 框架中,有着各种各样的技术,不同的 软件企业需要从 J2EE 中选择不同的技术,这就使得软件企业最终的应用依赖于这些技术,技术自身的复杂性和技 术的风险性将会直接对应用造成冲击。而应用是软件企业的核心,是竞争力的关键所在,因此应该将应用自身的设 计和具体的实现技术解耦。这样,软件企业的研发将集中在应用的设计上,而不是具体的技术实现,技术实现是应 用的底层支撑,它不应该直接对应用产生影响。

框架一般处在低层应用平台(如 J2EE)和高层业务逻辑之间的中间层。

1.3-软件分层开发的重要性

框架的重要性在于它实现了部分功能,并且能够很好的将低层应用平台和高层业务逻辑进行了缓和。为了实现 软件工程中的“高内聚、低耦合”。把问题划分开来各个解决,易于控制,易于延展,易于分配资源。我们常见的 MVC 软件设计思想就是很好的分层思想。

通过分层更好的实现了各个部分的职责,在每一层将再细化出不同的框架,分别解决各层关注的问题 。

1.4-分层开发下常见的框架

常见的 JavaEE 开发框架:

Mybatis:解决数据的持久化问题的框架

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。

作为持久层的框架,还有一个封装程度更高的框架就是Hibernate,但这个框架因为各种原因目前在国内的 流行程度下降太多,现在公司开发也越来越少使用。目前使用 Spring Data 来实现数据持久化也是一种趋势。

Spring MVC:解决 WEB 层问题的 MVC 框架

Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts 2(一般老项目使用)等。

Spring:解决技术整合问题的框架

Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。

1.5-Mybaits框架概述

mybatis 是一个优秀的基于 java 的持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql 语句本身, 而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。

mybatis 通过 xml 或注解的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并 返回。

采用 ORM 思想解决了实体和数据库映射的问题,对 jdbc 进行了封装,屏蔽了 jdbc api 底层访问细节,使我 们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。

第二章:JDBC编程分析

2.1-JDBC编程代码

import java.sql.*;
/**
* 查询所有的学生信息
*/
public class Demo6DQL {
 public static void main(String[] args) throws SQLException {
     //1) 得到连接对象
     Connection connection =
    DriverManager.getConnection("jdbc:mysql://localhost:3306/day24","root","root");
     //2) 得到语句对象
     Statement statement = connection.createStatement();
     //3) 执行 SQL 语句得到结果集 ResultSet 对象
     ResultSet rs = statement.executeQuery("select * from student");
     //4) 循环遍历取出每一条记录
     while(rs.next()) {
         int id = rs.getInt("id");
         String name = rs.getString("name");
         boolean gender = rs.getBoolean("gender");
         Date birthday = rs.getDate("birthday");
         //5) 输出的控制台上
         System.out.println("编号:" + id + ", 姓名:" + name + ", 性别:" + gender + ", 生日:" +
        birthday);
     }
     //6) 释放资源
     rs.close();
     statement.close();
     connection.close();
 }
}

2.2-JDBC问题分析

1、数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

2、Sql 语句在代码中硬编码,造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。

3、使用 preparedStatement 向占有位符号传参数存在硬编码,因为 sql 语句的 where 条件不一定,可能 多也可能少,修改 sql 还要修改代码,系统不易维护。

4、对结果集解析存在硬编码(查询列名),sql 变化导致解析代码变化,系统不易维护,如果能将数据库记 录封装成 pojo 对象解析比较方便。

第三章:MyBaits框架快速入门

3.1-官网下载

https://mybatis.org/mybatis-3/zh/getting-started.html

3.2-搭建MyBatis开发环境

数据库脚本

/*
SQLyog Ultimate v12.09 (64 bit)
MySQL - 5.5.40 : Database - db7
*********************************************************************
*/
CREATE DATABASE /*!32312 IF NOT EXISTS*/`db7` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `db7`;

/*Table structure for table `user` */

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  `sex` varchar(22) DEFAULT NULL,
  `address` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;

/*Data for the table `user` */

insert  into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (1,'张三丰','2018-12-12','male','海南'),(2,'李四','2019-09-04','female','南京'),(3,'王五','2020-02-12','male','北京'),(4,'赵六','2020-01-01','female','上海'),(5,'阿珂','2019-09-09','female','广州'),(8,'张三','2020-02-04','male','杭州'),(9,'白起','2018-12-12','male','深圳'),(10,'鲁班','2018-12-12','male','深圳'),(15,'阿珂2','2019-09-09','female','广州');

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

创建Maven工程

Groupid:cn.lpl666 
ArtifactId:Pro06TestMybatis01 
Packing:jar 

添加MyBatis坐标

在 pom.xml 文件中添加 Mybatis3.4.5 的坐标,如下:

<dependencies>
    <!--单元测试-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!--mybatis-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.5</version>
    </dependency>
    <!--mysql-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.26</version>
      <scope>runtime</scope>
    </dependency>
    <!--log4j-->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>
  </dependencies>

创建User实体类

package cn.lpl666.domain;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable {
  private int id;
  private String username;
  private Date birthday;
  private String sex;
  private String address;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getUsername() {
    return username;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public Date getBirthday() {
    return birthday;
  }

  public void setBirthday(Date birthday) {
    this.birthday = birthday;
  }

  public String getSex() {
    return sex;
  }

  public void setSex(String sex) {
    this.sex = sex;
  }

  public String getAddress() {
    return address;
  }

  public void setAddress(String address) {
    this.address = address;
  }

  @Override
  public String toString() {
    return "User{" +
            "id=" + id +
            ", username='" + username + '\'' +
            ", birthday=" + birthday +
            ", sex='" + sex + '\'' +
            ", address='" + address + '\'' +
            '}';
  }
}

编写持久层接口 IUserDao

package cn.lpl666.dao;

import cn.lpl666.domain.User;

import java.util.List;

/**
 * 用户持久层操作
 */
public interface IUserDao {
  /**
   * 查询用户列表
   * @return
   */
  List<User> findAll();
}

编写持久层接口的映射文件 IUserDao.xml

要求:

  • 创建位置:必须和持久层接口在相同的包中。
  • 名称:必须以持久层接口名称命名文件名,扩展名是.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="cn.lpl666.dao.IUserDao">
    <!--配置查询所有操作,id值要和接口中的方法名称一致-->
    <select id="findAll" resultType="cn.lpl666.domain.User">
        select * from user
    </select>
</mapper>

编写 SqlMapConfig.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>
    <!--配置Mybatis环境-->
    <environments default="mysql">
        <!--配置mysql环境-->
        <environment id="mysql">
            <!--配置事务类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据连接信息,用的是数据源(连接池)-->
            <dataSource type="POOLED">
                <!--数据库驱动-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!--数据库连接-->
                <property name="url" value="jdbc:mysql://localhost:3306/db7"/>
                <!--登录用户名-->
                <property name="username" value="root"/>
                <!--密码-->
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!--告知mybatis映射配置的位置-->
    <mappers>
        <mapper resource="cn/lpl666/dao/IUserDao.xml"/>
    </mappers>
</configuration>

编写测试类

package cn.lpl666.test;

import cn.lpl666.dao.IUserDao;
import cn.lpl666.domain.User;
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;
import java.util.List;

public class MybatisTest01 {
  public static void main(String[] args) throws IOException {
    // 1. 读取配置文件
    InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    // 2. 创建SqlSessionFactory构建者对象
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    //3.使用构建者创建工厂对象 SqlSessionFactory
    SqlSessionFactory sqlSessionFactory = builder.build(resourceAsStream);
    // 4.使用 SqlSessionFactory 生产 SqlSession 对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    // 5.使用 SqlSession 创建 dao 接口的代理对象
    IUserDao mapper = sqlSession.getMapper(IUserDao.class);
    // 6.使用代理对象执行查询方法
    List<User> list = mapper.findAll();
    System.out.println(list);
    // 7.释放资源
    resourceAsStream.close();
    sqlSession.close();

  }
}

基于注解的 mybatis 使用

在使用基于注解的 Mybatis 配置时,请移除 xml 的映射配置(IUserDao.xml)。

在持久层接口中添加注解

package cn.lpl666.dao;

import cn.lpl666.domain.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * 用户持久层操作
 */
public interface IUserDao {
  /**
   * 查询用户列表
   * @return
   */
  @Select("select * from user")
  List<User> findAll();
}

修改 SqlMapConfig.xml

<!-- 告知 mybatis 映射配置的位置 -->
<mappers>
	<mapper class="cn.lpl666.dao.IUserDao"/>
</mappers>

第四章:基于代理 Dao 实现 CRUD 操作

数据库脚本(同上)

创建Maven工程(同上)

添加Mybatis坐标(同上)

创建User实体类(同上)

创建QueryVo实体类

package cn.lpl666.domain;

/**
 * 自定义查询对象
 */
public class QueryVo {
  private User user;

  public User getUser() {
    return user;
  }

  public void setUser(User user) {
    this.user = user;
  }
}

编写持久层接口IUserDao

package cn.lpl666.dao;

import cn.lpl666.domain.QueryVo;
import cn.lpl666.domain.User;

import java.util.List;

/**
 * 用户持久层操作
 */
public interface IUserDao {
  /**
   * 查询用户列表
   * @return
   */
  List<User> findAll();

  /**
   * 保存用户(添加新的用户数据)
   * @param user
   */
  void saveUser(User user);

  /**
   * 更新用户
   * @param user
   */
  void updateUser(User user);

  /**
   * 移除用户
   * @param id
   */
  void delUser(int id);

  /**
   * 根据id查询用户
   * @param id
   */
  User findOne(int id);

  /**
   * 根据用户名模糊查询
   * @param username
   */
  List<User> findByUserName(String username);

  /**
   * 查询用户总数量
   * @return
   */
  int getTotalCount();

  /**
   * 据用户名模糊查询(自定义查询对象)
   * @param vo
   * @return
   */
  List<User> findByUserNameVo(QueryVo vo);
}

编写jdbc配置文件

文件名:jdbc.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/db7
username=root
password=root

持久层接口映射文件IUserDao.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="cn.lpl666.dao.IUserDao">

    <!--查询所有用户-->
    <select id="findAll" resultType="user">
        select * from user
    </select>
    <!--添加新的用户信息,并获取用户的id-->
    <insert id="saveUser" parameterType="cn.lpl666.domain.User">
        <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
            select last_insert_id()
        </selectKey>
        INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address});
    </insert>
    <!--根据id更新用户-->
    <update id="updateUser" parameterType="cn.lpl666.domain.User">
        UPDATE USER SET username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} WHERE id=#{id}
    </update>
    <!--根据id删除用户-->
    <delete id="delUser" parameterType="int">
        DELETE FROM USER WHERE id=#{id};
    </delete>
    <!--根据id查询用户-->
    <select id="findOne" parameterType="int" resultType="cn.lpl666.domain.User">
        select * from user where id=#{id}
    </select>
    <!--根据用户名查询用户-->
    <select id="findByUserName" parameterType="string" resultType="cn.lpl666.domain.User">
        select * from user where username like #{username}
    </select>
    <!--查询用户总数量-->
    <select id="getTotalCount" resultType="int">
        select count(id) from user
    </select>
    <!--根据用户名查询用户-自定义查询对象-->
    <select id="findByUserNameVo" parameterType="cn.lpl666.domain.QueryVo" resultType="cn.lpl666.domain.User">
        select * from user where username like #{user.username}
    </select>

</mapper>

SqlMapConfig.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>
    <!--resources,指定外联数据库配置文件-->
    <properties resource="jdbc.properties">
        <!--<property name="driver" value="com.mysql.jdbc.Driver"/>-->
        <!--<property name="url" value="jdbc:mysql://localhost:3306/db7"/>-->
        <!--<property name="username" value="root"/>-->
        <!--<property name="password" value="root"/>-->
    </properties>
    <!--配置实体类映射,后期在dao配置文件中,可以不用写全限名称,而直接使用实体类名-->
    <typeAliases>
        <!--<typeAlias type="cn.lpl666.domain.User" alias="user"></typeAlias>-->
        <package name="cn.lpl666.domain"></package>
    </typeAliases>
    <!--配置mybatis环境-->
    <environments default="mysql">
        <!--配置mysql环境-->
        <environment id="mysql">
            <!--配置事务类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据库连接信息,连接池(数据源)-->
            <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>

    <!--告诉mybatis映射配置的位置-->
    <mappers>
        <!--IUserDao-->
        <!--<mapper resource="cn/lpl666/dao/IUserDao.xml"/>-->
        <!--可以映射该位置下的所有dao.xml配置-->
        <package name="cn.lpl666.dao"></package>
    </mappers>
</configuration>

测试类

package cn.lpl666;

import static org.junit.Assert.assertTrue;

import cn.lpl666.domain.QueryVo;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import cn.lpl666.dao.IUserDao;
import cn.lpl666.domain.User;
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;
import java.util.List;

public class AppTest {
    private static InputStream is;
    private static SqlSession sqlSession;
    private static IUserDao dao;
    @Before
    public void init(){
        // 读取配置文件
        try {
            is = Resources.getResourceAsStream("SqlMapConfig.xml");
            // 创建工厂构建者对象
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            // 创建SqlSessionFactory工厂对象
            SqlSessionFactory sqlSessionFactory = builder.build(is);
            // 创建SqlSession对象
            sqlSession = sqlSessionFactory.openSession();
            // 创建dao代理对象
            dao = sqlSession.getMapper(IUserDao.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @After
    public  void destroy() throws IOException {
        sqlSession.commit();
        is.close();
        sqlSession.close();
    }

    /**
     * 查询
     */
    @Test
    public void getAll() throws IOException {
        List<User> all = dao.findAll();
        System.out.println(all);
    }

    /**
     * 插入
     */
    @Test
    public void add(){
        User user = new User();
        user.setAddress("深圳");
        user.setUsername("白起");
        user.setBirthday("2018-12-12");
        user.setSex("male");
        System.out.println("插入前:" + user);
        dao.saveUser(user);
        System.out.println("插入前:" + user);
    }

    /**
     * 更新
     */
    @Test
    public void update(){
        User user = new User();
        user.setId(1);
        user.setAddress("海南");
        user.setUsername("张三丰");
        user.setBirthday("2018-12-12");
        user.setSex("male");
        dao.updateUser(user);
    }

    /**
     * 删除
     */
    @Test
    public void del(){
        dao.delUser(6);
    }

    /**
     * 根据id查询一个用户数据
     */
    @Test
    public void findOne(){
        User user = dao.findOne(1);
        System.out.println(user);
    }

    /**
     * 根据用户名查询用户(模糊查询)
     */
    @Test
    public void findByUserName(){
        List<User> list = dao.findByUserName("%三%");
        System.out.println(list);

    }

    /**
     * 根据用户名查询用户(模糊查询,自定义查询对象)
     */
    @Test
    public void findByUserName2(){
        QueryVo vo = new QueryVo();
        User user = new User();
        user.setUsername("%三%");
        vo.setUser(user);
        List<User> list = dao.findByUserNameVo(vo);
        System.out.println(list);

    }
    /**
     * 查询用户总数量(聚合函数)
     */
    @Test
    public void getUserTotalCount(){
        int totalCount = dao.getTotalCount();
        System.out.println(totalCount);
    }
}

第五章:MyBatis参数深入

5.1-parameterType 配置参数

SQL 语句传参,使用标签的 parameterType 属性来设定。

该属性的取值可以 是基本类型,引用类型(例如:String 类型),还可以是实体类类型(POJO 类)。

同时也可以使用实体类的包装 类,本章节将介绍如何使用实体类的包装类作为参数传递。

5.2-注意事项

基 本 类 型 和 String 我 们 可 以 直 接 写 类 型 名 称 , 也 可 以 使 用 包 名 . 类 名 的 方 式 , 例 如 : java.lang.String。 究其原因,是 mybaits 在加载时已经把常用的数据类型注册了别名,从而我们在使用时可以不写包名, 而我们的是实体类并没有注册别名,所以必须写全限定类名。

这些都是支持的默认别名。我们也可以从源码角度来看它们分别都是如何定义出来的。 可以参考 TypeAliasRegistery.class 的源码。

5.3-传递 pojo 包装对象

概述和需求

开发中通过 pojo 传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查 询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。 Pojo 类中包含 pojo。

需求:根据用户名查询用户信息,查询条件放到 QueryVo 的 user 属性中。

编写 QueryVo

package cn.lpl666.domain;

/**
 * 自定义查询对象
 */
public class QueryVo {
  private User user;

  public User getUser() {
    return user;
  }

  public void setUser(User user) {
    this.user = user;
  }
}

编写持久层接口

package cn.lpl666.dao;
import cn.lpl666.domain.QueryVo;
import cn.lpl666.domain.User;

import java.util.List;

/**
 * 用户持久层操作
 */
public interface IUserDao {

  /**
   * 据用户名模糊查询(自定义查询对象)
   * @param vo
   * @return
   */
  List<User> findByUserNameVo(QueryVo vo);
}

持久层接口的映射文件

    <!--根据用户名查询用户-自定义查询对象-->
    <select id="findByUserNameVo" parameterType="cn.lpl666.domain.QueryVo" resultType="cn.lpl666.domain.User">
        select * from user where username like #{user.username}
    </select>

测试

package cn.lpl666;

import static org.junit.Assert.assertTrue;

import cn.lpl666.domain.QueryVo;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import cn.lpl666.dao.IUserDao;
import cn.lpl666.domain.User;
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;
import java.util.List;

public class AppTest {
    private static InputStream is;
    private static SqlSession sqlSession;
    private static IUserDao dao;
    @Before
    public void init(){
        // 读取配置文件
        try {
            is = Resources.getResourceAsStream("SqlMapConfig.xml");
            // 创建工厂构建者对象
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            // 创建SqlSessionFactory工厂对象
            SqlSessionFactory sqlSessionFactory = builder.build(is);
            // 创建SqlSession对象
            sqlSession = sqlSessionFactory.openSession();
            // 创建dao代理对象
            dao = sqlSession.getMapper(IUserDao.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @After
    public  void destroy() throws IOException {
        sqlSession.commit();
        is.close();
        sqlSession.close();
    }

    /**
     * 根据用户名查询用户(模糊查询,自定义查询对象)
     */
    @Test
    public void findByUserName2(){
        QueryVo vo = new QueryVo();
        User user = new User();
        user.setUsername("%三%");
        vo.setUser(user);
        List<User> list = dao.findByUserNameVo(vo);
        System.out.println(list);

    }
}

第六章:Mybatis的输出结果封装

6.1-resultType属性

resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型。

需要注意的是,它和 parameterType 一样,如果注册过类型别名的,可以直接使用别名。没有注册过的必须 使用全限定类名。

6.2-resultMap 结果类型

概述

resultMap 标签可以建立查询的列名和实体类的属性名称不一致时建立对应关系。从而实现封装。

在 select 标签中使用 resultMap 属性指定引用即可。同时 resultMap 可以实现将查询结果映射为复杂类 型的 pojo,比如在查询结果映射对象中包括 pojo 和 list 实现一对一查询和一对多查询 。

User实体类

User实体类中的属性名和数据库中的列名不一致

package cn.lpl666.domain;

import java.io.Serializable;

public class User implements Serializable {
  private int uid;
  private String userName;
  private String date;
  private String gender;
  private String city;

  public int getUid() {
    return uid;
  }

  public void setUid(int uid) {
    this.uid = uid;
  }

  public String getUserName() {
    return userName;
  }

  public void setUserName(String userName) {
    this.userName = userName;
  }

  public String getDate() {
    return date;
  }

  public void setDate(String date) {
    this.date = date;
  }

  public String getGender() {
    return gender;
  }

  public void setGender(String gender) {
    this.gender = gender;
  }

  public String getCity() {
    return city;
  }

  public void setCity(String city) {
    this.city = city;
  }

  @Override
  public String toString() {
    return "User{" +
            "uid=" + uid +
            ", userName='" + userName + '\'' +
            ", date='" + date + '\'' +
            ", gender='" + gender + '\'' +
            ", city='" + city + '\'' +
            '}';
  }
}

dao.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="cn.lpl666.dao.IUserDao">
    <!--
		【resultMap标签的使用】
		type属性:实体类的全限定类名
        id 标签:用于指定主键字段
        result 标签:用于指定非主键字段
        column 属性:用于指定数据库列名
        property 属性:用于指定实体类属性名称
	-->
    <resultMap id="userMap" type="cn.lpl666.domain.User">
        <!--主键-->
        <id property="uid" column="id"></id>
        <!--其他-->
        <result property="userName" column="username"></result>
        <result property="gender" column="sex"></result>
        <result property="city" column="address"></result>
        <result property="date" column="birthday"></result>
    </resultMap>
    <!--查询所有用户-->
    <select id="findAll" resultMap="userMap">
        select * from user
    </select>
</mapper>
posted @ 2020-02-04 15:31  雷哒哒  阅读(188)  评论(0编辑  收藏  举报