一、传统连接数据库和执行sql的不足

1、数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响 数据库性能。

设想:使用数据库连接池管理数据库连接。

2、将sql语句硬编码到java代码中,如果sql 语句修改,需要重新编译java代码,不利于系统维护。

设想:将sql语句配置在xml配置文件中,即使sql变化,不需要对java代码进行重新编译。

3、向preparedStatement中设置参数,对占位符号位置和设置参数值,硬编码在java代码中,不利于系统维护。

设想:将sql语句及占位符号和参数全部配置在xml中。

4、从resutSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,,不利于系统维护。

设想:将查询的结果集,自动映射成java对象。

二、mybatis框架

1、 mybatis是什么?

  1. mybatis是一个持久层的框架,是apache下的顶级项目。
  2. mybatis托管到goolecode下,再后来托管到github下(https://github.com/mybatis/mybatis-3/releases)。
  3. mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活生成(半自动化,大部分需要程序员编写sql)满足需要sql语句。
  4. mybatis可以将向 preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象。(输出映射)

2、mybatis框架

三、入门程序

3.1     需求

  1. 根据用户id(主键)查询用户信息
  2. 根据用户名称模糊查询用户信息
  3. 添加用户
  4. 删除用户
  5. 更新用户

3.2     环境

java环境:jdk1.7.0_72

开发工具:eclipse

mysql:5.7

mybatis运行环境(jar包):从https://github.com/mybatis/mybatis-3/releases下载,3.2.7版本

ib下:依赖包

mybatis-3.2.7.jar:核心 包

mybatis-3.2.7.pdf,操作指南

加入mysql的驱动包

lib下的包:

需要建log4j.properties

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

3.3    工程结构

3.4     SqlMapConfig.xml

配置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">
<configuration> <!-- 加载属性文件 -->
<properties resource="db.properties">
<!--properties中还可以配置一些属性名和属性值 -->
<!-- <property name="jdbc.driver" value=""/> -->
</properties>
<!-- 全局配置参数,需要时再设置 -->
<!-- <settings> </settings> --> <!-- 别名定义 -->
<typeAliases> <!-- 针对单个别名定义
type:类型的路径
alias:别名
-->
<!-- <typeAlias type="cn.mybatis.po.User" alias="user"/> -->
<!-- 批量别名定义
指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大写或小写都可以)
-->
<package name="cn.mybatis.po"/> </typeAliases> <!-- 和spring整合后 environments配置将废除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理,事务控制由mybatis-->
<transactionManager type="JDBC" />
<!-- 数据库连接池,由mybatis管理-->
<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>
<!-- 加载 映射文件 -->
<mappers>
<mapper resource="sqlmap/User.xml"/> <!--通过resource方法一次加载一个映射文件 -->
<!-- <mapper resource="mapper/UserMapper.xml"/> --> <!-- 通过mapper接口加载单个 映射文件
遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中
上边规范的前提是:使用的是mapper代理方法
-->
<!-- <mapper class="cn.mybatis.mapper.UserMapper"/> --> <!-- 批量加载mapper
指定mapper接口的包名,mybatis自动扫描包下边所有mapper接口进行加载
遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中
上边规范的前提是:使用的是mapper代理方法
-->
<package name="cn.mybatis.mapper"/> </mappers> </configuration>

3.5     根据用户id(主键)查询用户信息

3.5.1     创建po类

public class User {

	//属性名和数据库表的字段对应
private int id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址

3.5.1     映射文件

映射文件命名:

User.xml(原始ibatis命名),mapper代理开发映射文件名称叫XXXMapper.xml,比如:UserMapper.xml、ItemsMapper.xml

在映射文件中配置sql语句。新建sqlmap/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">

<!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离
注意:使用mapper代理方法开发,namespace有特殊重要的作用
-->
<mapper namespace="test">

<!-- 在 映射文件中配置很多sql语句 -->
<!-- 需求:通过id查询用户表的记录 -->
<!-- 通过 select执行数据库查询
id:标识 映射文件中的 sql
将sql语句封装到mappedStatement对象中,所以将id称为statement的id
parameterType:指定输入 参数的类型,这里指定int型
#{}表示一个占位符号
#{id}:其中的id表示接收输入 的参数,参数名称就是id,如果输入 参数是简单类型,#{}中的参数名可以任意,可以value或其它名称

resultType:指定sql输出结果 的所映射的java对象类型,select指定resultType表示将单条记录映射成的java对象。
-->
<select id="findUserById" parameterType="int" resultType="cn.mybatis.po.User">
SELECT * FROM USER WHERE id=#{value}
</select>

  

3.5.3     在SqlMapConfig.xml加载映射文件

在sqlMapConfig.xml中加载User.xml:

<!-- 加载 映射文件 -->
<mappers>
<mapper resource="sqlmap/User.xml"/>
</mappers>

 

3.5.4     程序编写

