mybatis初级映射

一 前言

系统学习知识请认准知识追寻者(同公众号),错过作者,你有可能要走好多弯路
经过第一篇的入门文章,小白们都对mybatis的搭建流程应该都很熟悉,这篇文章主讲的是如何使用mybatis实现数据库的增删改查,以及相关的标签属性、配置说明,可以说这篇文章是为你以后的学习和工作打下坚实基础文章,小白们要认真看,认真敲,下面是准备的sql语句。此文强到没朋友!!!!

CREATE TABLE `course` (
  `courseName` varchar(255) DEFAULT NULL COMMENT '课程名称',
  `coursePrice` decimal(10,2) DEFAULT NULL COMMENT '课程价格',
  `courseId` int(11) NOT NULL AUTO_INCREMENT COMMENT '课程id',
  PRIMARY KEY (`courseId`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='课程';

INSERT INTO `mybatis`.`course`(`courseName`, `coursePrice`, `courseId`) VALUES ('java基础课', 500.00, 1);
INSERT INTO `mybatis`.`course`(`courseName`, `coursePrice`, `courseId`) VALUES ('javaWeb课程', 1000.00, 2);

二 pom.xml

引入的依赖跟上篇文章一致,这次我们会用到junit单元测试。

 <dependencies>
        <!-- mybatis support-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
        <!-- log4j support -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- junit support -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- mysql support -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.5</version>
        </dependency>

    </dependencies>

三 log4j.properties

log4j.properties 放在 resource目录下,修改包名并配置日志级别为debug,用于打印sql;

log4j.rootLogger = info,stdout

log4j.appender.stdout = org.apache.log4j.ConsoleAppender
## 注意改薄
log4j.logger.com.zszxz.mybatis.config.mapper = debug
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

四 实体

mybatis中经常使用到实体就是可以用作封装参数或者对返回的结果集进行映射到实体;

/**
 * @Author lsc
 * <p> </p>
 */
public class Course {

    // 课程名称
    private String courseName;
    // 课程价格
    private double coursePrice;
    // 主键
    private Long courseId;

    public String getCourseName() {
        return courseName;
    }

    public void setCourseName(String courseName) {
        this.courseName = courseName;
    }

    public double getCoursePrice() {
        return coursePrice;
    }

    public void setCoursePrice(double coursePrice) {
        this.coursePrice = coursePrice;
    }

    public Long getCourseId() {
        return courseId;
    }

    public void setCourseId(Long courseId) {
        this.courseId = courseId;
    }
}

五 mapper配置

mybatis-config.xml 存放于resource目录下,用于配置mybatis;

<?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">

<!-- mybaits配置 -->
<configuration>

    <!-- 全局环境配置-->
    <environments default="development">
        <environment id="development">
            <!-- 事物 -->
            <transactionManager type="JDBC"/>
            <!-- 配置数据源 -->
            <dataSource type="POOLED">
                <!-- 数据库驱动 5.6以上版本使用com.mysql.cj.jdbc.Driver -->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!-- 数据库路径 -->
                <property name="url" value="jdbc:mysql://192.168.0.105:3306/mybatis"/>
                <!-- 账号-->
                <property name="username" value="root"/>
                <!--密码 -->
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 引入自定义mapper.xml 在resource 目录下 -->
    <mappers>
        <mapper resource="configMapper/CourseMapper.xml"/>
    </mappers>
</configuration>

六 使用方法名称查询

6.1 mapper接口与mxl

这么注意命名空间与接口的关系,方法名与id的关系,返回值是类的全限定名;其中CourseMapper.xml文件是放在resource目录下configMapper中;

CourseMapper.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="com.zszxz.mybatis.config.mapper.CourseMapper">

    <select id="getCourseList" resultType="com.zszxz.mybatis.config.entity.Course">
        SELECT * FROM course
    </select>
</mapper>    

mapper接口

public interface CourseMapper {

    /* *
     * @Author lsc
     * <p> 查询课程列表</p>
     * @Param []
     * @Return java.util.List<com.zszxz.mybatis.config.entity.Course>
     */
    List<Course> getCourseList();

  }  

6.2查询测试

这边的@before注解是在每次执行测试类之前都会执行,固后面的查询测试将直接列出测试方法,不会重复@before注解下的方法;

@RunWith(JUnit4.class)
public class SelectTest {

    SqlSession sqlSession = null;

    // @Before 会在执行测试类之前执行该方法
    @Before
    public void before() throws IOException {
        // 资源路径 resource目录下
        String resource = "mybatis-config.xml";
        // 配置mybatis获得输入流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 创建 SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //从 SqlSessionFactory 中获取 SqlSession
        sqlSession= sqlSessionFactory.openSession();
    }
    /* *
     * @Author lsc
     * <p> 查询课程列表</p>
     * @Param []
     * @Return void
     */
    @Test
    public void testSelect(){
        // 使用传入方法名查询形式
        List<Course> getCourseList = sqlSession.selectList("getCourseList");
        for (Course course : getCourseList){
            System.out.println(course.getCourseName());
        }
        sqlSession.close();
    }
}    

6.3 测试结果

==>  Preparing: SELECT * FROM course
[DEBUG] 2019-12-05 21:02:00,238 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==> Parameters:
[DEBUG] 2019-12-05 21:02:00,256 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
<==      Total: 2
java基础课
javaWeb课程

七 使用获取接口方式查询

这种方式是主流方式,你不可能每次查询都输入一个方法名吧,很不现实,我们更倾向于面向对象方式直接调用方法获得想要的结果;

7.1 查询测试

测试结果和上次一致;

 @Test
    public void testSelect2(){
        // 获得mapper的形式
        CourseMapper courseMapper = sqlSession.getMapper(CourseMapper.class);
        // 遍历打印课程
        for (Course course : courseMapper.getCourseList()){
            System.out.println(course.getCourseName());
        }
        sqlSession.close();
    }

7.2 select标签属性说明

属性 说明
id 在命名空间中唯一的标识符,可以代表引用该sql
parameterType 入参的完全限定名或者别名,可选操作,默认未设置。
resultType 返回值的期望类型的类的完全限定名或者别名,可以使用 resultType 或 resultMap,但不能同时使用
resultMap 外部结果集映射配置,可以与实体字段映射;可以使用 resultType 或 resultMap,但不能同时使用
flushCache 设置true会清口本地缓存和二级缓存,默认是false
useCache 设置为true会导致查询结果集保存至二级缓存,对于select默认是true
timeout 抛出异常前,驱动程序等待的最大毫秒数,默认未设置,依赖于驱动
fetchSize 驱动程序每次批量返回行数,默认未设置
statementType 设置STATEMENT,PREPARED 或 CALLABLE 。分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED
resultSetType 设置结果集类型,FORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等价于 unset)默认为设置 DEFAULT
databaseId 如果配置了数据库厂商标识(databaseIdProvider),会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。
resultOrdered 嵌套查询语句中使用,设置为true,则sql执行结果为嵌套结果或者分组
resultSets 在多个结果集情况下,会列出结果集名称,以逗号分隔

八 普通新增

8.1 mapper接口方法

    /* *
     * @Author lsc
     * <p> 普通新增</p>
     * @Param [course]
     * @Return int
     */
    int addCourse(Course course);

8.2 mxl语句

    <insert id="addCourse" parameterType="com.zszxz.mybatis.config.entity.Course">
        INSERT INTO course ( courseName, coursePrice ) VALUES ( #{ courseName },#{ coursePrice });
    </insert>

8.3 测试

 @Test
    public void testInsert(){

        // 创建入参实体 Course
        Course course = new Course();
        course.setCourseName("知识追寻者的心理课");
        course.setCoursePrice(10000);
        // 获得mapper
        CourseMapper courseMapper = sqlSession.getMapper(CourseMapper.class);
        // 调用添加课程方法
        courseMapper.addCourse(course);
        // 事物提交
        sqlSession.commit();
        // 关闭会话
        sqlSession.close();
    }

8.4 执行结果

可以看见我们用#{}在xml中达到了原生jdbc预编译后的结果每次进入都是以?占位符形式,有效防止sql注入问题;${}通常用在获取字段名称,表名,而非入参,否则会有sql注入风险。

[DEBUG] 2019-12-05 21:58:44,193 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==>  Preparing: INSERT INTO course ( courseName, coursePrice ) VALUES ( ?,?);
[DEBUG] 2019-12-05 21:58:44,221 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==> Parameters: 知识追寻者的心理课(String), 10000.0(Double)
[DEBUG] 2019-12-05 21:58:44,224 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
<==    Updates: 1

九 新增返回主键方式一

9.1 mapper接口方法

    /* *
     * @Author lsc
     * <p> 新增数据并获得主键方式1</p>
     * @Param [course]
     * @Return int
     */
    int addCourseAndGetIdbyGen(Course course);

9.2 mxl语句

<insert> 标签中 相比于 <select> 标签多出了3个属性。

  1. useGeneratedKeys 为true,表示使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键。其适用于mysql 、 sqlServer这样有自增主键的数据库管理系统,默认是false;仅对 插入和更新操作有效。
  2. keyProperty 代表主键,mybaits会将主键赋值给这个列,这里我们配置的是实体字段courseId;希望赋值给多个列,默认是以逗号分开;默认是未设置;仅对 插入和更新操作有效。
  3. keyColumn 当主键列不是表中的第一列的时候需要设置。如果希望使用多个生成的列,也可以设置为逗号分隔的属性名称列表。我们这里必须设置,因为作者把 主键放在第三列了,不仔细看作者文章的小朋友等着出错把!默认是未设置;仅对 插入和更新操作有效。
   <insert id="addCourseAndGetIdbyGen" parameterType="com.zszxz.mybatis.config.entity.Course" useGeneratedKeys="true" keyProperty="courseId" keyColumn="courseId">
        INSERT INTO course ( courseName, coursePrice ) VALUES ( #{ courseName },#{ coursePrice });
    </insert>

9.3 测试

小白们这里注意啊,获得插入的主键是从我们入参的Course实体属性中获得;

    @Test
    public void testInsertGetId1(){

        Course course = new Course();
        course.setCourseName("知识追寻者的课程1");
        course.setCoursePrice(100000);
        CourseMapper courseMapper = sqlSession.getMapper(CourseMapper.class);
        courseMapper.addCourseAndGetIdbyGen(course);
        //
        System.out.println("返回的课程id: "+course.getCourseId());
        sqlSession.commit();
        sqlSession.close();
    }

9.4 执行结果

[DEBUG] 2019-12-05 22:17:01,788 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==>  Preparing: INSERT INTO course ( courseName, coursePrice ) VALUES ( ?,?);
[DEBUG] 2019-12-05 22:17:01,820 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==> Parameters: 知识追寻者的课程1(String), 100000.0(Double)
[DEBUG] 2019-12-05 22:17:01,822 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
<==    Updates: 1
返回的课程id: 4

十新增返回主键方式二

10.1 mapper接口方法

    /* *
     * @Author lsc
     * <p> 新增数据并获得主键方式2</p>
     * @Param [course]
     * @Return int
     */
    int addCourseAndGetIdbyKey(Course course);

10.2 mxl语句

这里使用了 <selectKey> 标签做返回插入数据的主键,这种方式使用于具有主键自增的数据库管理系统,也使用于像oracle这样不具有主键自增的数据库管理系统,而且每种数据库管理系统支持的 <selectKey> 标签内容都不一样,但都大同小异,读者可以查阅数据库管理系统相关文档使用。需要注意的是 order 属性,由于mysql这种主键自增型数据库管理系统是语句插入后才能获得主键,固使用 after;如果是 oracle这种非自增型主键数据库管理系统,是语句插入之前主键就以及存在,固要设置属性为before;

    <insert id="addCourseAndGetIdbyKey" parameterType="com.zszxz.mybatis.config.entity.Course">
        INSERT INTO course ( courseName, coursePrice, courseId ) VALUES ( #{ courseName },#{ coursePrice },#{ courseId });
        <selectKey resultType="long" order="AFTER" keyProperty="courseId">
            SELECT LAST_INSERT_ID();
        </selectKey>
    </insert>

10.3 测试

代码很清秀,不用作者多余的注释了吧。

     @Test
    public void testInsertGetId2(){

        Course course = new Course();
        course.setCourseName("知识追寻者的课程2");
        course.setCoursePrice(100000);
        CourseMapper courseMapper = sqlSession.getMapper(CourseMapper.class);
        courseMapper.addCourseAndGetIdbyGen(course);
        //
        System.out.println("返回的课程id: "+course.getCourseId());
        sqlSession.commit();
        sqlSession.close();
    }

10.4 执行结果

[DEBUG] 2019-12-05 22:25:31,232 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==>  Preparing: INSERT INTO course ( courseName, coursePrice ) VALUES ( ?,?);
[DEBUG] 2019-12-05 22:25:31,258 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==> Parameters: 知识追寻者的课程2(String), 100000.0(Double)
[DEBUG] 2019-12-05 22:25:31,261 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
<==    Updates: 1
返回的课程id: 5

十一更新操作

更新相比于查询和插入,其相对简单;

11.1 mapper接口方法

    /* *
     * @Author lsc
     * <p> </p>
     * @Param [course]
     * @Return int
     */
    int updateCourse(Course course);

11.2 mxl语句

    <update id="updateCourse" parameterType="com.zszxz.mybatis.config.entity.Course">
        UPDATE  course set courseName = #{courseName}, coursePrice = #{coursePrice}
         WHERE courseId = #{courseId}
    </update>

11.3 测试

    @Test
    public void testUpdate2(){

        Course course = new Course();
        course.setCourseName("知识追寻者的课程3");
        course.setCoursePrice(1000);
        course.setCourseId(5L);
        CourseMapper courseMapper = sqlSession.getMapper(CourseMapper.class);
        courseMapper.updateCourse(course);
        sqlSession.commit();
        sqlSession.close();
    }

11.4 执行结果

[DEBUG] 2019-12-05 22:38:46,093 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==>  Preparing: UPDATE course set courseName = ?, coursePrice = ? WHERE courseId = ?
[DEBUG] 2019-12-05 22:38:46,121 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==> Parameters: 知识追寻者的课程3(String), 1000.0(Double), 5(Long)
[DEBUG] 2019-12-05 22:38:46,124 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
<==    Updates: 1

十二删除操作

删除操作和更新操作类似,没什么技巧难度;

12.1 mapper接口方法

    /* *
     * @Author lsc
     * <p> </p>
     * @Param []
     * @Return int
     */
    int deleteCourse(Long courseId);

12.2 mxl语句

    <delete id="deleteCourse" parameterType="long">
        DELETE FROM course WHERE courseId = #{courseId}
    </delete>

12.3 测试

    @Test
    public void testDelte(){

        CourseMapper courseMapper = sqlSession.getMapper(CourseMapper.class);
        courseMapper.deleteCourse(1L);
        sqlSession.commit();
        sqlSession.close();
    }

12.4 执行结果

[DEBUG] 2019-12-05 22:39:29,926 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==>  Preparing: DELETE FROM course WHERE courseId = ?
[DEBUG] 2019-12-05 22:39:29,952 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==> Parameters: 1(Long)
[DEBUG] 2019-12-05 22:39:29,955 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
<==    Updates: 1

十三 参考文档

mybatis官方文档

原文地址:https://www.cnblogs.com/zszxz/p/12065725.html

时间: 2024-11-08 23:12:56

mybatis初级映射的相关文章

mybatis中映射文件和实体类的关联性

mybatis的映射文件写法多种多样,不同的写法和用法,在实际开发过程中所消耗的开发时间.维护时间有很大差别,今天我就把我认为比较简单的一种映射文件写法记录下来,供大家修改建议,争取找到一个最优写法~~: 以User对象和UserMap.xml为例讲解,代码如下: User为用户实体类(仅作为讲解,可以只关注引用类型变量,get/set方法省略): import com.google.common.collect.Lists; import com.gukeer.common.persisten

(十一)mybatis之映射器(select)

映射器 映射器的主要元素有八种: 元素名称 描述 select 查询语句,可自定义参数 insert 插入语句,执行后返回插入的条数 update 更新语句,执行后返回更新的条数 delete 删除语句,执行后返回删除的条数 sql 定义一部分的sql,被各处引用 resultMap 描述从数据库中得到的结果,提供映射规则 cache 给定命名空间的缓存配置 cache-ref 其他命名空间缓存配置的引用   select元素 ①   简单地应用查询的select元素: <select id =

MyBatis SpringMVC映射配置注意

applicationContext.xml中要配置 <!-- MyBatis 的 sqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <pro

mybatis一对一映射配置详解

听说mybatis一对一有三种写法,今天我试了一下. 数据库表准备 为了偷懒,我直接就拿用户权限菜单里的菜单表和菜单与权限的中间表做实现,他们原来是多对多的关系,这边我假设这两张表是一对一. 表  gl_role_men:id,role_id,menu_id     --------->  实体类 GlrolemenuModel  private String id;private String roleId;private String menuId;private MenuModel men

MyBatis -- sql映射文件详解

MyBatis 真正的力量是在映射语句中.和对等功能的jdbc来比价,映射文件节省很多的代码量.MyBatis的构建就是聚焦于sql的. sql映射文件有如下几个顶级元素:(按顺序) cache配置给定命名空间的缓存. cache-ref从其他命名空间引用缓存配置. resultMap最复杂,也是最有力量的元素,用来描述如何从数据库结果集中来加载你的对象. parameterMap已经被废弃了!老式风格的参数映射.内联参数是首选,这个元素可能在将来被移除. sql可以重用的SQL块,也可以被其他

mybatis关系映射之一对多和多对一

一. 简介: 本实例使用顾客和订单的例子做说明: 一个顾客可以有多个订单, 一个订单只对应一个顾客 二. 例子: 1. 代码结构图: 2. 建表语句: CREATE DATABASE test; USE test; CREATE TABLE person( personId VARCHAR(36) PRIMARY KEY, personName VARCHAR(64), personAddress VARCHAR(128), personTel VARCHAR(11) ); CREATE TAB

Mybatis关联映射

Mybatis是半自动化的ORM框架,相比于Hibernate具有更好的灵活性,更容易进行性能优化,当然Hibernate和Mybatis各具特点,并不存在技术的优劣问题,只是应用场景不同,对于一个优秀的开发人员来说最好二者的技术都能掌握.Mybatis需要程序员完成实体类属性和数据库表字段之间的映射设计,并可以定制化返回类型,因此具有更高的灵活性,设计数据库表间的关联映射是Mybatis的核心,本文主要描述Mybatis进行表间关联映射设计的基本内容,包括完成一对一.一对多.多对多常见关联关系

Mybatis输入输出映射

一.输入映射 1.传递简单类型 <select id="findUserById" parameterType="int" resultType="com.test.pojo.User"> select * from user where id = #{id}</select> 2.传递pojo对象 Mybatis使用OGNL表达式解析对象字段的值. <select id="findUserByUser&q

MyBatis学习-映射文件标签篇

MyBatis 真正的核心在映射文件中.比直接使用 JDBC 节省95%的代码.而且将 SQL 语句独立在 Java 代码之外,可以进行更为细致的 SQL 优化. 一. 映射文件的顶级元素 resultMap:最复杂,最有力量的元素,用来描述如何从数据库结果集中加载你的对象 sql:可以重用的 sql 代码块 insert:映射插入语句 update:映射更新语句 delete:映射删除语句 select:映射查询语句 cache:配置给定命名空间的缓存 cache-ref:从其他命名空间引用缓