MyBatis框架介绍以及快速入门

MyBatis框架

今日学习内容目标

  • 能够了解什么是框架
  • 理解自定义Mybatis框架
  • 掌握Mybatis框架开发快速入门

第一节 认识框架

1.介绍

框架就是一个架子,表演节目,舞台已经搭建好,表演什么节目,看自己的需求了。

框架是一个半成品,对于Java语言来说,框架就是封装了别人的代码。在框架的基础上我们在进一步开发,拿来用。

2.解决的问题

解决的是技术整合问题。软件开发环境和规模都很大,不可能任何一个项目的代码都从零开始,此时就需要一个非常优秀的框架把基础技术整合完毕,我们在他的基础上进一步开发。提高性能,易扩展,易维护,最终提高整个团队的开发效率。

3.使用框架

企业级大型项目开发用框架,避免大炮打蚊子。

Java的框架是具有一些共性

  • 导入jar包
  • 框架运行细节定义,也就是编写配置文件(xml)
  • 调用框架中的api

第二节 原生JDBC案例

  • 查询user表
  • 以List集合形式返回
  • 编写pojo类 (User)
    • domain,pojo本质都是相同的

1.JdbcDemo类

/**
 * 原始的JDBC,对数据表user查询,结果集存储List集合
 * */
public class JdbcDemo {
    public static void main(String[] args) throws Exception {
        // 注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 获取连接
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis","root","root");
        // SQL语句执行对象
        PreparedStatement pst = con.prepareStatement("select * from user");
        // 执行查询,返回结果集
        ResultSet rs = pst.executeQuery();
        List<User> userList = new ArrayList<User>();
        while (rs.next()){
            User user = new User();
            // 取出表中数据,rs对象的方法getXXX()
            user.setId(rs.getInt("id"));
            user.setUsername(rs.getString("username"));
            user.setSex(rs.getString("sex"));
            user.setBirthday(rs.getDate("birthday"));
            user.setAddress(rs.getString("address"));
            userList.add(user);
        }

        for (User user : userList){
            System.out.println(user);
        }

        rs.close();
        pst.close();
        con.close();

    }
}

2.User类

// 和数据库中的键对照
public class User {
    private int id;
    private String username;
    private String sex;
    private Date birthday;
    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 String getSex() {
        return sex;
    }

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

    public Date getBirthday() {
        return birthday;
    }

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

    public String getAddress() {
        return address;
    }

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

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

3.原始的JDBC的缺陷

原始程序问题:维护性差,扩展性差,出现问题,修改源码,代码量大

  1. 频繁连接,释放数据库资源,降低系统性能
    • 解决办法:连接池
  2. 数据库驱动类,连接四大信息
    • 解决办法:写配置文件,读取
  3. SQL语句硬编码,SQL语句写死了 SQL语句中的 ? 占位符
    • 解决办法:写配置文件,读取
  4. 封装数据表结果集代码,硬编码
    • 引出连接池,Apache DBUtils

4.框架

框架:最基本的代码,整合起来

连接数据库,执行SQL语句,封装结果集整合

只要提供:SQL语句,写xml中

第三节 MyBatis框架

1.历史

Mybatis原本是Apache软件基金会的一个开源项目叫做iBatis,2010年这个项目由Apache迁移到了google code管理才改名为Mybatis,2013年又迁移到了GitHub。

2.介绍

Mybatis是一个优秀的持久层框架(Dao层框架),它是对JDBC的封装,使得开发者只需要关注Sql语句(业务)本身即可,无需开发者处理载驱动、获取连接、创建Statement等繁琐的过程。

3.原理

Mybatis最大的特点是把Sql语句写在XML配置文件当中。而且Mybatis执行完Sql语句之后可以以对象形式返回(POJO/POJO集合等)。

思想

Mybatis是一个实现了ORM思想的持久层框架。

ORM:Object/Relation Mapping 对象/关系映射。

ORM思想:将数据库中的关系数据表映射为JAVA中的对象,把对数据表的操作转换为对对象的操作,实现面向对象编程。因此ORM的目的是使得开发人员以面向对象的思想来操作数据库。

比如:原来insert使用的是insert into…,如果使用实现了ORM思想的持久层框架,就可以在Java程序中直接调用api,比如insert(User),达到操作对象即操作数据库的效果。Hibernate框架是一个全自动的ORM持久层框架,只需要编写POJO,在xml中定义好Pojo属性和数据表字段的映射/对应关系,就可以在java中实现类似 insert(User)的操作。Sql语句都不用写。但是因为性能等问题,市场占有率越来越低

4.半自动ORM持久层框架

Mybatis框架是一个半自动的ORM持久层框架,也可以在Java中实现类似 insert(User)的操作最终操作数据库,但是需要我们自己写Sql语句。Mybatis是目前比较流行的Dao层框架。

第四节 自定义MyBatis框架

1.目的

