MyBatis02:流程分析、注解、代理dao实现CRUD、参数深入、传统DAO、配置

今日内容
  • 回顾 mybatis的自定义、分析和环境搭建
  • 完善基于注解的mybatis
  • mybatis的curd(基于代理dao的方式)※
  • mybatis的参数深入及结果集的深入
  • mybatis中基于传统dao的方式(编写dao的实现类)--了解
  • mybatis中的配置(主配置文件:SqlMapConfig.xml)
    • properties标签
    • typeAliases标签
    • mappers标签
一、回顾
1、自定义mybatis的流程分析
2、基于注解的自定义再分析

3、实现查询所有功能
  • 写pom.xml文件
  • 创建domain下的User
  • 创建dao下的IUserDao
  • 写SqlMapConfig.xml和IUSerDao.xml(逐级创建目录)
  • 放入log4j的配置文件
二、CURD
1、保存操作
package com.itcast.test;
import com.itcast.dao.IUserDao;
import com.itcast.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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

/**
 * 测试mybatis的CURD操作
 */
public class MyBatisTest {
    private InputStream in;
    private SqlSession sqlSession;
    private IUserDao userDao;

    /**
     * 在测试方法执行之前执行
     * @throws IOException
     */
    @Before
    public void init() throws IOException {
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.获取SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.获取SQLSession对象
        sqlSession = factory.openSession();
        //4.获取dao的代理对象
        userDao = sqlSession.getMapper(IUserDao.class);
    }
    /**
     * 释放资源
     * 在测试方法之后执行
     */
    @After
    public void destroy() throws IOException {
        //提交事务
        sqlSession.commit();
        sqlSession.close();
        in.close();

    }
    /**
     * 测试查询所有
     */
    @Test
    public void findAll() throws IOException {
        //5.执行查询所有方法
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }
    /**
     * 测试保存操作
     */
    @Test
    public void testSave() {
        User user = new User();
        user.setUsername("刘金辉");
        user.setAddress("山东省聊城市");
        user.setSex("男");
        user.setBirthday(new Date());
        //5.执行保存方法
        userDao.saveUser(user);
    }
}
2、修改和删除操作
3、查询一个和模糊查询
4、(使用聚合函数)查询返回一行一列和占位符分析
三、mybatis的深入
1、模糊查询改写
  <select id="findByName" parameterType="String" resultType="com.itcast.domain.User">
        <!-- select * from user where username like '#{username}'; -->
        select * from user where username like '%${value}%';
    </select>

    /**
     * 模糊查询操作
     */
    @Test
    public void testFindByName() {
        //5.执行删除方法
        List<User> users = userDao.findByName("王");
        for (User user : users) {
            System.out.println(user);
        }
    }
