Mybatis入门_OhNewbie_M的博客-程序员秘密

技术标签: java  maven  数据库  

简介

JDBC存在的问题

  • 数据库的连接创建、释放频繁造成系统资源浪费,使用数据库连接池可解决

    • 数据库连接池:负责分配、管理和释放数据库连接,允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个
  • SQL语句在代码中硬编码,代码维护不易,在应用中Sql变化大,一旦变动就要修改代码

    • 硬编码是将数据直接嵌入到源代码中,只能通过编辑源代码重新编译可执行文件来修改
  • 使用preparedStatement时,占位符?可能接收硬编码,当条件子句不一定时,占位符可多可少。改完sql要改代码,维护不易

  • 对结果集解析存在硬编码,将数据库记录封装成pojo对象解析方便

上面的问题借助DBUtils或Spring中自带的数据库操作框架JdbcTemplate,解决一定程度的问题

真正解决问题的是:

  • Jpa
  • MyBatis

MyBatis介绍

  • 优秀的持久层框架
  • 对操作数据库过程进行封装,只关注Sql,不用费力去处理代码
  • 通过xml或注解的方式将要执行的各种statement配置起来,映射生成最终的执行sql语句,MyBatis将结果映射成Java对象返回
  • MyBatis不将Java对象与数据库表关联起来,将Java方法与SQL语句关联
  • MyBatis允许用户充分利用数据库的各种功能

第一个程序

创建数据库

CREATE DATABASE `stumsg`;
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int NOT NULL,
  `name` varchar(45) DEFAULT NULL,
  `sex` varchar(45) DEFAULT NULL,
  `number` varchar(45) DEFAULT NULL,
  `address` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `student` VALUES 
	(1,'李继勇','男','12337623816','山东省'),
	(2,'张航','男','23839203813','海南省'),
	(3,'赵涛','男','27301820912','安徽省'),
	(4,'张美娜','女','38201739103','云南省'),
	(5,'夏佳宁','女','18392748372','新疆省'),
	(6,'金斐','女','17392640933','山东省');

创建普通maven工程

  • file-new-project
  • 选择maven
  • 一直下一步即可

添加依赖

<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.20</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<!-- 解决maven资源过滤问题 -->
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <filtering>false</filtering>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

构建父工程

  • 将src目录删除
  • 选择父项目(刚才创建的项目)
  • 右击-new-module
  • 选择maven项目

构建核心配置文件

  • 在resources文件夹下右击
  • 选择file
  • 输入mybatis-config.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="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/stumsg?useSSL=false&amp;serverTimezone=UTC"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
      </dataSource>
    </environment>
  </environments>
    
  <mappers>
      <!-- 改为映射文件XxxMapper.xml所在的路径 -->
    <mapper resource="com/ma/mapper/StudentMapper.xml"/>
  </mappers>
</configuration>

构建SqlSessionFactory

package com.ma.utils;

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 java.io.IOException;
import java.io.InputStream;

/**
 * @author :Myy
 * @date :Created in 2021/9/5 14:20
 */
public class Utils {
    
    // 提升作用域
    private static SqlSessionFactory sqlSessionFactory;

    static {
    
        try {
    
            // 获取SqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        }catch (IOException e) {
    
            e.printStackTrace();
        }
    }
	
    // 获取
    public static SqlSession getSqlSession() {
    
        return sqlSessionFactory.openSession();
    }
}

编写实体类

package com.ma.pojo;

/**
 * @author :Myy
 * @date :Created in 2021/9/5 11:25
 */
public class Student {
    
	// 属性
    
    // 构造方法

	// 重写toString方法
    
    // Getter方法 Setter方法
}

编写持久层

package com.ma.mapper;

import com.ma.pojo.Student;

import java.util.List;

/**
 * @author :Myy
 * @date :Created in 2021/9/5 11:27
 */
public interface StudentMapper {
    
    List<Student> selectAllStudent();
}

编写映射文件XxxMapper.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接口 -->
<mapper namespace="com.ma.mapper.StudentMapper">
    <!-- id填写持久层的方法名 -->
    <!-- 返回结果集路径是持久层 -->
    <select id="selectAllStudent" resultType="com.ma.pojo.Student">
        select * from student ;
    </select>
</mapper>

测试

快捷方法:

  • 在接口中右击
  • 选择goto
  • 选择test
  • 点击create new test