  • 感受一个框架的生产过程,通过这个过程帮助我们了解底层的一些东西,提高竞争力(软实力)

  • 注意

    • 完整性和严谨性不能和真实的相比
    • 今天的课程依然有难度
    • 不影响真正Mybatis框架的使用
  • 所有的Dao层框架都是以接口的形式给我们提供增删改查的API

  • 我们今天自定义Mybatis框架只完成一个API接口:selectList

2.流程

MyBatis框架的使用流程

3.快速入门

需求:查询user表,数据存储到List集合

4.实现步骤

  1. 创建对象 SqlSessionFactoryBuilder (SQL会话工厂建设者) 读取配置文件SqlSessionFactory

    方法build(输入流) 只需要绑定主文配置文件

    工厂的构造者对象,作用创建SQLSession对象工厂的

  2. SqlSessionFactory 工厂创建

    创SqlSession接口实现类对象

  3. SqlSession接口实现类对象

    方法,执行SQL语句

    调用方法 select 查询数据表

  4. 输出查询结果集

  5. 释放资源

示例代码

步骤:

  • 导入MyBatis框架jar包
  • 配置文件
  • SqlSessionFactoryBuilder,传入字节输入流,构建工厂
  • SqlSessionFactory,创建SqlSession
  • SqlSession执行selectList方法查询数据

导入jar包和SqlMapConfig.xml以及UserMapper.xml配置文件

创建pojo文件夹 放user类

public class User {
    private int id;
    private String username;
    private String sex;
    private Date birthday;
    private String address;
    // getXXX和SetXXX以及toString方法省略
}

建QuickStart类

public void MyBatisQuickStart(){
        // 1.创建对象  SqlSessionFactory
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 使用SQLSessionFactoryBuilder方法 build(),创建出SqlSessionFactory对象
        // build方法,读取配置文件,返回SqlSessionFactory对象,需要传递流对象,流对象绑定数据库配置文件
        InputStream inputStream = QuickStart.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");
        // 2.SqlSessionFactory  工厂创建
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        // 工厂对象,获取SqlSession接口实现类对象,工厂对象的方法openSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 3.SqlSession接口实现类对象,调用方法select 查询数据表
        // selectList方法参数不是SQL语句, namespace+"."+id 锁定SQL语句  test.queryList 在SqlMapConfig.xml配置文件中
        List<User> userList = sqlSession.selectList("test.queryList");
        for (User user :userList){
            System.out.println(user);
        }
        sqlSession.close();
    }

第五节 Java中的日志组件

#log4j日志级别如下:
#A:off     最高等级,用于关闭所有日志记录。
#B:fatal   指出每个严重的错误事件将会导致应用程序的退出。
#C:error   指出虽然发生错误事件,但仍然不影响系统的继续运行。
#D:warn    表明会出现潜在的错误情形。
#E:info    一般和在粗粒度级别上,强调应用程序的运行全程。
#F:debug   一般用于细粒度级别上,对调试应用程序非常有帮助。
#G:all     最低等级,用于打开所有日志记录。

#但log4j只建议使用4个级别,优先级从高到低分别是:
#error>warn>info>debug

log4j.rootLogger =debug,systemOut,logFile

#输出到控制台
log4j.appender.systemOut = org.apache.log4j.ConsoleAppender
log4j.appender.systemOut.layout = org.apache.log4j.PatternLayout
log4j.appender.systemOut.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n
log4j.appender.systemOut.Target = System.out

#输出到文件
log4j.appender.logFile = org.apache.log4j.FileAppender
log4j.appender.logFile.layout = org.apache.log4j.PatternLayout
log4j.appender.logFile.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n
log4j.appender.logFile.File = E:/log/log4j.log
log4j.appender.logFile.Encoding = UTF-8

#将日志输记录到MySQL数据库
#log4j.appender.logDB = org.apache.log4j.jdbc.JDBCAppender
#log4j.appender.logDB.layout = org.apache.log4j.PatternLayout
#log4j.appender.logDB.Driver = com.mysql.jdbc.Driver
#log4j.appender.logDB.URL = jdbc:mysql://localhost:3306/log4j?characterEncoding=utf-8
#log4j.appender.logDB.User = root
#log4j.appender.logDB.Password = root
#log4j.appender.logDB.Sql = INSERT INTO t_log4j(project_name,create_date,level,category,file_name,thread_name,line,all_category,message)values('mybatis','%d{yyyy-MM-ddHH:mm:ss}','%p','%c','%F','%t','%L','%l','%m')

第六节 MyBatis配置文件详解

1.SqlMapperConfig.xml

enviroments配置数据源环境 运行环境 可配置多个

default = "development" 默认,值 = development 开发环境