2、获取保存数据的id
  • 增删改都有id,想要获取保存的id
 <insert id="saveUser" parameterType="com.itcast.domain.User">
        <!-- 配置插入后,获取插入操作的id -->
        <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
            select last_insert_id();
        </selectKey>
        insert into user(username,address,sex,birthday) values(#{username},#{address},#{sex},#{birthday});
    </insert>
3、使用实体类的包装对象作为查询条件【传递pojo包装对象】
  • OGNL表达式:
    • Object Graphic Navigation Language对象图导航语言
    • 作用:通过对象的取值方法来获取数据,在写法上省略get
    • 如:获取用户名称
      • 类中写法:user.getUsername()
      • OGNL表达式写法:user.username
    • mybatis中可以直接写username,而不需要user.
      • 原因:在parameterType中已经提供了属性所属的类,不许写对象名,可以直接写属性名
package com.itcast.domain;

public class QueryVo {
    private User user;

    public User getUser() {
        return user;
    }

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

  /**
     * 根据queryVo中的条件查询用户
     * @return
     */
    List<User> findUserByVo(QueryVo vo);

    <!-- 根据queryVo的条件查询用户 -->
    <!--根据名称模糊查询用户-->
    <select id="findUserByVo" parameterType="com.itcast.domain.QueryVo" resultType="com.itcast.domain.User">
        <!-- select * from user where username like '#{username}'; -->
        select * from user where username like #{user.username};
    </select>

 /**
     * 测试使用QueryVo作为查询条件
     */
    @Test
    public void testFindByVo(){
        QueryVo vo = new QueryVo();
        User user = new User();
        user.setUsername("%刘%");
        List<User> users = userDao.findUserByVo(vo);
        for (User u : users) {
            System.out.println(u);
        }
    }
4、调整实体类属性解决增和改方法的报错
  • 实体类属性和数据库列名不一致
 <!-- 设置属性名与列名的对应关系 -->
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
    • 解决方案
      • 起别名
      • 单独配置查询结果的列名和实体类的属性名之间的对应关系※
    <resultMap id="userMap" type="com.itcast.domain.User">
        <!--主键字段的对应-->
        <id property="id" column="id"></id>
        <!--非主键字段的对应-->
        <result property="username" column="username"></result>
        <!--等-->
    </resultMap>
    <select id="findAll" resultMap="userMap">
        select * from user;
    </select>
四、编写DAO实现类
之前介绍的是使用代理dao方式,也可以自己实现dao
1、查询列表
public class UserDaoImpl implements IUserDao {
    private SqlSessionFactory factory;

    public UserDaoImpl(SqlSessionFactory factory) {
        this.factory = factory;
    }

    @Override
    public List<User> findAll() {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用SQLSession中的方法实现查询列表
        List<User> users = session.selectList("com.itcast.dao.IUserDao.findAll");//参数就是能获取配置信息的key
        //3.释放资源
        session.close();
        return users;
    }
2、保存操作
    @Override
    public void saveUser(User user) {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用SQLSession中的方法实现查询列表
        session.insert("com.itcast.dao.IUserDao.saveUser",user);
        //3.提交事务
        session.commit();
        //4.关闭
        session.close();
    }

    /**
     * 测试保存操作
     */
    @Test
    public void testSave() {
        User user = new User();
        user.setUsername("杨玉琼");
        user.setAddress("云南省昭通市");
        user.setSex("女");
        user.setBirthday(new Date());
        System.out.println("保存操作之前"+user);
        //5.执行保存方法
        userDao.saveUser(user);
        System.out.println(user);
    }
3、修改删除等其他操作
   @Override
    public User findById(Integer userId) {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用SQLSession中的方法实现查询列表
        User user = session.selectOne("com.itcast.dao.IUserDao.findById", userId);
        //3.提交事务
        session.commit();
        //4.关闭
        session.close();
        return user;
    }

    @Override
    public List<User> findByName(String username) {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用SQLSession中的方法实现查询列表
        List<User> users = session.selectList("com.itcast.dao.IUserDao.findByName", username);
        //3.提交事务
        session.commit();
        //4.关闭
        session.close();
        return users;
    }

    @Override
    public int findTotal() {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用SQLSession中的方法实现查询列表
        Integer count = session.selectOne("com.itcast.dao.IUserDao.findTotal");
        //3.提交事务
        session.commit();
        //4.关闭
        session.close();
        return count;
    }
4、使用Dao实现类的执行过程分析-查询方法1
  • debug mybatistest
    • sqlsession实现类,选择diagram,显示implements
5、使用代理dao的方式
实际上实现dao的方法,所以不用再写dao实现类
五、标签使用
1、properties标签的使用及细节
支持写配置properties
        可以在标签内部配置连接数据库的信息
        也可以通过属性引用外部配置文件信息
        resource属性:
            用于指定配置文件的位置,是按照类路径的写法来写,并且必须存在类路径下
            resource="jdbcConfig.properties"
        url属性:
            是要求按照url的写法来写地址
            URL:Uniform Resource Locator:统一资源定位符,可以唯一标识一个资源的位置
            写法:
                协议 主机 端口 URI
                http://localhost:8080/mybatisServer/demo1Servlet
                windows实际上就是使用了file协议,拖到浏览器file:///c:....
                不要写中文
            URI:Uniform Resource Identifier 统一资源标识符,可以在应用中唯一定位一个资源
  <properties resource="jdbcConfig.properties">
        <!--<property name="driver" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/eesy"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>-->
    </properties>
    <!--配置环境-->
    <environments default="mysql">
        <!--配置mysql的环境-->
        <environment id="mysql">
            <!--配置事务-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
2、typeAliases标签和package标签
<?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>
    <properties resource="jdbcConfig.properties">
        <!--<property name="driver" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/eesy"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>-->
    </properties>
    <!--使用typeAliases配置别名,只能配置domain中类的别名-->
    <typeAliases>
        <!--typeAliases配置别名,type指定全限定类名,alias指定别名,指定别名后不再区分大小写-->
        <typeAlias type="com.itcast.domain.User" alias="user"></typeAlias>
        <!--package用于指定要配置别名的包,当指定后,该报下的实体类都会注册别名,并且类名就是别名,不再区分大小写-->
        <package name="com.itcast.domain.User"></package>
    </typeAliases>
 
    <mappers>
        <mapper resource="com/itcast/dao/IUserDao.xml"></mapper>
        <!--用于指定dao接口所在的包,当指定完成之后就不需要再写mapper、resource或class了-->
        <package name="com.itcast.dao"/>
    </mappers>
</configuration>




posted @ 2021-02-16 21:33  哥们要飞  阅读(83)  评论(0)    收藏  举报