 在工程中添加junit的jar包

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;

public class MybatisFirst {

	// 根据id查询用户信息,得到一条记录结果
@Test
public void findUserByIdTest() throws IOException { // mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource); // 创建会话工厂,传入mybatis的配置文件信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 通过工厂得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession(); // 通过SqlSession操作数据库
// 第一个参数:映射文件中statement的id,等于=namespace+"."+statement的id
// 第二个参数:指定和映射文件中所匹配的parameterType类型的参数
// sqlSession.selectOne结果 是与映射文件中所匹配的resultType类型的对象
// selectOne查询出一条记录
User user = sqlSession.selectOne("test.findUserById", 1); System.out.println(user); // 释放资源
sqlSession.close(); }
}

  

3.6     根据用户名称模糊查询用户信息

3.6.1     映射文件

使用User.xml,添加根据用户名称模糊查询用户信息的sql语句。

	<!-- 根据用户名称模糊查询用户信息,可能返回多条
resultType:指定就是单条记录所映射的java对象 类型
${}:表示拼接sql串,将接收到参数的内容不加任何修饰拼接在sql中。
使用${}拼接sql,引起 sql注入
${value}:接收输入 参数的内容,如果传入类型是简单类型,${}中只能使用value
-->
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.mybatis.po.User">
SELECT * FROM USER WHERE username LIKE '%${value}%'
</select>

 

3.6.2     程序代码

 

	// 根据用户名称模糊查询用户列表
@Test
public void findUserByNameTest() throws IOException {
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource); // 创建会话工厂,传入mybatis的配置文件信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream); // 通过工厂得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// list中的user和映射文件中resultType所指定的类型一致
List<User> list = sqlSession.selectOne("test.findUserByName", "明");
System.out.println("+++++++++++"+list);
sqlSession.close(); }

3.7    添加用户

  

3.1.1     映射文件

	<!-- 添加用户
parameterType:指定输入 参数类型是pojo(包括 用户信息)
#{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值
-->
<insert id="insertUser" parameterType="cn.mybatis.po.User">
insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
</insert>

  

3.7.2     程序代码

	// 添加用户信息
@Test
public void insertUserTest() throws IOException {
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource); // 创建会话工厂,传入mybatis的配置文件信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream); // 通过工厂得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 插入用户对象
User user = new User();
user.setUsername("王小军");
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("河南郑州"); sqlSession.insert("test.insertUser", user); // 提交事务
sqlSession.commit(); // 获取用户信息主键
System.out.println(user.getId());
// 关闭会话
sqlSession.close(); }

 

3.7.3     自增主键返回

mysql自增主键,执行insert提交之前自动生成一个自增主键。

通过mysql函数获取到刚插入记录的自增主键:

LAST_INSERT_ID()是insert之后调用此函数。

修改insertUser定义:

<insert id="insertUser" parameterType="cn.mybatis.po.User">
<!--
将插入数据的主键返回,返回到user对象中

SELECT LAST_INSERT_ID():得到刚insert进去记录的主键值,只适用与自增主键

keyProperty:将查询到主键值设置到parameterType指定的对象的哪个属性
order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序
resultType:指定SELECT LAST_INSERT_ID()的结果类型
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})

</insert>

 

3.7.4     非自增主键返回(使用uuid())

使用mysql的uuid()函数生成主键,需要修改表中id字段类型为string,长度设置成35位。

执行思路:

先通过uuid()查询到主键,将主键输入 到sql语句中。

执行uuid()语句顺序相对于insert语句之前执行。