  • default数据源开关

  • environment具体数据源环境,可以配置多个

    id 不同作用不同

    • id = "development" id 唯一的属性 值=id = "development" 开发环境
    • id = "product" 生产环境 交互给用户使用
    • id = "test" 测试环境 例如测试员测试
  • transactionManager事务管理器

  • datasource数据源

<!--配置-->
<configuration>
    <!--配置数据源环境信息-->
    <environments default="development">
        <!-- 开发环境数据源配置-->
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>

        <!--测试环境数据源 -->
        <environment id="test">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>

        <!-- 生产环境数据源-->
        <environment id="produce">
            <!--
               事务管理器
               type="JDBC" 当前MyBatis事务管理,使用的是JDBC的事务
               Connection接口方法 commit rollback
               type="MANAGERED" 不管理事务,交给其他框架管理
            -->
            <transactionManager type="JDBC" />
            <!--
                数据源
                type="POOLED" 使用数据库连接池
                type="UNPOOLED" 不使用连接池
            -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="UserMapper.xml" />
    </mappers>
</configuration>    

2.MyBatis框架的CRUD

1.根据id查询用户

  • SqlMapperConfig.xml
<mappers>
    <!-- 配置User表SQL语句 -->
    <mapper resource="sqlmapper/UserMapper.xml" />
</mappers>
  • UserMapper.xml配置
<mapper namespace="test">
   <!--
        test+.+id 锁定唯一SQL语句
        resultType 结果集封装类型
        parameterType 参数的数据类型
        SQL语句中的取参数语法 #{基本类型 任意命名}
    -->
   <select id="queryUserById" parameterType="Integer" resultType="com.itheima.pojo.User">
      select * from user where id=#{id}
</select>
</mapper>
  • 实现步骤

    • Resources获取字节输入流,绑定配置文件
    • SqlSessionFactoryBuilder构建工厂
    • SqlSessionFactory创建SqlSession对象
    • SqlSession对象方法selectOne执行查询
public class MyBatisCRUD {
    /**
     * 框架:查询数据表user,根据主键查询
     * */
    public static void main(String[] args) throws IOException {
        testQueryUserById();
    }
    public static void testQueryUserById() throws IOException {
        // 1.SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // MyBatis框架提供类,Resource静态方法  getResourceAsStream()  底层封装的就是加载器,中的流
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        // 2.创建SqlSession接口的实现类对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 3.方法,执行SQL语句
        // selectOne(namespace +"."+id 锁定唯一SQL)方法,查询结果一个对象
        User user = sqlSession.selectOne("test.queryUserById",3);
        System.out.println(user);
        sqlSession.close();
    }
}

配置UserMapper.xml

<!--
           配置,主键查询的SQL语句,标签 select
           id具有唯一性
           查询是有结果集
              标签中属性 resultType:配置结果集的类型
           SQL语句有参数的
              标签中属性 parameterType:SQL语句的参数类型
        -->
    <select id="queryUserById" resultType="com.zhuxu.pojo.User" parameterType="Integer">
        <!--
          SQL语句
          MyBatis配置SQL语句,参数不能写问好
          取参数 #{参数名}
          参数名,如果只有一个参数,基本类型及其包装类和String,任意
        -->
        select * from user where id = #{id}
    </select>

2.根据用户名模糊查询

框架:查询数据表user,根据用户名模糊查询
大量的重复性代码:代码坏味道
共性抽取:
目的:SqlSession接口,执行SQL语句
每个功能不同的,SqlSession接口不能抽取

读取配置文件可以抽取
SqlSessionFactory sqlSessionFactory 创建SqlSession接口对象,可以抽取
工厂对象,提升为成员变量

public class MyBatisCRUD {

