开发环境

jdk1.7.0_72

eclipse:eclipse-3.7-indigo

mysql:mysql5.1

1.1 创建数据库

先导入sql_table.sql,再导入sql_data.sql(记录系统的初始化数据)

通常需要提供初始化数据的数据库脚本。

jdbc编程中问题

企业开发中,根据项目大小、特点进行技术选型 ,jdbc操作数据库时效率是很高的,jdbc也是技术选型的参考。

2.1  jdbc程序

需要数据库的驱动包:

上边是mysql的驱动,下边是oracle的驱动。

2.2 jdbc问题总结

1、数据库连接频繁的创建和关闭,缺点浪费数据库的资源,影响操作效率

设想:使用数据库连接池

2、sql语句是硬编码,如果需求变更需要修改sql,就需要修改java代码,需要重新编译,系统不易维护。

设想:将sql语句 统一配置在文件中,修改sql不需要修改java代码。

3、通过preparedStatement向占位符设置参数,存在硬编码( 参数位置,参数)问题。系统不易维护。

设想:将sql中的占位符及对应的参数类型配置在配置文件中,能够自动输入 映射。

4、遍历查询结果集存在硬编码(列名)。

设想:自动进行sql查询结果向java对象的映射(输出映射)。

mybatis架构

3.1 mybatis介绍

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis,实质上Mybatis对ibatis进行一些改进。 目前mybatis在github上托管。git(分布式版本控制,当前比较流程)

MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

3.2 mybatis架构

mybatis入门程序

4.1 需求

实现用户查询:

根据用户id(主键)查询用户信息(单条记录)

根据用户名称模糊查询用户信息(多条记录)

用户添加

用户删除

用户修改

4.2 导入jar包

从mybatis管网下载(地址:https://github.com/mybatis/mybatis-3/releases)

mybatis-3.2.7.pdf---操作手册

mybatis-3.2.7.jar--核心 jar包

依赖的jar包

4.3 工程结构

4.4 log4j.properties(公用文件)

# Global logging configuration,建议开发环境中要用debuglog4j.rootLogger=DEBUG, stdout# Console output...log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

4.5 SqlMapConfig.xml(公用文件)

通过SqlMapConfig.xml加载mybatis运行环境。

<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 属性定义加载一个properties文件在 properties标签 中配置属性值--><properties resource="db.properties"><!-- <property name="" value=""/> --></properties><!-- 定义 别名 --><typeAliases><!--单个别名的定义alias:别名,type:别名映射的类型  --><!-- <typeAlias type="com.sihai.mybatis.po.User" alias="user"/> --><!-- 批量别名定义指定包路径,自动扫描包下边的pojo,定义别名,别名默认为类名(首字母小写或大写)--><package name="com.sihai.mybatis.po"/></typeAliases><!-- 和spring整合后 environments配置将废除--><environments default="development"><environment id="development"><!-- 使用jdbc事务管理--><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></environments><!--加载mapper映射如果将和spring整合后,可以使用整合包中提供的mapper扫描器,此处的mappers不用配置了。--><mappers><!-- 通过resource引用mapper的映射文件 --><mapper resource="sqlmap/User.xml" /><!-- <mapper resource="mapper/UserMapper.xml" /> --><!-- 通过class引用mapper接口 class:配置mapper接口全限定名要求:需要mapper.xml和mapper.java同名并且在一个目录 中--><!-- <mapper class="com.sihai.mybatis.mapper.UserMapper"/> --><!-- 批量mapper配置 通过package进行自动扫描包下边的mapper接口,要求:需要mapper.xml和mapper.java同名并且在一个目录 中--><package name="com.sihai.mybatis.mapper"/></mappers></configuration>

4.6  实现用户增删改查

4.6.1 pojo(User.java)

package com.sihait.mybatis.po;import java.util.Date;/*** @author sihai*/
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;}@Overridepublic String toString() {return "User [id=" + id + ", username=" + username + ", sex=" + sex+ ", birthday=" + birthday + ", address=" + address + "]";}}

