【Java中级】30.0 SSM之Mybatis框架(一)——入门、增删查改、架构和动态代理Dao包装

1.0 Java后台项目框架分为web层、业务层、Dao层(持久层)。

三者采用什么架构没有非常必然的联系。所以就有了SSM和SSH等不同的组合方式。

2.0 常见的持久层框架

DBUtils , Hibernate,Mybatis。

3.0 为什么学Mybatis?
    1. 目前最主流的持久层框架为hibernate与mybatis,而且国内目前情况使用Mybatis的公司比hibernate要多。
    1. Hibernate学习门槛不低,要精通门槛更高。门槛高在怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate缓存与数据加载策略方面需要你的经验和能力都很强才行。国内目前前的情况精通hibernate技术大牛非常少。
    1. sql优化方面,Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。当然了,Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。说得更深入一些,如果有个查询要关联多张表,比如5张表,10张表时,而且,我们要取的字段只是其中几张表的部分字段。这时用hibernate时就会显得非常力不从心。就算用hibernate的sqlquery,后续的维护工作也会让人发狂
4.0 2JDBC编程回顾与存在的问题分析
4.1 开发步骤
  • 1.导入数据脚本,在课前资料中有
  • 2.创建工程,导入mysql jar包
  • 3.编码
4.2Jdbc访问数据库的过程:
1.加载数据库驱动
2.创建数据库连接
3.创建statement
4.设置sql语句
5.设置查询参数
6.执行查询,得到ResultSet
7.解析结果集ResultSet
8.释放资源
5.0 Mybatis介绍
  • MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
  • Mybatis是面向sql的持久层框架,他封装了jdbc访问数据库的过程,我们开发,只需专注于sql语句本身的拼装,其它复杂的过程全部可以交给mybatis去完成。
6.0 Mybaits入门
6.1 建立数据库
/*
Navicat MySQL Data Transfer

Source Server         : localhost_3306
Source Server Version : 50521
Source Host           : localhost:3306
Source Database       : mybatis

Target Server Type    : MYSQL
Target Server Version : 50521
File Encoding         : 65001

Date: 2015-04-09 16:03:53
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `orders`
-- ----------------------------
DROP TABLE IF EXISTS `order`;
CREATE TABLE `order` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT '下单用户id',
  `number` varchar(32) NOT NULL COMMENT '订单号',
  `createtime` datetime NOT NULL COMMENT '创建订单时间',
  `note` varchar(100) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`),
  KEY `FK_orders_1` (`user_id`),
  CONSTRAINT `FK_order_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of orders
-- ----------------------------
INSERT INTO `order` VALUES ('3', '1', '1000010', '2015-02-04 13:22:35', null);
INSERT INTO `order` VALUES ('4', '1', '1000011', '2015-02-03 13:22:41', null);
INSERT INTO `order` VALUES ('5', '10', '1000012', '2015-02-12 16:13:23', null);

-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) NOT NULL COMMENT '用户名称',
  `birthday` date DEFAULT NULL COMMENT '生日',
  `sex` char(1) DEFAULT NULL COMMENT '性别',
  `address` varchar(256) DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', '王五', null, '2', null);
INSERT INTO `user` VALUES ('10', '张三', '2014-07-10', '1', '北京市');
INSERT INTO `user` VALUES ('16', '张小明', null, '1', '河南郑州');
INSERT INTO `user` VALUES ('22', '陈小明', null, '1', '河南郑州');
INSERT INTO `user` VALUES ('24', '张三丰', null, '1', '河南郑州');
INSERT INTO `user` VALUES ('25', '陈小明', null, '1', '河南郑州');
INSERT INTO `user` VALUES ('26', '王五', null, null, null);

6.2 工程搭建
image.png
1.导入依赖jar包
2.配置SqlMapConfig.xml
3.配置log4j.properties
5.配置sql查询的映射文件
6.加载映射文件
image.png

这里我本地数据库版本是MySQL 8.0.18。
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>
    <!-- 和spring整合后 environments配置将废除 -->

    <!--  development是开发环境 -->
    <environments default="development">
        <!-- 可以设置多个environment -->
        <environment id="development">
            <!-- 使用jdbc事务管理 -->
            <transactionManager type="JDBC" />
            <!-- 数据库连接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver" />
                <property name="url"
                    value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;serverTimezone=UTC"/>
                    
                <property name="username" value="root" />
                <property name="password" value="bywwcnll" />
            </dataSource>
        </environment>
    </environments>
    
<!--    加载映射文件 -->
    <mappers>
<!--    resource -->
    <mapper resource="mybatis/user.xml"/>
    </mappers>
</configuration>

log4j.properties

log4j.rootLogger=DEBUG, Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

也可以这样配置:

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE

# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

User.java

package com.edp.mybatis.domain;

/**
 * User的实体类:用户
 * 
 * @author edpeng
 * @DATE 2020年02月18日
 *       CREATE TABLE `user` (
 *       `id` int(11) NOT NULL AUTO_INCREMENT,
 *       `username` varchar(32) NOT NULL COMMENT '用户名称',
 *       `birthday` date DEFAULT NULL COMMENT '生日',
 *       `sex` char(1) DEFAULT NULL COMMENT '性别',
 *       `address` varchar(256) DEFAULT NULL COMMENT '地址',
 *       PRIMARY KEY (`id`)
 *       ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
 * 
 *       添加数据
 *       INSERT INTO `user` VALUES ('1', '王五', null, '2', null);
 *       INSERT INTO `user` VALUES ('10', '张三', '2014-07-10', '1', '北京市');
 *       INSERT INTO `user` VALUES ('16', '张小明', null, '1', '河南郑州');
 *       INSERT INTO `user` VALUES ('22', '陈小明', null, '1', '河南郑州');
 *       INSERT INTO `user` VALUES ('24', '张三丰', null, '1', '河南郑州');
 *       INSERT INTO `user` VALUES ('25', '陈小明', null, '1', '河南郑州');
 *       INSERT INTO `user` VALUES ('26', '王五', null, null, null);
 * 
 */

