一 前言

系统学习知识请认准知识追寻者(同公众号),错过作者,你有可能要走好多弯路

经过第一篇的入门文章,小白们都对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官方文档

mybatis初级映射的更多相关文章

  1. MyBatis初级实战之一:Spring Boot集成

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  2. MyBatis初级实战之二:增删改查

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  3. MyBatis初级实战之三:springboot集成druid

    OpenWrite版: 欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kuber ...

  4. MyBatis初级实战之四:druid多数据源

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  5. MyBatis初级实战之五:一对一关联查询

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  6. MyBatis初级实战之六:一对多关联查询

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  7. 【Mybatis高级映射】一对一映射、一对多映射、多对多映射

    前言 当我们学习heribnate的时候,也就是SSH框架的网上商城的时候,我们就学习过它对应的高级映射,一对一映射,一对多映射,多对多映射.对于SSM的Mybatis来说,肯定也是差不多的.既然开了 ...

  8. MyBatis 关系映射XML配置

    关系映射 在我看来这些实体类就没啥太大关联关系,不就是一个sql语句解决的问题,直接多表查询就完事,程序将它设置关联就好 xml里面配置也是配置了sql语句,下面给出几个关系的小毛驴(xml) 一对多 ...

  9. mybatis高级映射(一对一,一对多)

    mybatis高级映射 一对一关联映射 需求:查询订单信息,关联查询用户信息(一个订单对应一个用户) (1)通过resultType实现 sql语句: select orders.* , USER.u ...

随机推荐

  1. SpringBoot 源码解析 (九)----- Spring Boot的核心能力 - 整合Mybatis

    本篇我们在SpringBoot中整合Mybatis这个orm框架,毕竟分析一下其自动配置的源码,我们先来回顾一下以前Spring中是如何整合Mybatis的,大家可以看看我这篇文章Mybaits 源码 ...

  2. DexOpt相关的异常

    查找的资料 dvm探讨之odex绕过 DexClassLoader4.4.2动态加载分析(磁盘加载分析) - ::): DexOpt: incorrect opt magic number (0xff ...

  3. win上找到host文件的方法

    在运行的位置输入 C:\WINDOWS\system32\drivers\etc

  4. Airtest介绍与脚本入门

    前言 通过阅读本小节教程,你将了解以下内容: 一个Airtest脚本例子的详细解析 如何在Python脚本中调用Airtest接口 图片语句的参数介绍 Airtest介绍 Airtest是一款基于Py ...

  5. JS的对象、数组等处理方法:解构

    对象方法简写 你可以在定义方法时省略function和 :: const obj = { insteadOfThis: function() { // do stuff }, youCanDoThis ...

  6. Flink 中LatencyMarks延迟监控(源码分析)

    流式计算中处理延迟是一个非常重要的监控metric flink中通过开启配置   metrics.latency.interval  来开启latency后就可以在metric中看到askManage ...

  7. UIScrollViewDelegate相关方法

    UIScrollViewDelegate - (void)scrollViewDidScroll:(UIScrollView *)scrollView;//scrollview 滚动的时候调用该方法, ...

  8. 移动前端不得不了解的HTML5 head 头标签 —— link 标签

    目录 link 标签 rss订阅 不推荐的link标签 favicon 图标 link 标签 说到 link 标签,估计大家的第一反应和我一样,就是引入外部CSS样式文件的,不错,这是 link 标签 ...

  9. 如何在ASP.NET Core 中快速构建PDF文档

    比如我们需要ASP.NET Core 中需要通过PDF来进行某些简单的报表开发,随着这并不难,但还是会手忙脚乱的去搜索一些资料,那么恭喜您,这篇帖子会帮助到您,我们就不会再去浪费一些宝贵的时间. 在本 ...

  10. Ceph 概述和理论

    1.1 Ceph概述 官网地址:https://docs.ceph.com/docs/master/ 1.Ceph简介 概述:Ceph是可靠的.可扩展的.统一的.分布式的存储系统.同时提供对象存储RA ...