<insert id="insertUser" parameterType="cn.mybatis.po.User">
<!--
使用mysql的uuid()生成主键
执行过程:
首先通过uuid()得到主键,将主键设置到user对象的id属性中
其次在insert执行时,从user对象中取出id属性值
-->
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
SELECT uuid()
</selectKey>
insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address})
</insert>

补充:

通过oracle的序列生成主键:

<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">

SELECT 序列名.nextval()

</selectKey>

insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address})

 

3.8    删除用户

3.8.1     映射文件

	<!-- 删除 用户
根据id删除用户,需要输入 id值
-->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>

  

3.8.2     代码:

// 根据id删除 用户信息
@Test
public void deleteUserTest() throws IOException {
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource); // 创建会话工厂,传入mybatis的配置文件信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream); // 通过工厂得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession(); // 传入id删除 用户
sqlSession.delete("test.deleteUser", 39); // 提交事务
sqlSession.commit(); // 关闭会话
sqlSession.close(); }

  

3.9     更新用户

3.9.1     映射文件

	<!-- 根据id更新用户
分析:
需要传入用户的id
需要传入用户的更新信息
parameterType指定user对象,包括 id和更新信息,注意:id必须存在
#{id}:从输入 user对象中获取id属性值
-->
<update id="updateUser" parameterType="cn.mybatis.po.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
where id=#{id}
</update>

  

3.9.2    代码

// 更新用户信息
@Test
public void updateUserTest() throws IOException {
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource); // 创建会话工厂,传入mybatis的配置文件信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream); // 通过工厂得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 更新用户信息 User user = new User();
//必须设置id
user.setId(41);
user.setUsername("王大军");
user.setBirthday(new Date());
user.setSex("2");
user.setAddress("河南郑州"); sqlSession.update("test.updateUser", user); // 提交事务
sqlSession.commit(); // 关闭会话
sqlSession.close(); }

  

3.10     总结

3.10.1     parameterType

在映射文件中通过parameterType指定输入 参数的类型。

3.10.2    resultType

在映射文件中通过resultType指定输出结果的类型。

3.10.3     #{}和${}

#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap。

如果接收简单类型,#{}中可以写成value或其它名称。

#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

${}表示一个拼接符号,会引用sql注入,所以不建议使用${}。

${}接收输入参数,类型可以是简单类型,pojo、hashmap。

如果接收简单类型,${}中只能写成value。