4.6.2 User.xml(重点)

建议命名规则:表名+mapper.xml

早期ibatis命名规则:表名.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">
<!-- namespace命名空间,为了对sql语句进行隔离,方便管理 ,mapper开发dao方式,使用namespace有特殊作用
mapper代理开发时将namespace指定为mapper接口的全限定名-->
<mapper namespace="test">
<!-- 在mapper.xml文件中配置很多的sql语句,执行每个sql语句时,封装为MappedStatement对象
mapper.xml以statement为单位管理sql语句--><!-- 根据id查询用户信息 --><!-- id:唯一标识 一个statement#{}:表示 一个占位符,如果#{}中传入简单类型的参数,#{}中的名称随意parameterType:输入 参数的类型,通过#{}接收parameterType输入 的参数resultType:输出结果 类型,不管返回是多条还是单条,指定单条记录映射的pojo类型--><select id="findUserById" parameterType="int" resultType="com.sihai.mybatis.po.User">SELECT * FROM USER WHERE id= #{id}</select><!-- 根据用户名称查询用户信息,可能返回多条${}:表示sql的拼接,通过${}接收参数,将参数的内容不加任何修饰拼接在sql中。--><select id="findUserByName" parameterType="java.lang.String" resultType="com.sihai.mybatis.po.User">select * from user where username like '%${value}%'</select><!-- 添加用户parameterType:输入 参数的类型,User对象 包括 username,birthday,sex,address#{}接收pojo数据,可以使用OGNL解析出pojo的属性值#{username}表示从parameterType中获取pojo的属性值selectKey:用于进行主键返回,定义了获取主键值的sqlorder:设置selectKey中sql执行的顺序,相对于insert语句来说keyProperty:将主键值设置到哪个属性resultType:select LAST_INSERT_ID()的结果 类型--><insert id="insertUser" parameterType="com.sihai.mybatis.po.User"><selectKey keyProperty="id" order="AFTER" resultType="int">select LAST_INSERT_ID()</selectKey>INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})</insert><!-- mysql的uuid生成主键 --><!-- <insert id="insertUser" parameterType="com.sihai.mybatis.po.User"><selectKey keyProperty="id" order="BEFORE" resultType="string">select uuid()</selectKey>INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})</insert> --><!-- oracle在执行insert之前执行select 序列.nextval() from dual取出序列最大值,将值设置到user对象 的id属性--><!-- <insert id="insertUser" parameterType="com.sihai.mybatis.po.User"><selectKey keyProperty="id" order="BEFORE" resultType="int">select 序列.nextval() from dual</selectKey>INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})</insert> --><!-- 用户删除  --><delete id="deleteUser" parameterType="int">delete from user where id=#{id}</delete><!-- 用户更新 要求:传入的user对象中包括 id属性值--><update id="updateUser" parameterType="com.sihai.mybatis.po.User">update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}</update></mapper>

4.6.3 测试

创建SqlSessionFactory:

package com.sihai.mybatis.first;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.Before;
import org.junit.Test;import com.sihai.mybatis.po.User;/*** @author sihai*/
public class MybatisFirst {// 会话工厂private SqlSessionFactory sqlSessionFactory;// 创建工厂@Beforepublic void init() throws IOException {// 配置文件(SqlMapConfig.xml)String resource = "SqlMapConfig.xml";// 加载配置文件到输入 流InputStream inputStream = Resources.getResourceAsStream(resource);// 创建会话工厂sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);}// 测试根据id查询用户(得到单条记录)@Testpublic void testFindUserById() {// 通过sqlSessionFactory创建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 通过sqlSession操作数据库// 第一个参数:statement的位置,等于namespace+statement的id// 第二个参数:传入的参数User user = null;try {user = sqlSession.selectOne("test.findUserById", 2);} catch (Exception e) {e.printStackTrace();} finally {// 关闭sqlSessionsqlSession.close();}System.out.println(user);}// 测试根据id查询用户(得到单条记录)@Testpublic void testFindUserByName() {// 通过sqlSessionFactory创建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 通过sqlSession操作数据库// 第一个参数:statement的位置,等于namespace+statement的id// 第二个参数:传入的参数List<User> list = null;try {list = sqlSession.selectList("test.findUserByName", "小明");} catch (Exception e) {e.printStackTrace();} finally {// 关闭sqlSessionsqlSession.close();}System.out.println(list.get(0).getUsername());}// 测试根据id查询用户(得到单条记录)@Testpublic void testInsertUser() {// 通过sqlSessionFactory创建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 通过sqlSession操作数据库// 创建插入数据对象User user = new User();user.setUsername("浪子燕青");user.setAddress("河南郑州");user.setBirthday(new Date());user.setSex("1");try {sqlSession.insert("test.insertUser", user);// 需要提交事务sqlSession.commit();} catch (Exception e) {e.printStackTrace();} finally {// 关闭sqlSessionsqlSession.close();}System.out.println("用户的id=" + user.getId());}// 测试根据id删除用户(得到单条记录)@Testpublic void testDeleteUser() {// 通过sqlSessionFactory创建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 通过sqlSession操作数据库try {sqlSession.delete("test.deleteUser", 35);// 需要提交事务sqlSession.commit();} catch (Exception e) {e.printStackTrace();} finally {// 关闭sqlSessionsqlSession.close();}}// 测试根据id更新用户(得到单条记录)@Testpublic void testUpdateUser() {// 通过sqlSessionFactory创建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 通过sqlSession操作数据库// 创建更新数据对象,要求必须包括 idUser user = new User();user.setId(35);user.setUsername("燕青");user.setAddress("河南郑州");
//      user.setBirthday(new Date());user.setSex("1");try {sqlSession.update("test.updateUser", user);// 需要提交事务sqlSession.commit();} catch (Exception e) {e.printStackTrace();} finally {// 关闭sqlSessionsqlSession.close();}System.out.println("用户的id=" + user.getId());}}

5 Mybatis解决jdbc编程的问题

1、 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。

2、 Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。

解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。

3、 向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。

解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。

4、 对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。

解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。

6 mybatis与hibernate重要区别

企业开发进行技术选型 ,考虑mybatis与hibernate适用场景。

mybatis:入门简单,程序容易上手开发,节省开发成本 。mybatis需要程序员自己编写sql语句,是一个不完全 的ORM框架,对sql修改和优化非常容易实现 。

mybatis适合开发需求变更频繁的系统,比如:互联网项目。

hibernate:入门门槛高,如果用hibernate写出高性能的程序不容易实现。hibernate不用写sql语句,是一个ORM框架。

hibernate适合需求固定,对象数据模型稳定,中小型项目,比如:企业OA系统。

总之,企业在技术选型时根据项目实际情况,以降低成本和提高系统 可维护性为出发点进行技术选型。

7 总结

7.1 #{}

表示一个占位符,向占位符输入参数,mybatis自动进行java类型和jdbc类型的转换。

程序员不需要考虑参数的类型,比如:传入字符串,mybatis最终拼接好的sql就是参数两边加单引号。

#{}接收pojo数据,可以使用OGNL解析出pojo的属性值

7.2 ${}

表示sql的拼接,通过${}接收参数,将参数的内容不加任何修饰拼接在sql中。

${}也可以接收pojo数据,可以使用OGNL解析出pojo的属性值

缺点:不能防止sql注入。

mybatis教程--实现增删改查的入门教程相关推荐

  1. springboot+mybatis+mysql(增删改查xml入门编程)

    jdk1.8 idea 2017.2.6 springboot 2.x 项目搭建省略,直接上代码: 项目结构: application.properties配置 server.port=8086#加载 ...

  2. MySQL 学习一:新手一学就会,MySQL 零基础增删改查简单入门教程

    文章目录 前言 一.MySQL 的相关概念介绍 二.Windows 下 MySQL 的配置 2.1.MySQL 安装配置步骤 2.2.MySQL 服务的启动.停止与卸载 三.MySQL 脚本的基本组成 ...

