• Java 20-Mybatis学习


    1614734335(1)

    1. 什么是框架?

            框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面而后者是从目的方面给出的定义。简而言之,框架其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统。简单说就是使用别人搭好的舞台,你来做表演。而且,框架一般是成熟的,不断升级的软件。

    不同的框架解决不同的问题,因此需要考虑到此前的三层架构的知识进行分类讲解:

        三层架构-表现层 用于展示数据的

                      业务层  处理业务需求的

                      持久层  和数据库进行交互的---mybatis

    其中持久层技术解决方案

  •   jdbc-有三个对象connection、preparedStatement、resultSet
  • spring中jdbcTemplate-spring对jdbc的简单封装
  • Apache的DBUtils:和spring的jdbcTemplate很像,也是简单封装
  • image
  • 但这些都不是框架,JDBC是规范,另外两个都是工具类

    image

    JDBC的问题      

    public static void main(String[] args) {
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    try {
    //加载数据库驱动
    Class.forName("com.mysql.jdbc.Driver");
    //通过驱动管理类获取数据库链接
    connection = DriverManager
    .getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8","ro
    ot", "root");
    //定义 sql 语句 ?表示占位符
    String sql = "select * from user where username = ?";
    传智播客——专注于 Java、.Net 和 Php、网页平面设计工程师的培训
    北京市昌平区建材城西路金燕龙办公楼一层 电话:400-618-9090
    //获取预处理 statement
    preparedStatement = connection.prepareStatement(sql);
    //设置参数,第一个参数为 sql 语句中参数的序号(从 1 开始),第二个参数为设置的
    参数值
    preparedStatement.setString(1, "王五");
    //向数据库发出 sql 执行查询,查询出结果集
    resultSet = preparedStatement.executeQuery();
    //遍历查询结果集
    while(resultSet.next()){
     System.out.println(resultSet.getString("id")+"
     "+resultSet.getString("username"));
    }
    } catch (Exception e) {
    e.printStackTrace();
    }finally{
    //释放资源
    if(resultSet!=null){
    try {
    resultSet.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    if(preparedStatement!=null){
    try {
    preparedStatement.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    if(connection!=null){
    try {
    connection.close();
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    }
    上边使用 jdbc 的原始方法(未经封装)实现了查询数据库表记录的操作。

    jdbc问题分析

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

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

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

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


    mybatis通过xml或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中的sql的动态参数进行映射生成最终执行的sql语句(也就是可能有where条件,通过占位符实现),最后由mybatis框架执行sql并将最终结果映射为java对象并返回。

          采用ORM思想(封装结果集的功能---对象关系映射,就是把数据库表和实体类及实体类的属性对应起来,让我们操作实体类,就可以实现操作数据库表)解决了实体和数据库映射的问题,对jdbc进行封装,屏蔽了jdbc api底层访问细节,是我们不用与jdbc api打交道,就可以完成数据库的持久化操作。

    实现基础:实体类的属性和数据库表的字段名称保持一致


           ORM-object relational  mapping 对象关系映射,简单的说就是把数据库表和实体类以及实体类的属性对应起来。让我们通过操作实体类,就可以实现操作数据库表。我们mybatis是写sql语句的,那么我们封装结果集的时候,有一个user表和user类,就可以一一对应。未来注意实体类中的属性和数据库表的字段名称保持一致。

    1.1 Mybatis环境搭建和入门

    (1)数据库创建 eesy_mybatis的数据表创建

    (2)pom.XML中给以packaging配置   

    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>com.itheima.mybatis</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>jar</packaging>
    
    </project>



    (3)环境搭建四步走

  • 创建maven工程并导入坐标,可以去官网找到mybatis的官方依赖要求
  • 1614740159<dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>x.x.x</version>
    </dependency>
  • 创建实体类和dao接口
  • 创建Mybties的主配置文件  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>
    <!--    配置环境-->
        <environments default="mysql">
            <!--配置mysql的环境-->
            <environment id="mysql">
                <!--配置事务的类型-->
                <transactionManager type="JDBC"></transactionManager>
                <!--配置数据源/连接池 有三种选法-->
                <dataSource type="POOLED">
                    <!--配置连接数据库的四个基本信息-->
                    <property name="driver" value="com.mysql.jdbc.Driver"></property>
                    <property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"></property>
                    <property name="username" value="root"></property>
                    <property name="password" value="root"></property>
                </dataSource>
            </environment>
        </environments>
    <!--    指定映射配置文件的位置(每个dao独立的配置文件)-->
        <mappers>
            <mapper resource="com/itheima/dao/IUserDao.xml"></mapper>
        </mappers>
    
    </configuration>
    
  • 创建映射配置文件 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-config.dtd">
    <mapper namespace="com.itheima.dao.IUserDao">
        <!--配置查询所有-->
    <!--    select的id得是dao的方法名称-->
        <select id="findAll">
            select * from user
        </select>
    </mapper>
    

    image

    注意:

  • 1,创建IUserDao.xml和IUserDao.java时名称一样,是为和前面学习知识保持一致,在mybatis中,它把持久层的操作接口门窗和映射文件叫做Mapper。所以IUserDao和IUserMapper是一样的。
  • ,2,在IDEA中,创建目录时,包创建时和文件夹名字是不一样的,有分级概念

    ,3.Mybatis的映射配置文件位置必须和dao接口的包结构相同

  • 4.映射配置文件的mapper标签namespace属性的取值,必须是dao接口的权限定类名。
  • 5.映射配置文件的操作配置,id属性取值必须是dao接口的方法名

  •         当我们遵从3.4.5之后,我们无需写dao的实现类。当然 按照注解方式开发的话:

  • IUserDao.xml文件不需要了,方便很多
  • 在dao接口的方法上使用@Select注解,并指定sql语句
  • public interface IUserDao {
    
        /**
         * 查询所有操作
         * @return
         */
        @Select("select * from user")
        List<User> findAll();
    }
  • SqlMapConfig.xml文件里的mapper配置进行以下修改:
  •     如果是注解来配置话,此处使用class属性指定被注解的dao全限定类名

    <mappers>
        <mapper resource="com/itheima/dao/IUserDao.xml"/>
    修改为:
       <mapper class="com.itheima.dao.IUserDao"/>
    </mappers>
    
    因此 注解开发将会更加简单。
    mybatis在使用dao方式实现增删改查时做了什么事呢:
         1.创建代理对象
         2.在代理对象中调用selectList

    1.2 自定义mybatis类

  • class Resources
  • class SqlSessionFactoryBuilder
  • interface SqlSessionFactory
  • interface SqlSession

  • 2.1.回顾mybatis自定义再分析和环境搭建+完善基于注解的mybatis

    自定义mybatis开发流程图

    package com.itheima.test;
    
    import com.itheima.dao.IUserDao;
    import com.itheima.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 javax.annotation.Resource;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    /**
     *
     */
    public class MybatisTest {
        private IUserDao us;
    
        /**
         * 入门案例
         * @param args
         */
        public static void main(String[] args) throws IOException {
            //1,读取配置文件
            InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
            //2.创建sqlsessionFactory工厂,这个工厂是一个接口。因此不能new   SqlSessionFactory sqlSessionFactory =null;
            SqlSessionFactoryBuilder sb = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory =sb.build(in);
            //3.使用工厂生产sqlSession对象
            SqlSession session = sqlSessionFactory.openSession();
            //4.使用sqlSession对dao接口的字节码文件进行创建dao接口的代理对象
            IUserDao userDao = session.getMapper(IUserDao.class);
            //5.使用代理对象执行方法
            List<User> users = userDao.findAll();
            for (User user : users) {
                System.out.println(user);
            }
            //6.释放资源
            session.close();
            in.close();
        }
    }
    
    
    <?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="com.itheima.dao.IUserDao">
    <!--   配置查询所有,sql语句执行完后,会封装为com.itheima.domain.User对象中,并将user对象封装为list -->
        <select id="findAll" resultType="com.itheima.domain.User">
            select * from user;
        </select>
    </mapper>
    
    
    
    <?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">
    <!--mybatis的主配置文件,内含映射配置文件的位置,映射配置文件的指的是每个dao独立的配置-->
    <configuration>
        <environments default="mysql">
            <!--配置mysql的环境-->
            <environment id="mysql">
                <!--配置事务的类型-->
                <transactionManager type="JDBC"></transactionManager>
                <!--配置数据源(连接池)-->
                <dataSource type="POOLED">
                <!--配置连接数据库的4个基本信息-->
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis?useSSL=false"/>
                    <property name="username" value="root"/>
                    <property name="password" value="root"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <mapper resource="com/itheima/dao/IUserDao.xml"></mapper>
        </mappers>
    </configuration>
    
    

    注解方式:

    image

    <!--    指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件-->
    <!--    指定映射配置文件的位置,如果使用的是注解,此处应该使用class属性指定被注解的dao全限定类名-->
        <mappers>
    <!--        <mapper resource="com/itheima/dao/IUserDao.xml"></mapper>-->
            <mapper class="itheima.dao.IUserDao"></mapper>
        </mappers>
    /**
     * 用户的持久层
     */
    public interface IUserDao {
        /**
         * 查询所有操作
         * @return
         */
        @Select("select * from user")
        List<User> findAll();
    }
    

    切记,一般来说,在mybatis框架下,不建议些dao接口的实现类,不是不可以写,而是不需要,我们一般是减少代码编写,完成业务逻辑即可,因此我们此处可以尝试使用dao接口实现类来操作,但需要用的xml里面全限定类名的namespace和id绑定的方法名来共同得到statement的语句执行进而封装结果数据。

    public class IUserDaoImpl implements IUserDao {
        //定义一个能拿到session对象的工厂
        private SqlSessionFactory factory=null;
    
        /**
         * 默认构造函数,传入factory对象,这样使用本实现类,就一定有factory对象
         * 有了工厂对象,好处就是具体的findAll方法即可真实进行相应的数据获取
         * @param factory
         */
        public IUserDaoImpl(SqlSessionFactory factory) {
            this.factory = factory;
        }
    
        public List<User> findAll() {
    
            SqlSession session = factory.openSession();
            List<User> users = session.selectList("itheima.dao.IUserDao.findAll");
            session.close();
            return users;
        }
    }

    测试

       public static void main(String[] args) throws IOException {
            //1,读取配置文件
            InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
            //2.创建sqlsessionFactory工厂,这个工厂是一个接口。因此不能new   SqlSessionFactory sqlSessionFactory =null;
            SqlSessionFactoryBuilder sb = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory =sb.build(in);
            //3.使用工厂生产sqlSession对象
    //        SqlSession session = sqlSessionFactory.openSession();
            //4.使用sqlSession对dao接口的字节码文件进行创建dao接口的代理对象
    //        IUserDao userDao = session.getMapper(IUserDao.class);
            //5.使用代理对象执行方法
    //        List<User> users = userDao.findAll();
            IUserDao iUserDao=new IUserDaoImpl(sqlSessionFactory);
            List<User> users = iUserDao.findAll();
            for (User user : users) {
                System.out.println(user);
            }
            //6.释放资源
    //        session.close();
            in.close();
        }

    shuom

    image

    image


    image

    04mybatis的分析

    查询所有的分析

    入门案例的分析

    image

    #{}表示一个占位符号通过#{}可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换, #{}可以有效防止 sql 注入。 #{}可以接收简单类型值或 pojo 属性值。 如果 parameterType 传输单个简单类型值,#{}括号中可以是 value 或其它名称。 ${}表示拼接 sql 串通过${}可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换, ${}可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,${}括号中只能是 value。



    如何获得保存的自增长的用户id,如何获取呢

    image

    <!--  保存用户配置, parameterTypes是入参全限定类名 -->
        <insert id="saveUser" parameterType="com.itheima.domain.User">
    -- keyProperty属性名   keyColumn列名  resultType返回值类型  order执行先后
            <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>

    image

    由此 也就获取到了id值


    2.3 mybatis的参数深入及结果集的深入

    parameterType(输出类型)

    • 传递简单类型:基 本 类 型 和 String 我 们 可 以 直 接 写 类 型 名 称 , 也 可 以 使 用 包 名 . 类 名 的 方 式 , 例 如 : java.lang.String。
    • 传递pojo对象:mybatis使用ognl表达式来解析对象字段的值,#{}或者 ¥{}中的值为pojo属性名称。目前我们只能使用全限定类名。究其原因,是 mybaits 在加载时已经把常用的数据类型注册了别名,从而我们在使用时可以不写包名,而我们的是实体类并没有注册别名,所以必须写全限定类名。在今天课程的最后一个章节中将讲解如何注册实体类的别名。

    1f244b34c0321ec86e6b72f7aede887

    • 传递pojo包装对象:开发中,查询条件是综合条件,不仅仅包括用户的查询条件,还包括其他的查询条件(比如讲用户购买的商品信息也作为查询条件),这时可以使用包装对象传递输入参数,pojo类中包含pojo:这个对象是我们自己定义的查询条件对象,需求是根据用户名查询用户信息,查询条件放到queryvo的user属性中。

    package com.itheima.dao;
    
    import com.itheima.domain.QueryVo;
    import com.itheima.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 deleteUser(Integer id);
        /**
         * 查询用户
         */
        User findById(Integer id);
        /**
         * 根据用户名,模糊查询用户信息
         */
        List<User> findByUsername(String username);
    
        /**
         * 查询总用户数
         *
         */
        int findTotal();
    
        /**
         *根据queryVo中的条件查询用户,需要我们自己定义其,比方说还是根据模糊查询
         */
        List<User> findUserByVo(QueryVo vo);
    }
    

    package com.itheima.test;
    
    import com.itheima.dao.IUserDao;
    import com.itheima.domain.QueryVo;
    import com.itheima.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.Test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Date;
    import java.util.List;
    
    /**
     *
     */
    public class MybatisTest {
        private IUserDao us;
    
        /**
         * 入门案例
         * @param args
         */
        public static void main(String[] args) throws IOException {
            //1,读取配置文件
            InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
            //2.创建sqlsessionFactory工厂,这个工厂是一个接口。因此不能new   SqlSessionFactory sqlSessionFactory =null;
            SqlSessionFactoryBuilder sb = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory =sb.build(in);
            //3.使用工厂生产sqlSession对象
            SqlSession session = sqlSessionFactory.openSession();
            //4.使用sqlSession对dao接口的字节码文件进行创建dao接口的代理对象
            IUserDao userDao = session.getMapper(IUserDao.class);
            //5.使用代理对象执行方法
            List<User> users = userDao.findAll();
            for (User user : users) {
                System.out.println(user);
            }
            //6.释放资源
            session.close();
            in.close();
        }
    
        /**
         * 测试保存操作
         */
        @Test
        public void testSave(){
            try {
                User user = new User();
                user.setAddress("南京");
                user.setSex("");
                user.setUsername("555555555555");
                user.setBirthday(new Date());
                System.out.println("保存之前"+user);
                //1,读取配置文件
                InputStream in = null;
                in = Resources.getResourceAsStream("SqlMapConfig.xml");
                //2.创建sqlsessionFactory工厂,这个工厂是一个接口。因此不能new   SqlSessionFactory sqlSessionFactory =null;
                SqlSessionFactoryBuilder sb = new SqlSessionFactoryBuilder();
                SqlSessionFactory sqlSessionFactory =sb.build(in);
                //3.使用工厂生产sqlSession对象
                SqlSession session = sqlSessionFactory.openSession();
                //4.使用sqlSession对dao接口的字节码文件进行创建dao接口的代理对象
                IUserDao userDao = session.getMapper(IUserDao.class);
    
    
    
                //5.使用代理对象执行方法
                userDao.saveUser(user);
                session.commit();//提交事务,否则会报错 Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2a40cd94]
                System.out.println("保存之后"+user);
    
                //6.释放资源
                session.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
    
        }
    
        /**
         * 测试更新
         */
        @Test
        public void testUpdateUser(){
            try {
                User user = new User();
                user.setId(52);
                user.setBirthday(new Date());
                user.setUsername("123");
                user.setSex("");
                user.setAddress("SHANGHAI");
                //1,读取配置文件
                InputStream in = null;
                in = Resources.getResourceAsStream("SqlMapConfig.xml");
                //2.创建sqlsessionFactory工厂,这个工厂是一个接口。因此不能new   SqlSessionFactory sqlSessionFactory =null;
                SqlSessionFactoryBuilder sb = new SqlSessionFactoryBuilder();
                SqlSessionFactory sqlSessionFactory =sb.build(in);
                //3.使用工厂生产sqlSession对象
                SqlSession session = sqlSessionFactory.openSession();
                //4.使用sqlSession对dao接口的字节码文件进行创建dao接口的代理对象
                IUserDao userDao = session.getMapper(IUserDao.class);
    
    
    
                //5.使用代理对象执行方法
                userDao.updateUser(user);
                session.commit();//提交事务,否则会报错 Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2a40cd94]
                //6.释放资源
                session.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        @Test
        public void testDeleteUser(){
            try {
                User user = new User();
                user.setId(52);
                //1,读取配置文件
                InputStream in = null;
                in = Resources.getResourceAsStream("SqlMapConfig.xml");
                //2.创建sqlsessionFactory工厂,这个工厂是一个接口。因此不能new   SqlSessionFactory sqlSessionFactory =null;
                SqlSessionFactoryBuilder sb = new SqlSessionFactoryBuilder();
                SqlSessionFactory sqlSessionFactory =sb.build(in);
                //3.使用工厂生产sqlSession对象
                SqlSession session = sqlSessionFactory.openSession();
                //4.使用sqlSession对dao接口的字节码文件进行创建dao接口的代理对象
                IUserDao userDao = session.getMapper(IUserDao.class);
    
                //5.使用代理对象执行方法
                userDao.deleteUser(user.getId());
                session.commit();//提交事务,否则会报错 Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2a40cd94]
                //6.释放资源
                session.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        @Test
        public void testFindById(){
            try {
                User user = new User();
                user.setId(1);
                //1,读取配置文件
                InputStream in = null;
                in = Resources.getResourceAsStream("SqlMapConfig.xml");
                //2.创建sqlsessionFactory工厂,这个工厂是一个接口。因此不能new   SqlSessionFactory sqlSessionFactory =null;
                SqlSessionFactoryBuilder sb = new SqlSessionFactoryBuilder();
                SqlSessionFactory sqlSessionFactory =sb.build(in);
                //3.使用工厂生产sqlSession对象
                SqlSession session = sqlSessionFactory.openSession();
                //4.使用sqlSession对dao接口的字节码文件进行创建dao接口的代理对象
                IUserDao userDao = session.getMapper(IUserDao.class);
    
                //5.使用代理对象执行方法
                User userDaoById = userDao.findById(user.getId());
                System.out.println(userDaoById);//User{id=1, username='老王', birthday=Tue Feb 27 17:47:08 CST 2018, sex='男', address='北京'}
                session.commit();//提交事务,否则会报错 Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2a40cd94]
                //6.释放资源
                session.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        @Test
        public void testFindByUserName(){
            try {
                User user = new User();
                user.setUsername("");
                //1,读取配置文件
                InputStream in = null;
                in = Resources.getResourceAsStream("SqlMapConfig.xml");
                //2.创建sqlsessionFactory工厂,这个工厂是一个接口。因此不能new   SqlSessionFactory sqlSessionFactory =null;
                SqlSessionFactoryBuilder sb = new SqlSessionFactoryBuilder();
                SqlSessionFactory sqlSessionFactory =sb.build(in);
                //3.使用工厂生产sqlSession对象
                SqlSession session = sqlSessionFactory.openSession();
                //4.使用sqlSession对dao接口的字节码文件进行创建dao接口的代理对象
                IUserDao userDao = session.getMapper(IUserDao.class);
    
                //5.使用代理对象执行方法
                List<User> userList = userDao.findByUsername(user.getUsername());
                for (User users : userList) {
                    System.out.println(users);
                }
                session.commit();//提交事务,否则会报错 Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2a40cd94]
                //6.释放资源
                session.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    
        @Test
        public void testFindTotal(){
            try {
    //            User user = new User();
    //            user.setUsername("%王%");
                //1,读取配置文件
                InputStream in = null;
                in = Resources.getResourceAsStream("SqlMapConfig.xml");
                //2.创建sqlsessionFactory工厂,这个工厂是一个接口。因此不能new   SqlSessionFactory sqlSessionFactory =null;
                SqlSessionFactoryBuilder sb = new SqlSessionFactoryBuilder();
                SqlSessionFactory sqlSessionFactory =sb.build(in);
                //3.使用工厂生产sqlSession对象
                SqlSession session = sqlSessionFactory.openSession();
                //4.使用sqlSession对dao接口的字节码文件进行创建dao接口的代理对象
                IUserDao userDao = session.getMapper(IUserDao.class);
    
                //5.使用代理对象执行方法
                int total = userDao.findTotal();
                System.out.println(total);
                session.commit();//提交事务,否则会报错 Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2a40cd94]
                //6.释放资源
                session.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        @Test
        public void testFindQueryVo(){
            try {
                User user = new User();
                user.setUsername("老王");
                QueryVo vo=new QueryVo();
                vo.setUser(user);
                //1,读取配置文件
                InputStream in = null;
                in = Resources.getResourceAsStream("SqlMapConfig.xml");
                //2.创建sqlsessionFactory工厂,这个工厂是一个接口。因此不能new   SqlSessionFactory sqlSessionFactory =null;
                SqlSessionFactoryBuilder sb = new SqlSessionFactoryBuilder();
                SqlSessionFactory sqlSessionFactory =sb.build(in);
                //3.使用工厂生产sqlSession对象
                SqlSession session = sqlSessionFactory.openSession();
                //4.使用sqlSession对dao接口的字节码文件进行创建dao接口的代理对象
                IUserDao userDao = session.getMapper(IUserDao.class);
    
                //5.使用代理对象执行方法
                List<User> userByVo = userDao.findUserByVo(vo);
                System.out.println(userByVo);
                session.commit();//提交事务,否则会报错 Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2a40cd94]
                //6.释放资源
                session.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    package com.itheima.domain;
    
    public class QueryVo {
        private User user;
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    }
    


    <?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="com.itheima.dao.IUserDao">
    <!--   配置查询所有,sql语句执行完后,会封装为com.itheima.domain.User对象中,并将user对象封装为list -->
        <select id="findAll" resultType="com.itheima.domain.User">
            select * from user;
        </select>
    <!--  保存用户配置, parameterTypes是入参全限定类名 -->
        <insert id="saveUser" parameterType="com.itheima.domain.User">
    -- keyProperty属性名   keyColumn列名  resultType返回值类型  order执行先后
            <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>
    <!--    更新用户配置,parameterTypes是入参全限定类名-->
        <update id="updateUser" parameterType="com.itheima.domain.User">
            update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id = #{id}
        </update>
    
    <!--    删除用户配置-->
        <delete id="deleteUser" parameterType="Integer">
            delete from user where id=#{id}
        </delete>
    <!--    查询用户配置-->
        <select id="findById" parameterType="Integer" resultType="com.itheima.domain.User">
            select * from user where id=#{id}
        </select>
    <!--    模糊查询用户根据用户名-->
        <select id="findByUsername" parameterType="String" resultType="com.itheima.domain.User">
            select * from user where username like '%${value}%'
        </select>
    <!--    查询总用户数-->
        <select id="findTotal" resultType="Integer">
            select count(id) from user;
        </select>
    <!--    根据queryVo的条件查询用户 like后面不能是name,OGNL表达式会把username当成queryvo的属性,但其实他没有,他只有User,因为queryVo中没有name属性,他只有user,我们只能取其子项,用打点-->
    <!--    这就体现了ognl表达式如何将实体类包装起来,作为参数属性传递时候的操作过程,简单来说就是对象.属性  达到属性传值-->
        <select id="findUserByVo" parameterType="com.itheima.domain.QueryVo" resultType="com.itheima.domain.User">
            select * from user where username= #{user.username}
        </select>
    </mapper>
    

    mybatis输出结果类型的封装


    •   输出简单类型-int啥

    image

    •   输出pojo对象-实体类对象

    image

    •   输出pojo列表-或者实体类对象列表

    image

    image


    resultMap类型








    2.4mybatis的传统dao方式(编写dao实现类)



    2.5 mybatis中的配置(主配置文件:sqlmapconfig.xml)


    主要包含标签:properties标签,typeAliases标签,mappers标签








  • 相关阅读:
    POJ 2007 Scrambled Polygon (极角排序)
    POJ 1113 Wall (凸包 + 思维)
    POJ 2074 Line of Sight(求直线交点 + 思维)
    POJ 1584 A Round Peg in a Ground Hole(凸多边形判断 + 点是否在多边形内 + 点到线段的最短距离)
    HDU 4623 Crime (状压DP + 数学优化)
    P4755 Beautiful Pair
    CF235C Cyclical Quest
    luoguP4449 于神之怒加强版
    扩展KMP
    P4397 [JLOI2014]聪明的燕姿
  • 原文地址:https://www.cnblogs.com/rango0550/p/14081344.html
  • Copyright © 2020-2023  润新知