${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

3.10.4     selectOne和selectList

selectOne表示查询出一条记录进行映射。如果使用selectOne可以实现使用selectList也可以实现(list中只有一个对象)。

selectList表示查询出一个列表(多条记录)进行映射。如果使用selectList查询多条记录,不能使用selectOne。

如果使用selectOne报错:

org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 4

3.11     mybatis和hibernate本质区别和应用场景

hibernate:是一个标准ORM框架(对象关系映射)。入门门槛较高的,不需要程序写sql,sql语句自动生成了。

对sql语句进行优化、修改比较困难的。

应用场景:

适用与需求变化不多的中小型项目,比如:后台管理系统,erp、orm、oa。。

mybatis:专注是sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全 的ORM框架,虽然程序员自己写sql,mybatis 也可以实现映射(输入映射、输出映射)。

应用场景:

适用与需求变化较多的项目,比如:互联网项目。

企业进行技术选型,以低成本 高回报作为技术选型的原则,根据项目组的技术力量进行选择。

mybais学习记录一——入门程序的更多相关文章

  1. SpringMVC学习记录一——入门介绍和入门程序

    1       springmvc框架 1.1      什么是springmvc springmvc是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合. spr ...

  2. 学习记录---C# Web程序获取客户端电脑信息

    问题描述:由于最近项目需要使用Mac地址与注册码进行加密处理,但是又因为Web程序的局限性不能获取客户端电脑系统信息,当然IE浏览器有一个activex控件他是可以通过Js在前端代码中直接获取的,局限 ...

  3. TCP协议学习记录 (三) Ping程序 RR选项 记录路由hop

    一开始想直接在上个程序改,自己构造IP包头,但后来发现不行,微软不让干了,所以后来选用libcap库来收发包 代码写的很乱.. #pragma pack(4) #define ECHO_REQUEST ...

  4. TCP协议学习记录 (二) Ping程序

    简单的实现了一个ping程序,没有做icmp差错报文的检查. 支持自定义字节数,支持发包个数 #pragma pack(4) #define ECHO_REQUEST 8 #define DATASI ...

  5. LESS 学习记录(简单入门)

    什么是 LESS LESS是一种动态样式语言,属于 CSS 预处理语言的一种.它使用类似 CSS 的语法,但是 赋予了动态语言的特性,比如变量.继承.运算.函数等,方便 CSS 的编写和维护. 使用 ...

  6. Vue学习记录第一篇——Vue入门基础

    前面的话 Vue中文文档写得很好,界面清爽,内容翔实.但文档毕竟不是教程,文档一上来出现了大量的新概念,对于新手而言,并不友好.个人还是比较喜欢类似于<JS高级程序设计>的风格,从浅入深, ...

  7. 《java从入门到精通》学习记录

    目录 <Java从入门到精通>学习记录 3 基础的基础部分: 3 一. 常量与变量 3 1. 掌握: 3 (1) .常量与变量的声明方式: 3 (2) .变量的命名规则: 3 (3) .变 ...

  8. Git学习记录 力做全网最强入门教程

    目录 Git学习记录 力做全网最强入门教程 什么是GitHub? 什么是Git? Git的配置 Git的安装(只介绍windos操作系统下) Git的配置 至此我们的入门教程到此结束,更新中级教程要等 ...

  9. .NetCore微服务Surging新手傻瓜式 入门教程 学习日志---先让程序跑起来(一)

    原文:.NetCore微服务Surging新手傻瓜式 入门教程 学习日志---先让程序跑起来(一) 写下此文章只为了记录Surging微服务学习过程,并且分享给广大想学习surging的基友,方便广大 ...

随机推荐

  1. 使用SVN进行源码管理

    阅读目录: 1.SVN服务端配置 1.1 创建版本库 1.2 创建用户 1.3 设置用户权限 2.SVN客户端使用 2.1 向SVN服务器中导入源码 2.1.1 直接通过TortoiseSVN向SVN ...

  2. 如何发布一个包到npm && 如何使用自己发布的npm包 && 如何更新发布到npm的package && 如何更新当前项目的包?

    如何发布一个包到npm First 在https://www.npmjs.com注册一个账号. Second 编辑好项目,文件大致如下: 其中,gitignore可以如下: .DS_Store nod ...

  3. 让ubuntu的ssh保持长时间连接

    Ubuntu下的ssh连接老是自己会断,一段时间不理它就会失去响应 如何让ssh连接服务器或者ssh tunnel保持连接呢? 其实也很方便,只要在/etc/ssh/ssh_config文件里加两个参 ...

  4. POJ 2528——Mayor's posters——————【线段树区间替换、找存在的不同区间】

    Mayor's posters Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Sub ...

  5. OpenLayers 3 实现轨迹回放

    function PathBack() { var PVLayer = new ol.layer.Vector({ source: new ol.source.Vector({}) }); var p ...

  6. Hibernate中的一对一注解配置

    Card类 package cn.OneToOne2017109.entity; import javax.persistence.*; /** * Created by YSS on 2017/10 ...

  7. 从零开始的全栈工程师——html篇1.3

    文本.字体css样式与前期英语单词汇总 一.文本样式(text) 1.颜色:color:red; 2.文本对齐方式:text-align:left/center/right/justify; left ...

  8. Grunt压缩图片和JS

    今天我们来说一下用Grunt来压缩图片和JS吧! 首先要安装插件: 这是压缩图片的; npm install --save-dev gulp-imagemin 这是压缩JS的: npm install ...

  9. Linux服务器性能评估与优化(二)

    网络内容总结(感谢原创) 1.Linux内核参数优化 内核参数是用户和系统内核之间交互的一个接口,通过这个接口,用户可以在系统运行的同时动态更新内核配置,而这些内核参数是通过Linux Proc文件系 ...

  10. linux漏洞分析入门笔记-bypass_PIE

    ubuntu 16.04 IDA 7.0 docker 0x00:漏洞分析 1.ASLR的是操作系统的功能选项,作用于executable(ELF)装入内存运行时,因而只能随机化stack.heap. ...