package com.ma.dao;

import junit.framework.TestCase;

/**
 * @author :Myy
 * @date :Created in 2021/9/5 15:15
 */
public class StudentMapperTest extends TestCase {
    
    @Test
    public void testSelectAllStudent() {
    
    	SqlSession sqlSession = Utils.getSqlSession();

    	StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

    	List<Student> studentList = studentMapper.selectAllStudent();
    
    	// 获取数据
    	for (Student studentList : studentLists) {
    
            System.out.println(studentList);
        }
    
    	sqlSession.close();
    } 
}

注意:

  • xml文件里不要有中文注释

部分错误总结

  • 搭建环境时
    • 若提示出现中文乱码,在设置中设置编码为utf-8,或者将所有xml文件中的注释删除
    • 空指针异常,查看工具类是否创建了空对象
  • 测试时
    • 持久层接口里的方法名和映射文件里的id要对应
    • 编写测试类的时候,不要忘记注解@Test
    • 且测试类名尽量以TestXxx的形式

CRUD的完善

XxxMapper.xml

<insert id="insertStudent" parameterType="com.ma.pojo.Student">
    insert into student (id,name,sex,number,address)
    values (#{id},#{name},#{sex},#{number},#{address})
</insert>

XxxMapper.java

int insertStudent(Student student);

Test测试

@Test
public void testInsertStudent() {
    
    SqlSession sqlSession = MapperUtils.getSqlSession();
    StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

    studentMapper.insertStudent(new Student(7,"李文博", "男", "12037281909", "湖南省"));

    // 提交事务
    sqlSession.commit();

    // 关闭资源
    sqlSession.close();
}

XxxMapper.xml

<select id="selectAllStudent" resultType="com.ma.pojo.Student">
    select * from student
</select>
<select id="selectStudentById" parameterType="int" resultType="com.ma.pojo.Student">
    select * from student where id = #{id}
</select>

XxxMapper.java

List<Student> selectAllStudent();
Student selectStudentById(int id);

Test测试

@Test
public void testSelectAllStudent() {
    
    SqlSession sqlSession  = MapperUtils.getSqlSession();
    StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

    List<Student> studentLists = studentMapper.selectAllStudent();

    for (Student studentList : studentLists) {
    
        System.out.println(studentList);
    }

    sqlSession.close();
}

@Test
public void testSelectStudentById() {
    
    SqlSession sqlSession  = MapperUtils.getSqlSession();
    StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

    Student student = studentMapper.selectStudentById(1);

    System.out.println(student);

    sqlSession.close();

}

XxxMapper.xml

<update id="updateStudent" parameterType="com.ma.pojo.Student">
    update student set
    				name = #{name},
    				sex = #{sex},
    				number = #{number},
    				address = #{address}
    where id = #{id}
</update>

XxxMapper.java

int updateStudent(Student student);

Test测试

@Test
    public void testUpdateStudent() {
    
        SqlSession sqlSession = MapperUtils.getSqlSession();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

        studentMapper.updateStudent(new Student(7, "王明", "女", "18393048087", "浙江省"));

        sqlSession.commit();
        sqlSession.close();
    }

Mybatis逆向工程

创建普通maven项目

  • file-new-project
  • 选择maven
  • 一直下一步即可

导入jar包

  • 右键项目名称
  • 选择Open Module Settings
  • 点击dependencies
  • 点击+
  • 选择JARs or…
  • 导入mybatis-generator-core.1.4.0.jar
    • jar包下载地址:https://github.com/mybatis/generator/releases/tag/mybatis-generator-1.4.0

导入依赖

<dependency>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-core</artifactId>
    <version>1.4.0</version>
</dependency>

构建配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <commentGenerator>
            <!-- 是否去除自动生成的注释 -->
            <property name="suppressAllComments" value="true" />
        </commentGenerator>
        <!-- Mysql数据库连接的信息:驱动类、连接地址、用户名、密码 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/stumsg?useSSL=false&amp;serverTimezone=UTC"
                        userId="root"
                        password="123456" />
        <!-- 默认为false,把JDBC DECIMAL 和NUMERIC类型解析为Integer,为true时 把JDBC DECIMAL 和NUMERIC类型解析为java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>
        <!-- targetProject:生成POJO类的位置 -->
        <javaModelGenerator
                targetPackage="com.ma.pojo" targetProject="F:/MyBatisLearn/mybatis_reverse/src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- targetProject:mapper映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="com.ma.mapper"
                         targetProject="F:/MyBatisLearn/mybatis_reverse/src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>
        <!-- targetProject:mapper接口生成的的位置 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.ma.dao" targetProject="F:/MyBatisLearn/mybatis_reverse/src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>
        <!-- 指定数据表 有几个表写几个 -->
        <table tableName="数据表名"></table>
        <table tableName="数据表名"></table>
    </context>
</generatorConfiguration>

注意事项:

  • targetPackage里写包名
  • targetProject里写生成代码所在的路径

构建生成代码

import org.mybatis.generator.api.MyBatisGenerator;import org.mybatis.generator.config.Configuration;import org.mybatis.generator.config.xml.ConfigurationParser;import org.mybatis.generator.internal.DefaultShellCallback;import java.io.File;import java.util.*;/** * @author :Myy * @date :Created in 2021/9/10 10:53 */public class GeneratorSqlmap {
        public void generator() throws Exception {
            List<String> warnings = new ArrayList<String>();        boolean overwrite = true;        // 指定配置文件        File configFile = new File("mybatis_reverse/src/main/resources/config/genertorConfig.xml");        ConfigurationParser cp = new ConfigurationParser(warnings);        Configuration config = cp.parseConfiguration(configFile);        DefaultShellCallback callback = new DefaultShellCallback(overwrite);        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);        myBatisGenerator.generate(null);    }    // 执行main方法以生成代码    public static void main(String[] args) {        try {            GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap();            generatorSqlmap.generator();        } catch (Exception e) {            e.printStackTrace();        }    }}

部分错误总结

  • 生成代码中
    • 指定配置文件的路径不要写错,报系统找不到指定位置
    • 路径用 / 分割
  • 配置文件中
    • 数据库连接的信息不要写错,用户、密码、连接地址
    • 指定的数据表有几个写几个。数据表名也不要写错,否则生成代码虽然不报错,但不生成任何文件
    • targetProject里尽量写绝对路径,且用 / 分割,否则不报错,但不生成任何文件
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_50499324/article/details/120280401

智能推荐

Linux hwmon 子系统分析之三 新版本hwmon子系统说明_devm_hwmon_device_register_with_info_jerry_chg的博客-程序员秘密

上一篇文章我们实现了一个模拟的hwmon device,且针对该hwmon device的属性访问操作均是借助sysfs file(我们创建了4个通道温度的sysfs文件temp1_input、temp2_input…),而sysfs file则是我们的虚拟驱动程序借助我们创建device_attribute实现的,然后进行了hwmon_device的注册,相对而言hwmon子系统倒没有提供太多的帮助,而在linux 4.x的版本(4.14已经支持)中,则对hwmon子系统中进行了丰富,针对te...

基于 Python 的图像分类项目实践入门_infer_path_神迹小卒的博客-程序员秘密

课程目标CO1: 学习并掌握图像分类项目的语法基础、深度学习基础CO2: 通过学习和完成图像分类项目 ,初步掌握应用 python 语言调用模型并完成特定图像分类的能力。CO3 :培养学生在开展实践过程中的分工协作,交流表达能力CO4 : 培养学生对实践工作内容的文档写作能力。人工智能基础人工智能是什么,和图像分类项目的关系是什么人工智能( Artificial Intelligence ) ,英文缩写为 AI 。它是研究、开发用于 模拟、延伸和扩展人的智能 ...

ubuntu16.04 cuda8.0 cudnn6.0 faster-rcnn配置_陶宝大人的博客-程序员秘密

参考:http://blog.csdn.net/nicky_lyu/article/details/53181434http://blog.csdn.net/u012841667/article/details/53436615http://www.cnblogs.com/zjutzz/p/6034408.htmlstep 1. 安装常用的dependencies

Scala IDE for Eclipse 之spark scala语言开发环境搭建------遇到问题记录_王树民的博客-程序员秘密

 Scala IDE for Eclipse 之spark scala语言开发环境搭建------遇到问题记录2016年12月29日 19:37:551922人阅读 评论(0) 收藏 举报 分类:Spark(10) 版权声明:你好,欢迎来到我的博客。 https://blog.csdn.net/zwyjg/article/details/53931573spark开发都建议使用idea,但是使用不...

AIO中的AsynchronousServerSocketChannel.accept源码分析_collective_lz的博客-程序员秘密

在AIO中,服务端通过asynchronousServerSocketChannel.accept(this,newAcceptCompletionHandler());的方式接收客户端的连接,那它是怎么做的呢,我们做下源码分析。这个accept方法进入了实现类AsynchronousServerSocketChannelImpl的accept方法,如下: pub

詹金斯搭建_向詹金斯告别,为卫星互联网提供动力,以及更多OpenStack新闻_cumj63710的博客-程序员秘密

詹金斯搭建 您有兴趣跟踪开源云中正在发生的事情吗? Opensource.com是您在开源云基础设施项目OpenStack中获取新闻的来源。 Web上的OpenStack 关于OpenStack,有很多有趣的东西。 以下是一些我们的最爱的示例: 没有Jenkins,只有Zuul :OpenStack最终关闭了它的最后一个Jenkins主机,现在完全使用Zuul来自动化其测试。 ...

随便推点

随笔--读书笔记《软技能:代码之外的生存指南》_暴雪2008的博客-程序员秘密

前言最近读完的一本书,记录下随笔,留下对自己的影响。作为一个入行近10年的十年程序员,这本书中作者对待软件这个职业之外的观点看法,确实很多是我们不经常考虑的。比如健身,你的身体就是你灵魂的真实写照。如何选择饮食,如何控制卡路里,带你入门,引起注意。比如如何提前退休,如何投资,讲解基本的投资知识和经济学原理。对于职业生涯,经常面试看看自己在行业中的位置,番茄工作法,提高工作效率等等。心得绝不要做他人都在做的事。做事情、工作思考目标,目标是什么?关注人际交往能力,虽然是程序员,但不仅仅是跟电脑打交道

[填坑]解决PL2303HXA自2012已停产,请联系供货商_pl2303hxa自2012已停产 请联系供货商_清凉简装的博客-程序员秘密

Windows10 不知道从什么时候开始不再支持PL2303HXA USB转串口芯片了,无法在线获取驱动,需要手动安装。步骤如下:下载驱动:点击下载链接确认USB转串口已经从电脑拔出双击exe安装驱动根据弹窗提示插入USB转串口继续,完成安装安装完成之后可能还有感叹号,重启电脑即可...

Robot Framework - Jenkins 的测试报告打不开的问题_揪揪耳朵的博客-程序员秘密

问题描述:jenkins执行的robot用例,打开log.html时显示: 备注:浏览器版本已经是最新. -场景:用firefox和chrome打开jenkins robot项目的log.html,如上图所示,但是用IE8可以打开log,而IE8打开jenkins会有异常报错;解决方法: 参考:http://blog.csdn.net/max229max/article/details/5

Java命名规范:细节决定成功_yefei679的博客-程序员秘密

注重这些细节有几个好处:1. 好的命名规范可以使得写出来的程序更容易被别人理解,更好维护。当然也易于自己理解,以便日后扩展。   同时,也使程序更规范和专业。  在这个人性化横行的今天,我们的Java命名规范也应该注重体验。2. 了解命名规范,可以更好的学习和记忆 Java 类库中的类和函数等。3. 在命名规范里有很多都涉及到英文的,可以促进英文学习。  比如: numberMax, MaxNumber和maxNumber都是有区别的。  maxNumber可能是属性名; MaxNumber一般是类名; n

使用keil建立标准STM32工程模版(图文详细版!)_嵌入式gpio实验内容在计算机安装keil mdk软件创建stm32工程模板的讨论_寒心雪林-红叶嵌入式的博客-程序员秘密

1.   模板工程的创建(超级详细版)1.1创建工程目录良好的工程结构能让文件的管理更科学,让开发更容易更方便,希望大家养成良好的习惯,使用具有合理结构的工程目录,当你着手于较大的软件项目时,类别分明,层次合理的工程目录结构会让你的开发管理化繁为简。(1)首先在一个目录下创建主文件夹,名字按需求取,这里取名为:(0)工程模板(2)在该文件夹里分别建立名字为Project和Sou

fairseq 安装报错_fairseq安装报错_Kkkkaii的博客-程序员秘密

fairseq 安装报错问题Running setup.py install for fairseq ... errorERROR: Command errored out with exit status 1:command: /Users/superman/anaconda/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/3h/3v_dnwl95tl9k9swb

推荐文章

热门文章

相关标签