import java.util.Date;

public class User {

    private Integer id;
    private String username;// 用户姓名
    private String sex;// 性别
    private Date birthday;// 生日
    private String address;// 地址

    public Integer getId() {
        return id;
    }

    public void setId(Integer 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 + "]";
    }
}

Order.java

package com.edp.mybatis.domain;

/**
 * Order的实体类:订单
 * 
 * @author edpeng
 * @DATE 2020年02月18日
 *       CREATE TABLE `order` (
 *       `id` int(11) NOT NULL AUTO_INCREMENT,
 *       `user_id` int(11) NOT NULL COMMENT '下单用户id',
 *       `number` varchar(32) NOT NULL COMMENT '订单号',
 *       `createtime` datetime NOT NULL COMMENT '创建订单时间',
 *       `note` varchar(100) DEFAULT NULL COMMENT '备注',
 *       PRIMARY KEY (`id`),
 *       KEY `FK_orders_1` (`user_id`),
 *       CONSTRAINT `FK_order_id` FOREIGN KEY (`user_id`) REFERENCES `user`
 *       (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
 *       ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
 * 
 *       添加数据
 *       INSERT INTO `order` VALUES ('3', '1', '1000010', '2015-02-04 13:22:35', null);
 *       INSERT INTO `order` VALUES ('4', '1', '1000011', '2015-02-03 13:22:41', null);
 *       INSERT INTO `order` VALUES ('5', '10', '1000012', '2015-02-12 16:13:23', null);
 */
import java.util.Date;

public class Order {
    private Integer id;

    private Integer userId;

    private String number;

    private Date createtime;

    private String note;

    public Integer getId() {
        return id;
    }

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

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number == null ? null : number.trim();
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note == null ? null : note.trim();
    }

    @Override
    public String toString() {
        return "Order [id=" + id + ", userId=" + userId + ", number=" + number + ", createtime=" + createtime
                + ", note=" + note + "]";
    }
}

User.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:相当于package -->
<!-- namespace 命名空间,用于隔离sql语句 -->
<mapper namespace="user">
    <!-- id:sql语句的唯一标识 -->
    <!-- parameterType 入参的数据类型,查询字段的格式 -->
    <!-- resultType:返回结果的数据类型,返回字段包装 -->
    <!-- #{}:占位符,相当于jdbc的问号 -->
    <select id="getUserByid" parameterType="int" resultType="com.edp.mybatis.domain.User">
        SELECT
        *
        FROM `user`
        WHERE id = #{id2}
    </select>
</mapper>

环境搭建的注意事项:

  • 第一个:创建IUserDao.xml 和 IUserDao.java时名称是为了和我们之前的知识保持一致。
    在Mybatis中它把持久层的操作接口名称和映射文件也叫做:Mapper
    所以:IUserDao 和 IUserMapper是一样的
  • 第二个:在idea中创建目录的时候,它和包是不一样的
    包在创建时:com.itheima.dao它是三级结构
    目录在创建时:com.itheima.dao是一级目录
  • 第三个:mybatis的映射配置文件位置必须和dao接口的包结构相同
  • 第四个:映射配置文件的mapper标签namespace属性的取值必须是dao接口的全限定类名
  • 第五个:映射配置文件的操作配置(select),id属性的取值必须是dao接口的方法名
  • 当我们遵从了第三,四,五点之后,我们在开发中就无须再写dao的实现类。