    /**
     * 框架:查询数据表user,根据用户名模糊查询
     * 大量的重复性代码:代码坏味道
     * 共性抽取:
     *    目的:SqlSession接口,执行SQL语句
     *      每个功能不同的,SqlSession接口不能抽取
     *
     *      读取配置文件可以抽取
     *      SqlSessionFactory sqlSessionFactory  创建SqlSession接口对象,可以抽取
     *      工厂对象,提升为成员变量
     * */


    private SqlSessionFactory sqlSessionFactory;
    @Before
    public void before() throws IOException {
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    }

    
    // 框架:查询数据表user,根据用户名模糊查询
    @Test
    public void testQueryUsername() throws IOException{
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<User> userList = sqlSession.selectList("test.queryUserByUsername", "'%王%'");
        for (User user : userList){
            System.out.println(user);
        }
        sqlSession.close();
    }

    /**
     * 框架:查询数据表user,根据主键查询
     * */

    @Test
    public void testQueryUserById() throws IOException {
        /*// 1.SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // MyBatis框架提供类,Resource静态方法  getResourceAsStream()  底层封装的就是加载器,中的流
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);*/
        // 2.创建SqlSession接口的实现类对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 3.方法,执行SQL语句
        // selectOne(namespace +"."+id 锁定唯一SQL)方法,查询结果一个对象
        User user = sqlSession.selectOne("test.queryUserById",3);
        System.out.println(user);
        sqlSession.close();
    }
}

UserMapper.xml配置文件

<mapper namespace="test">

    <!--
        配置,数据表user模糊查询
        用户名模糊查询
        SQL语句参数
        ${参数名} 写参数名字固定写为value
    -->
    <select id="queryUserByUsername" resultType="com.zhuxu.pojo.User" parameterType="String">
        select * from user where username like ${value}
    </select>

3.#{}和${} 获取参数的区别

能用#{}不用${}

使用#的原理是 参数编译为 ? 占位符,更快更高效,框架底层使用的是JDBC中的接口 PreparedStatement

$的原理是拼接方式

select * from user where username like #{value}
--运算时为
select * from user where username like ? '%王%'

select * from user where username like ${value}
--运算时为
select * from user where username like '%王%'

4.添加用户

使用子标签

selectKey 标签体中会在执行一次SQL语句

新增操作:insert标签中,子标签 获取上一次新增主键值
属性:
order = "after或者before" 获取主键,是在SQL语句之前,还是之后执行
resultType 获取逐渐的结果数据类型
keyProperty 属性,查询后的值放在哪里 pojo对象的属性中

<selectKey order="AFTER" resultType="Integer" keyProperty="id">
    <!--新增数据获取最新的主键-->
    select last_insert_id ()
</selectKey>

5.修改和删除用户

修改

实现步骤

  • Resources获取字节输入流,绑定配置文件
  • SqlSessionFactoryBuilder构建工厂
  • SqlSessionFactory创建SqlSession对象
  • SqlSession对象方法update | delete 更新数据
  • 提交事务

UserMapper.xml配置文件中

<!--
        配置更新数据,标签update  修改数据
    -->
    <update id="updateUserById" parameterType="com.zhuxu.pojo.User">
        update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address} where id = #{id}
    </update>

<!--
        配置删除数据
    -->
    <delete id="deleteUserById" parameterType="Integer">
        delete from user where id = #{id}
    </delete>

java类

private SqlSessionFactory sqlSessionFactory;
    @Before
    public void before() throws IOException {
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    }

    @Test
    /*实现更新数据*/
    public void testUpdateUserById(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = new User();
        user.setId(7);// 要修改的主键
        user.setUsername("大桥");
        user.setSex("女");
        user.setBirthday(new Date(0));
        user.setAddress("益州");

        int row = sqlSession.update("test.updateUserById", user);
        sqlSession.commit();
        System.out.println(row);
        sqlSession.close();
    }

// 删除数据
@Test
    public void testDeleteUserById(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        int row = sqlSession.delete("test.deleteUserById", 7);
        sqlSession.commit();
        sqlSession.close();
        System.out.println(row);
    }

6.原始dao层开发方式

  • 实现步骤
    • 定义dao层接口
    • 定义dao层接口实现类
public interface UserDao {
    User queryUserById(Integer id);
}
public class UserDaoImpl implements  UserDao {
    private SqlSessionFactory sqlSessionFactory;

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