  3. Mybatis基础:增删改查、模糊查询、多条件查询

    Mybatis基础:增删改查.模糊查询.多条件查询http://www.bieryun.com/3132.html 1.新建测试数据库,根据实体类属性创建 2.实体类 [java] view plai ...

  4. SpringBoot + MyBatis + MySQL +IDEA2021 增删改查 2021-06-04

    SpringBoot + MyBatis + MySQL +IDEA2021 增删改查 1.环境介绍 Windows 10 JDK 1.8 MySQL 8 IDEA 2021.1.2 2.开始操作.新 ...

  5. myBatis 简单的增删改查

    myBatis 简单的增删改查 前面已经讲到用接口的方式编程.这种方式,要注意的一个地方就是.在User.xml 的配置文件中, mapper namespace="com.fjh.inte ...

  6. java springboot整合zookeeper入门教程(增删改查)

    java springboot整合zookeeper增删改查入门教程 zookeeper的安装与集群搭建参考:https://www.cnblogs.com/zwcry/p/10272506.html ...

  7. SpringBoot实战系列1:Spring Boot+Mybatis+MySql实现增删改查

    前言 Spring boot项目目前是Java Web开发领域最受市场欢迎的Spring框架之一,也是构建分布式项目.微服务项目重要基础之一,Spring Boot免去了配置繁杂的依赖和配置,使得开发 ...

  8. 【Mybatis 之应用篇】1_Mybatis简介、第一个Mybatis程序和增删改查在Mybatis中的使用方式

    文章目录 Mybatis 一.简介 1.持久化 2.持久层 3.为什么需要Mybatis? 二.第一个Mybatis程序 1.创建一个数据库 2.配置pom.xml文件 3.创建实体类 4.创建一个M ...

  9. MyBatis批量的增删改查操作

    本文转载至http://blog.csdn.net/mahoking 前文我们介绍了MyBatis基本的增删该查操作,本文介绍批量的增删改查操作.前文地址:http://blog.csdn.net/m ...

最新文章

  1. 人工智能正在推动芯片的复兴
  2. 第2周第4课:set_uid、set_gid、stick_bit、软(硬)链接文件
  3. django in的一点心得
  4. 今天的新坑 ubuntu18.04安装docker
  5. 成功解决Instructions for updating: Use `tf.global_variables_initializer` instead.
  6. Programiz C 语言教程·翻译完成
  7. python调用metasploit自动攻击_Python脚本与Metasploit交互进行自动永恒之蓝攻击-Go语言中文社区...
  8. Bailian3247 回文素数【素数+回文】(POJ NOI0113-11)
  9. 灵魂一问:一个TCP连接可以发多少个HTTP请求?
  10. Miller-rabin判素数
  11. php 仿安居客源码_python抓取安居客小区数据的程序代码
  12. project.management.cattle.io not found
  13. 怎么对比两个excel文档的数据差异
  14. 简化预测集合的永磁同步电机的无差拍预测转矩控制系统Simulink仿真
  15. 战舰世界选服务器删除什么文件夹,《战舰世界》常见问题解决方案合集
  16. Scrum板与Kanban如何抉择?kdliihoap板与按照xhvrcr
  17. 匿名留言板表白墙 小程序校园树洞带后台
  18. antony.net
  19. 微信扫描PC端二维码跳转到小程序确认登录通过WebSocket来获取用户信息达到PC端登录
  20. c语言快排过程,快速排序(快排)C语言实现

热门文章

  1. STL源代码分析(ch 1)组态1
  2. C++ Primer 5th笔记(chap 17 标准库特殊设施)smatch
  3. EOS开发步骤(2) 钱包操作
  4. Kubernetes构建过程分析
  5. 131. 分割回文串(回溯算法)
  6. 【Flask】项目中使用请求钩子的妙处有那些?
  7. Django Models 多条件查询 以及Q/F查询
  8. ANSI,ASCII,UNICODE
  9. 1.10 System类详解
  10. 计算两个日期相差的小时差