6.3 根据用户ID查询用户信息

MybatisDemo1.java测试代码

package com.edp.mybatis.demo;

import java.io.IOException;
import java.io.InputStream;

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 com.edp.mybatis.domain.User;

public class MybatisDemo1 {

    @Test
    public void testGetUserById() throws IOException {
        // 创建SqlSessionFactoryBuilder类
        SqlSessionFactoryBuilder ssfBuilder = new SqlSessionFactoryBuilder();
        // Mybatis的工具类Resources
        // 创建核心配置文件的输入流
        InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 通过输入流创建SqlSessionFactory对象
        SqlSessionFactory ssFactory = ssfBuilder.build(resourceAsStream);
        // SqlSession对象:内含访问数据库的所有API
        SqlSession sqlSession = ssFactory.openSession();
        // 执行查询
        User user = sqlSession.selectOne("user.getUserByid", 1);

        System.out.println(user);
        // 释放资源
        sqlSession.close();
    }
}

执行:


image.png
6.4 根据用户名模糊查询、添加用户

MybatisDemo1.java

package com.edp.mybatis.demo;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

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 com.edp.mybatis.domain.User;
import com.edp.mybatis.utils.SqlSessionFactoryUtils;

public class MybatisDemo1 {

    @Test
    /**
     * 
     * @Title: testGetUserById
     * @Description: 查询所有用户
     * @param @throws IOException
     * @return void
     * @throws
     *
     */
    public void testGetUserById() throws IOException {
        // 创建SqlSessionFactoryBuilder类
        SqlSessionFactoryBuilder ssfBuilder = new SqlSessionFactoryBuilder();
        // Mybatis的工具类Resources
        // 创建核心配置文件的输入流
        InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 通过输入流创建SqlSessionFactory对象
        SqlSessionFactory ssFactory = ssfBuilder.build(resourceAsStream);
        // SqlSession对象:内含访问数据库的所有API
        SqlSession sqlSession = ssFactory.openSession();
        // 执行查询
        User user = sqlSession.selectOne("user.getUserByid", 1);

        System.out.println(user);
        // 释放资源
        sqlSession.close();

    }

    @Test
    /**
     * 
     * @Title: testGetUserByUserName
     * @Description: 模糊查询
     * @param 
     * @return void
     * @throws
     *
     */
    public void testGetUserByUserName() {
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
        // SqlSession对象:内含访问数据库的所有API
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 执行查询
        List<User> userlist = sqlSession.selectList("user.getUserByUserName", "%张%");
        // List<User> userlist = sqlSession.selectList("user.getUserByUserName", "张");

        for (User user : userlist) {
            System.out.println(user);
        }
        // 释放资源
        sqlSession.close();
    }
    
    
    @Test
    /**
     * 
     * @Title: testInsertUser
     * @Description: 添加(插入)用户
     * @param 
     * @return void
     * @throws
     *
     */
    public void testInsertUser() {
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
        // SqlSession对象:内含访问数据库的所有API
        SqlSession sqlSession = sqlSessionFactory.openSession();
//      SqlSession sqlSession = sqlSessionFactory.openSession(true);就自动commit
        // 执行添加
        User user =new User();
        user.setUsername("非晶体");
        user.setAddress("白菜市场");
        user.setSex("1");
        user.setBirthday(new Date());
        sqlSession.insert("user.insertUser",user);
        //一定要提交
        sqlSession.commit();

        // 释放资源
        sqlSession.close();
    }
    
    
    @Test
    /**
     * 
     * @Title: testUpdateUser
     * @Description: 更新用户
     * @param 
     * @return void
     * @throws
     *
     */
    public void testUpdateUser() {
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
        // SqlSession对象:内含访问数据库的所有API
        SqlSession sqlSession = sqlSessionFactory.openSession();
//      SqlSession sqlSession = sqlSessionFactory.openSession(true);就自动commit
        // 执行添加
        User user =new User();
        user.setId(10);
        user.setUsername("冬瓜太郎");
        sqlSession.update("user.updateUser",user);
        //一定要提交
        sqlSession.commit();

        // 释放资源
        sqlSession.close();
    }
    @Test
    /**
     * 
     * @Title: testDeleteUser
     * @Description: 删除用户
     * @param 
     * @return void
     * @throws
     *
     */
    public void testDeleteUser() {
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
        // SqlSession对象:内含访问数据库的所有API
        SqlSession sqlSession = sqlSessionFactory.openSession();
//      SqlSession sqlSession = sqlSessionFactory.openSession(true);就自动commit
        // 执行添加
        sqlSession.delete("user.deleteUser",30);
        //一定要提交
        sqlSession.commit();

        // 释放资源
        sqlSession.close();
    }
}