    @Override
    public User queryUserById(Integer id) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = sqlSession.selectOne("test.queryUserById", id);
        sqlSession.close();
        return user;
    }
}
@Test
public void userTest() throws IOException {
    InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    UserDao userDao = new UserDaoImpl(sqlSessionFactory);
    User user = userDao.queryUserById(1);
    System.out.println(user);
}

7.动态代理技术

原理:

利用反射技术

不修改源码的情况下,增强功能

java.lang.reflect.Proxy 动态代理类

定义一个Mapper接口,这个接口其实和我们UserDao接口是一样的,从Mybatis框架中拿到一个代理对象(代理的是这个Mapper接口),通过代理对象调用接口当中的方法完成业务。
传统dao开发方式中的实现类其实起了一个连接、承上启下的作用,连接了接口和xml映射文件,效果就是调用接口方法时能够找到xml映射文件。

  • Mapper动态代理开发遵从的规范
    • sql映射文件的namespace必须和mapper接口的全限定类名保持一致
    • mapper接口的接口方法名必须和xml中的sql语句id保持一致
    • mapper接口的接口方法形参类型必须和sql语句的输入参数类型保持一致
    • mapper接口的接口方法返回类型必须和sql语句的resultType保持一致

小结

MyBatis动态代理开发(以后都是用的方式)简化开发

限制:

  1. dao层包名,修改为mapper

    定义接口 UserMapper,查询所有数据的方法(抽象)

    MyBatis框架,自动为我们生成接口实现类对象

  2. UserMa.xml配置文件,配置的是user表下的SQL语句

    配置文件,必须和接口在同一目录下

  3. 配置文件中的属性 namespace的属性值必须和接口的全类名一致

  4. 接口中的方法名,必须和SQL语句标签的id值相同

    参数和返回值都必须相同

  5. XXXMapper.xml配置文件的路径不要写错

示例代码:

SqlMapConfig.xml配置文件

<mappers>
        <!--
            路径写法:动态代理开发
            配置文件xml和接口在一个目录下
        -->
        <mapper resource="com/zhuxu/mapper/UserMapper.xml" />
</mappers>

UserMapper.xml配置文件

<mapper namespace="com.zhuxu.mapper.UserMapper">

    <!--配置查询所有的user表数据-->
    <select id="queryUser" resultType="com.zhuxu.pojo.User">
            select * from user
    </select>
</mapper>

UserMapper接口

public interface UserMaper{
     /**
     * 查询所有数据表user的接口
     * */
    List<User> queryUser();
}

实现类

public class MyBatisProxy {

    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void before() throws IOException {
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    }

    @Test
    /*
    * 动态代理方式,代理的是mapper包下的接口
    * */
    public void testQueryUser(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // SqlSession接口的方法  getMapper()
        /*
        * 参数是代理的接口的class文件对象
        * 返回值就是代理接口的实现类对象
        *
        * UserMapper接口的实现类
        * */
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userMapper.queryUser();
        for (User user:userList){
            System.out.println(user);
        }
        sqlSession.close();
    }


}

1.主键查询

UserMapper.xml配置文件

    <!--配置主键查询-->
    <select id="queryUserById" parameterType="Integer" resultType="com.zhuxu.pojo.User">
        select * from user where id = #{id}
    </select>

UserMapper接口

public interface UserMaper{
     /**
     * 根据主键查询
     * */
    User queryUserById(Integer id);
    
}

实现类

/**
     * 动态代理方式,代理mapper包下的接口
     * 主键查询
     * */
    @Test
    public void testQueryById(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.queryUserById(6);
        System.out.println(user);
        sqlSession.close();
    }

2.新增数据

注意 使用注解开发不需要写UserMapper.xml配置文件