user.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:相当于package -->
<!-- namespace 命名空间,用于隔离sql语句 -->
<mapper namespace="user">
    <!-- id:sql语句的唯一标识 -->
    <!-- parameterType 入参的数据类型,查询字段的格式 -->
    <!-- resultType:返回结果的数据类型,返回字段包装 -->
    <!-- #{}:占位符,相当于jdbc的问号 -->
    <!-- ${ }:字符串拼接指令,如果入参为普通数据类型,括号内部只能写value -->
    <select id="getUserByid" parameterType="int" resultType="com.edp.mybatis.domain.User">
        SELECT
        *
        FROM `user`
        WHERE id = #{id2}
    </select>


    <!--resultType 如果返回结果为集合,只需要设置每一个返回值的数据类型 -->
    <select id="getUserByUserName" parameterType="string"
        resultType="com.edp.mybatis.domain.User"
    >
        SELECT
        *
        FROM`user`
        WHERE username LIKE #{name}
        <!-- WHERE username LIKE '%${value}%' -->
    </select>

    <!-- 插入用户 -->
    <!-- useGeneratedKeys="true" 配套使用keyProperty,使用自增,实现主键返回
        keyProperty="id"等于selectKey标签 -->
    <insert id="insertUser" parameterType="com.edp.mybatis.domain.User">
        <!-- 级联添加 -->
        <!-- selectKey:主键返回 -->
        <!-- keyProperty:用户表的主键 -->
        <!-- resultType:主键的数据类型 -->
        <!-- order:指定selectKey合适执行 AFTER 之后 "BEFORE"之前 -->
        <!-- <selectKey keyProperty="id" resultType="int" order="AFTER"> -->
        <!-- SELECT LAST_INSERT_ID() -->
        <!-- </selectKey> -->
        INSERT INTO `user`
        (`username`,
        `birthday`,
        `sex`,
        `address`)
        VALUES (#{username},
        #{birthday},
        #{sex},
        #{address});
    </insert>

    <!-- 插入用户,返回UUID,和主键返回冲突 -->
    <!-- useGeneratedKeys="true" 配套使用keyProperty,使用自增,实现主键返回
        keyProperty="id"等于selectKey标签 -->
    <insert id="insertUserUUID" parameterType="com.edp.mybatis.domain.User">
        <!-- 级联添加 -->
        <!-- selectKey:主键返回 -->
        <!-- keyProperty:用户表的主键 -->
        <!-- resultType:主键的数据类型 -->
        <!-- order:指定selectKey合适执行 AFTER 之后 "BEFORE"之前 -->
        <selectKey keyProperty="uuid2" resultType="string" order="BEFORE">
            SELECT UUID()
        </selectKey>
        INSERT INTO `user`
        (`username`,
        `birthday`,
        `sex`,
        `address`)
        VALUES (#{username},
        #{birthday},
        #{sex},
        #{address});
    </insert>

    <!-- 更新用户 -->
    <update id="updateUser" parameterType="com.edp.mybatis.domain.User">
        UPDATE `user`
        SET username = #{username}
        WHERE
        id = #{id}
    </update>

    <!-- 删除用户 -->
    <delete id="deleteUser" parameterType="int">
        DELETE
        FROM `user`
        WHERE
        id = #{id}
    </delete>
</mapper>
7.0 Mybatis架构体系
image.png
8.0 Dao操作方式动态代理

动态代理开发规则 :只有接口,没有实现类

    1. namespace 必须是接口的全路径名称
    1. 接口的方法名必须与sql id一致
    1. 接口的入参必须与parameterType类型一致
    1. 接口的返回值必须与resultType类型一致

修改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>
    <!-- 和spring整合后 environments配置将废除 -->

    ………………
    
<!--    加载映射文件 -->
    <mappers>
<!--    resource -->
    <mapper resource="mybatis/UserMapper.xml"/>
    <mapper resource="mybatis/user.xml"/>
    </mappers>
</configuration>

UserMapper.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:相当于package -->
<!-- namespace 命名空间,用于隔离sql语句 -->
<!-- 动态代理开发规则 :只有接口,没有实现类
1.namespace 必须是接口的全路径名称
2.接口的方法名必须与sql id一致
3.接口的入参必须与parameterType类型一致
4.接口的返回值必须与resultType类型一致

-->


<mapper namespace="com.edp.mybatis.mapper.UserMapper">
    <!-- id:sql语句的唯一标识 -->
    <!-- parameterType 入参的数据类型,查询字段的格式 -->
    <!-- resultType:返回结果的数据类型,返回字段包装 -->
    <!-- #{}:占位符,相当于jdbc的问号 -->
    <!-- ${ }:字符串拼接指令,如果入参为普通数据类型,括号内部只能写value -->
    <select id="getUserById" parameterType="int" resultType="com.edp.mybatis.domain.User">
        SELECT
        *
        FROM `user`
        WHERE id = #{id2}
    </select>


    <!--resultType 如果返回结果为集合,只需要设置每一个返回值的数据类型 -->
    <select id="getUserByUserName" parameterType="string"
        resultType="com.edp.mybatis.domain.User"
    >
        SELECT
        *
        FROM`user`
        WHERE username LIKE #{name}
        <!-- WHERE username LIKE '%${value}%' -->
    </select>

    <!-- 插入用户 -->
    <!-- useGeneratedKeys="true" 配套使用keyProperty,使用自增,实现主键返回
        keyProperty="id"等于selectKey标签 -->
    <insert id="insertUser" parameterType="com.edp.mybatis.domain.User">
        <!-- 级联添加 -->
        <!-- selectKey:主键返回 -->
        <!-- keyProperty:用户表的主键 -->
        <!-- resultType:主键的数据类型 -->
        <!-- order:指定selectKey合适执行 AFTER 之后 "BEFORE"之前 -->
        <!-- <selectKey keyProperty="id" resultType="int" order="AFTER"> -->
        <!-- SELECT LAST_INSERT_ID() -->
        <!-- </selectKey> -->
        INSERT INTO `user`
        (`username`,
        `birthday`,
        `sex`,
        `address`)
        VALUES (#{username},
        #{birthday},
        #{sex},
        #{address});
    </insert>

    
    <!-- 更新用户 -->
    <update id="updateUser" parameterType="com.edp.mybatis.domain.User">
        UPDATE `user`
        SET username = #{username}
        WHERE
        id = #{id}
    </update>

</mapper>

UserMapper.java

package com.edp.mybatis.mapper;

import java.util.List;

import com.edp.mybatis.domain.User;

/**
 * 
 * @Title: UserMapper.java
 * @Package com.edp.mybatis.mapper
 * @author EdPeng
 * @version 创建时间 2020年2月18日
 * @Description 用户信息持久化接口
 * @version V1.0
 */
public interface UserMapper {

    User getUserById(Integer id);

    List<User> getUserByUserName(String userName);

    void updateUser(User user);
}

MybatisDemo2.java

package com.edp.mybatis.demo;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

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 com.edp.mybatis.domain.User;
import com.edp.mybatis.mapper.UserMapper;
import com.edp.mybatis.utils.SqlSessionFactoryUtils;

/**
 * 
 * @Title: MybatisDemo2.java
 * @Package com.edp.mybatis.demo
 * @author EdPeng
 * @version 创建时间 2020年2月18日
 * @Description 动态Dao代理测试类
 * @version V1.0
 */
public class MybatisDemo2 {

    @Test
    /**
     * 
     * @Title: testGetUserById
     * @Description: 查询所有用户
     * @param @throws IOException
     * @return void
     * @throws
     *
     */
    public void testGetUserById() throws IOException {
        SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
        // 获取接口的代理实现类
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.getUserById(24);
        System.out.println(user);
        sqlSession.close();
    }

    @Test
    /**
     * 
     * @Title: testGetUserByUserName
     * @Description: 模糊查询
     * @param
     * @return void
     * @throws
     *
     */
    public void testGetUserByUserName() {
        SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
        // 获取接口的代理实现类
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userMapper.getUserByUserName("%张%");
        for (User user : userList) {
            System.out.println(user);
        }
        sqlSession.close();
    }

    @Test
    /**
     * 
     * @Title: testInsertUser
     * @Description: 添加(插入)用户
     * @param
     * @return void
     * @throws
     *
     */
    public void testInsertUser() {
        SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
        // 获取接口的代理实现类
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user =new User();
        user.setId(29);
        user.setUsername("火钳刘明");
        userMapper.updateUser(user);
        
        sqlSession.commit();
        sqlSession.close();
    }

}

END

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352