UserMapper.xml配置文件

	<!--配置新增-->
    <insert id="saveUser" parameterType="com.zhuxu.pojo.User">
        insert into user values (null ,#{username},#{sex},#{birthday},#{address})
    </insert>

UserMapper接口

public interface UserMaper{
     /**
     * 新增数据
     * */
    // 注解开发
    // @Insert("insert into user values (#{id} ,#{username},#{sex},#{birthday},#{address})")
    
    int saveUser(User user);
    
}

实现类

/**
     * 动态代理方式,代理mapper包下的接口
     * 新增数据
     * */
    @Test
    public void testSaveUser(){
        User user = new User();
        user.setId(7);
        user.setUsername("安琪拉");
        user.setSex("女");
        user.setAddress("中国");
        user.setBirthday(new Date());

        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        int row = userMapper.saveUser(user);
        sqlSession.commit();
        System.out.println(row);
        sqlSession.close();

    }

7.全局properties配置

配置标签,引用外部的properties文件

实用价值不大

db.properties配置文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

SqlMapConfig.xml配置文件

<environment id="development">
    <transactionManager type="JDBC" />
    <dataSource type="POOLED">
        <property name="driver" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </dataSource>
</environment>

8.全局typeAliases配置

别名 映射的类型
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
map Map

结果集数据类型定义别名,别名不区分大小写

<typeAliases>
    <!-- 为pojo对象定义别名-->
    <typeAlias type="com.itheima.pojo.User" alias="user"></typeAlias>
</typeAliases>
<!-- 使用别名即可-->
<select id="queryUserById" parameterType="int" resultType="User">
   select * from user where id=#{id}
</select>

扫描所有pojo包下的类。注意:不可以出现相同的类名

<typeAliases>
    <!--<typeAlias type="com.itheima.pojo.User" alias="user"></typeAlias>-->
    <!-- 自动扫描pojo包下的全部类-->
    <package name="com.itheima.pojo" ></package>
</typeAliases>

9.全局配置文件mappers

  • mappers注册sql映射文件的
    • resource属性加载sql映射文件,万能型选手(crud、原始dao、mapper动态代理)
    • 针对Mapper动态代理进行一个增强(增强两种用法)
    • mapper class 单个注册
    • package 批量扫描注册
    • 以上两种方式有规范要求
<mappers>
        <!--
            路径写法:动态代理开发
            配置文件xml和接口在一个目录下
        -->
        <!--
            自动扫描配置
            mapper配置的xml文件的路径(SQL语句配置文件)
            一个数据表对应一个xml

            mapper标签的属性 resource="xml路径"
            package标签的属性 name= “包名”

            <package name="com.zhuxu.mapper"></package>
            框架自动扫描配置包下的xml文件
        -->
        <package name="com.zhuxu.mapper"></package>
        <!--<mapper resource="com/zhuxu/mapper/UserMapper.xml" />-->
    </mappers>

10.MyBatis输入参数类型

pojo包装类型,一个pojo类中,包含了另一个pojo类。

public class QueryVo {
    private User user;
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
}
public interface UserMapper {
    User queryUserById(Integer id);
    List<User> queryUserByQueryVo(QueryVo queryVo);
}
@Test
public void userMapperQueryVo(){
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    QueryVo queryVo = new QueryVo();
    User user = new User();
    user.setUsername("%王%");
    queryVo.setUser(user);
    List<User> list = mapper.queryUserByQueryVo(queryVo);
    for(User u :list){
        System.out.println(u);
    }
    sqlSession.close();
}
<select id="queryUserByQueryVo" resultType="user" parameterType="queryvo">
   select * from user where username like #{user.username}
</select>

11.MyBatis手动映射

OrdersMapper接口

public interface OrdersMapper {
    /**
     * 查询订单的全部数据
     */
    List<Orders> queryOrders();
}

配置文件

<!--属性值,必须和接口的全类名一致-->
<mapper namespace="com.zhuxu.mapper.OrdersMapper">

    <!--
        配置查询所有订单的SQL
        查询需要使用自己配置的映射
        select  标签属性resultMap,属性值,请写手动映射标签resultMap的id值
    -->
    <select id="queryOrders" resultType="orders" resultMap="ordersResultMap">
        select * from orders
    </select>

    <!--
        手动映射,手动配置pojo对象的属性名和数据表的列名resultMap
        属性:id=“” 唯一性
        type 结果类型,pojo对象
    -->
    <resultMap id="ordersResultMap" type="orders">
        <!--配置的就是数据表的列和pojo对象成员变量的对应关系-->

        <!--
            id配置的是主键
            columns列名
            property pojo 对象属性名
        -->
        <id column="id" property="id"></id>
        <!--配置其他列-->
        <result column="user_Id" property="userId"></result>
        <result column="number" property="number"></result>
        <result column="createrime" property="createtime"></result>
        <result column="note" property="note"></result>

    </resultMap>

</mapper>

实现类

/**
     * 动态代理,代理的接口是一个OrdersMapper接口
     */
    @Test
    public void testQueryOrders(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
        List<Orders> ordersList = ordersMapper.queryOrders();
        for (int i = 0; i < ordersList.size(); i++) {
            Orders orders = ordersList.get(i);
            System.out.println(orders);
        }
    }
posted @ 2020-07-19 15:10  _Anke  阅读(364)  评论(0编辑  收藏  举报