框架学习笔记之Mybatis(一)
一、简介
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
对sql语句进行优化、修改比较困难的。
应用场景:
适用与需求变化不多的中小型项目,比如:后台管理系统,erp、orm、oa。。
mybatis:专注是sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全 的ORM框架,虽然程序员自己写sql,mybatis 也可以实现映射(输入映射、输出映射)。
应用场景:
适用与需求变化较多的项目,比如:互联网项目。

package cn.mycookies.mybatis.demo.po;
import java.util.Date;
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 date) {
this.birthday = date;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex
+ ", birthday=" + birthday + ", address=" + address + "]";
}
}
<?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>
<!-- 配置数据库运行环境 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc实务管理 实务和数据库连接池都是由mybatis -->
<transactionManager type="JDBC"></transactionManager>
<!-- 数据库 -->
<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="mapper/UserMapper.xml"/>
</mappers>
</configuration>
2.配置映射文件
<?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="cn.mycookies.mybatis.demo.mapper.UserMapper">
<!--根据id查询User-->
<select id="findUserById" parameterType="int"
resultType="cn.mycookies.mybatis.demo.po.User">
SELECT * FROM USER WHERE id=#{id}
</select>
</mapper>
3.编写mapper.java接口在全局配置文件中加载映射文件
public interface UserMapper {
//根据id查询
public User findUserById(int id) throws Exception;
}
4.编写测试类
public class UserMapperTest {
private SqlSessionFactory sqlSessionFactory= null;
@Before
public void setUp() throws Exception {
//把配置文件加载到流中
InputStream config = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建SqlSessionFactory对象
sqlSessionFactory=new SqlSessionFactoryBuilder().build(config);
}
@Test
public void testFindUserById() throws Exception {
//通过factory获取SqlSession对象
SqlSession session = sqlSessionFactory.openSession();
//创建mapper对象
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.findUserById(1);
System.out.println(user);
}
}
注:在xxxmapper.xml配置文件中parameterType指定输入参数类型,resultType指定输出结果类型
四、mybatis的两种开发模式
1mybatis的原始dao开发(麻烦,程序员需要写dao接口和dao的实现类)
思路:写出dao接口和实现类,并向dao中注入SqlSessionFactory,在执行CRUD操作前需要通过SqlSessionFactory对象创建SqlSession
dao接口
public interface UserDao {
//根据id查询
public User findUserById(int id) throws Exception;
//添加用户
public int insertUser(User user ) throws Exception;
//删除用户信息
public void deleteUser(int id )throws Exception;
}
实现类
注:当执行删除添加修改时需要手动提交实务
public class UserDaoImpl implements UserDao {
//向dao注入SqlSessionFactory
//通过构造方法注入
private SqlSessionFactory factory;
public UserDaoImpl(SqlSessionFactory factory) {
super();
this.factory = factory;
}
@Override
public User findUserById(int id) throws Exception {
SqlSession session = factory.openSession();
//第一个参数为名称空间和id第二个参数为查询传入的参数
User user = session.selectOne("test.findUserById",id);
session.close();
return user;
}
@Override
public int insertUser(User user) throws Exception {
SqlSession session = factory.openSession();
session.insert("test.addUser", user);
session.commit();
session.close();
return user.getId();
}
@Override
public void deleteUser(int id) throws Exception {
SqlSession session = factory.openSession();
session.delete("test.deleteUser", id);
session.commit();
session.close();
}
}
测试代码
public class UserDaoImplTest {
private SqlSessionFactory sqlSessionFactory= null;
@Before
public void setUp() throws Exception {
InputStream config = Resources.getResourceAsStream("SqlMapConfig.xml");
sqlSessionFactory=new SqlSessionFactoryBuilder().build(config);
}
@Test
public void test() throws Exception {
//创建userdao对象
UserDao dao = new UserDaoImpl(sqlSessionFactory);
User user = dao.findUserById(1);
System.out.println(user);
}
}
总结
1、dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。
2、调用sqlsession方法时将statement的id硬编码了
3、调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。
<mapper namespace="cn.mycookies.mybatis.demo.mapper.UserMapper">
b.mapper.java接口类中的方法名和mapper.java中对应的statement的id一致
c.mapper.java接口 中的返回值和参数与mapper.xml中的resultType和parameterType一致
注:当遵守以上开发规范时mybatis会对具体类的实现自动生成
五、MyBatis的开发使用
mapper.xml配置文件
1.自增主键返回
场景:数据库表设置主键自增长,当插入一个新的对象时,执行insert之前自动生成一个自增主键,要求返回该主键。
可用此函数来获取: LAST_INSERT_ID()。想要完成此功能需要在mapper.xml
配置文件中对sql操作进行配置
<insert id="addUser" parameterType="cn.mycookies.mybatis.demo.po.User">
<!-- 插入之后返回主键(自动生成)只适用于自增主键
key+Property指的是将查询到的主键设置到parameType指定对象的那个属性
resultType:指定结果类型
-->
<selectKey keyProperty="id" resultType="java.lang.Integer" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
<!-- 使用mysql的uuid()生成主键
首先查询uuid得到主键 将主键设置到user对象中
<selectKey keyProperty="id" resultType="String" order="BEFORE">
SELECT uuid()
</selectKey> -->
INSERT INTO USER(id,username,birthday,sex,address) values(#{id},#{username},#{birthday},#{sex},#{address})
</insert>
2.模糊查询
mapper.xml配置文件中statement的配置
<select id="findUserByName" parameterType="String" resultType="cn.mycookies.mybatis.demo.po.User">
<!-- SELECT * FROM USER WHERE username like #{value}
$符号表示拼接字符串,将接受到的内容不加任何修饰的拼接到sql中
可能会引起sql注入
大括号内只能使用value
-->
SELECT * FROM USER WHERE username like '%${value}%'
</select>
3.#{}和${}的区别
#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,#{}中可以写成value或其它名称。
#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
${}表示一个拼接符号,会引用sql注入,所以不建议使用${}。
${}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,${}中只能写成value。
${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
4.selectOne 和selectList(指的是mapper.java接口中返回值类型的配置)
selectonse表示查询一条记录进行映射,如果selectOne映射成功,selectList也可以映射。
selectList表示查询多天记录进行映射。如果使用selectList查询多条记录,不能使用selectOne.
SqlMapConfig.xml-mybatis的全局配置文件
mybatis的全局配置文件SqlMapConfig.xml配置文件包括一下内容
properties:属性
setting:全局参数设置
typeAliases:类型别名
typeHandlers:类型处理器
objectFactory:对象工厂
environments:环境集合属性对象
environment:环境子属性对象
transactionManager:实务管理
dataSource:数据库源的配置
mappers:映射器
1.properties
场景:将数据库参数单独提取出来配置到db.properties的配置文件中,只需要使用properties将db.properties里面的属性值加载到SqlMapConfig.xml中即可!方便对参数的统一管理,其他的配置文件都可以引用此配置文件。
db.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis2 jdbc.username=root jdbc.password=password
SqlMapConfig.xml
<!-- 加载数据库配置文件 -->
<properties resource="db.properties">
</properties>
<!-- 配置数据库运行环境 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc实务管理 实务和数据库连接池都是由mybatis -->
<transactionManager type="JDBC"></transactionManager>
<!-- 数据库 -->
<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>
注:MyBatis将按照下面的顺序来加载属性
》在properties元素体内定义的属性》properties元素中通过resource或url引用的属性》parameterType传递的属性
在加载过程中会覆盖同名属性,建议不要在properties元素内添加任何属性值,直接爱那个属性值定义在properties文件中,为了防止命名重复,在properties文件中定义属性名要有一定地特殊性,如:jdbc.url (尽量不要直接定义为url)
2.settiong
mybatis框架运行时可以调整一些默认的运行参数,通过该属性配置后进而影响mybatis的运行行为。
如:开启二级缓存,开启延迟加载。


3.typeAliases
场景:在mapper.xml中的statement中需要配置parameterType和resultType(参数类型和结果类型),在配置中通常需要指定类型的全路径,优化这一现象,通过在mapper.xml定义别名即可。
a.对于基本数据类型以及他们的封装类mybatis已经进行了定义直接引用即可
|
别名 |
映射的类型 |
|
_byte |
byte |
|
_long |
long |
|
_short |
short |
|
_int |
int |
|
_integer |
int |
|
_double |
double |
|
_float |
float |
|
_boolean |
boolean |
|
string |
String |
|
byte |
Byte |
|
long |
Long |
|
short |
Short |
|
int |
Integer |
|
integer |
Integer |
|
double |
Double |
|
float |
Float |
|
boolean |
Boolean |
|
date |
Date |
|
decimal |
BigDecimal |
|
bigdecimal |
BigDecimal |
b.自定义别名
b.1单个别名定义
<typeAliases>
<!--type:表示类的路径,alias:类的别名-->
<typeAlias type="cn.mycookies.mybatis.demo.po.User" alias="user"/>
</typeAliases>
b.2批量定义别名(常用)
<typeAliases>
<!--name指定包名,该包下的所有类都被定义了别名,为类名,首字母大小写都可以--> <package name="cn.mycookies.mybatis.demo.po"/> </typeAliases>
别名的引用:在需要使用的地方直接通过定义的别名直接引用即可。
4.typeHandlers
该标签用来处理jdbc类型和java类型之间的转换,但是通常情况下mybatis默认进行的转换已经满足日常开发,不需要自定义
|
类型处理器 |
Java类型 |
JDBC类型 |
|
BooleanTypeHandler |
Boolean,boolean |
任何兼容的布尔值 |
|
ByteTypeHandler |
Byte,byte |
任何兼容的数字或字节类型 |
|
ShortTypeHandler |
Short,short |
任何兼容的数字或短整型 |
|
IntegerTypeHandler |
Integer,int |
任何兼容的数字和整型 |
|
LongTypeHandler |
Long,long |
任何兼容的数字或长整型 |
|
FloatTypeHandler |
Float,float |
任何兼容的数字或单精度浮点型 |
|
DoubleTypeHandler |
Double,double |
任何兼容的数字或双精度浮点型 |
|
BigDecimalTypeHandler |
BigDecimal |
任何兼容的数字或十进制小数类型 |
|
StringTypeHandler |
String |
CHAR和VARCHAR类型 |
|
ClobTypeHandler |
String |
CLOB和LONGVARCHAR类型 |
|
NStringTypeHandler |
String |
NVARCHAR和NCHAR类型 |
|
NClobTypeHandler |
String |
NCLOB类型 |
|
ByteArrayTypeHandler |
byte[] |
任何兼容的字节流类型 |
|
BlobTypeHandler |
byte[] |
BLOB和LONGVARBINARY类型 |
|
DateTypeHandler |
Date(java.util) |
TIMESTAMP类型 |
|
DateOnlyTypeHandler |
Date(java.util) |
DATE类型 |
|
TimeOnlyTypeHandler |
Date(java.util) |
TIME类型 |
|
SqlTimestampTypeHandler |
Timestamp(java.sql) |
TIMESTAMP类型 |
|
SqlDateTypeHandler |
Date(java.sql) |
DATE类型 |
|
SqlTimeTypeHandler |
Time(java.sql) |
TIME类型 |
|
ObjectTypeHandler |
任意 |
其他或未指定类型 |
|
EnumTypeHandler |
Enumeration类型 |
VARCHAR-任何兼容的字符串类型,作为代码存储(而不是索引)。 |
5.mapper
该标签用于加载mapper.xml配置文件,可以单个加载也可以个批量加载。
<!-- 加载映射文件 -->
<mappers>
<!-- <mapper resource="sqlmap/User.xml" /> -->
<!-- <mapper resource="mapper/UserMapper.xml"/> -->
<!--
通过mapper接口加载配置文件
遵守一些规范:需要将mapper.java接口类名称和mapper.xml文件保持一致
,且在一个目录中
前提:使用mapper代理的方式
<mapper class="cn.mycookies.mybatis.demo.mapper.UserMapper"/>
-->
<!-- 批量加载 推荐使用 name:指定mapper.xml配置文件所在的包名 -->
<package name="cn.mycookies.mybatis.demo.mapper"/>
</mappers>
框架学习笔记之Mybatis(一)的更多相关文章
- 框架学习笔记之Mybatis(二)
一.动态sql 通过mybatis提供的标签,实现sql语句的拼接. 1.where <select id="findUserList" parameterType=&quo ...
- Spring框架学习笔记(8)——spring boot+mybatis plus+mysql项目环境搭建
之前写的那篇Spring框架学习笔记(5)--Spring Boot创建与使用,发现有多小细节没有提及,,正好现在又学习了mybatis plus这款框架,打算重新整理一遍,并将细节说清楚 1.通过I ...
- SSM框架学习笔记_第1章_SpringIOC概述
第1章 SpringIOC概述 Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架. 1.1 控制反转IOC IOC(inversion of controller)是一种概念 ...
- Spring框架学习笔记(5)——Spring Boot创建与使用
Spring Boot可以更为方便地搭建一个Web系统,之后服务器上部署也较为方便 创建Spring boot项目 1. 使用IDEA创建项目 2. 修改groupid和artifact 3. 一路n ...
- phalcon(费尔康)框架学习笔记
phalcon(费尔康)框架学习笔记 http://www.qixing318.com/article/phalcon-framework-to-study-notes.html 目录结构 pha ...
- Yii框架学习笔记(二)将html前端模板整合到框架中
选择Yii 2.0版本框架的7个理由 http://blog.chedushi.com/archives/8988 刚接触Yii谈一下对Yii框架的看法和感受 http://bbs.csdn.net/ ...
- JavaSE中Collection集合框架学习笔记(2)——拒绝重复内容的Set和支持队列操作的Queue
前言:俗话说“金三银四铜五”,不知道我要在这段时间找工作会不会很艰难.不管了,工作三年之后就当给自己放个暑假. 面试当中Collection(集合)是基础重点.我在网上看了几篇讲Collection的 ...
- JavaSE中Collection集合框架学习笔记(3)——遍历对象的Iterator和收集对象后的排序
前言:暑期应该开始了,因为小区对面的小学这两天早上都没有像以往那样一到七八点钟就人声喧闹.车水马龙. 前两篇文章介绍了Collection框架的主要接口和常用类,例如List.Set.Queue,和A ...
- JavaSE中Map框架学习笔记
前言:最近几天都在生病,退烧之后身体虚弱.头疼.在床上躺了几天,什么事情都干不了.接下来这段时间,要好好加快进度才好. 前面用了三篇文章的篇幅学习了Collection框架的相关内容,而Map框架相对 ...
随机推荐
- es6学习笔记--新数据结构Set,Map以及WeakSet,WeakMap
在javascript中,存储数据的方式大部分就是以数组或者对象形式存储的,es6出现了4种新集合Set,Map,WeakSet,WeakMap来存储数据,简化了编程. 集合--Set 类似于数组,但 ...
- Mycat 分片规则详解--枚举分片
实现方式:切分规则根据文件(partition-hash-int.txt)配置的可能的枚举来进行分片,此种分片规则理解为枚举分区,会比较适合于取值固定的场合,比如说省份(固定值) 优点:适用于按照省份 ...
- WinSock 异步I/O模型-2
事件选择(WSAEventSelect): WSAEventSelect模型是Windows Sockets提供的另外一个有用的异步I/O模型.该模型允许一个或多个套接字上接收以事件为基础的网络事件通 ...
- JVM学习五:JVM之类加载器之编译常量和主动使用
在学习了前面几节的内容后,相信大家已经对JAVA 虚拟机 加载类的过程有了一个认识和了解,那么本节,我们就继续进一步巩固前面所学知识和特殊点. 一.类的初始化回顾 类在初始化的时候,静态变量的声明语句 ...
- 【Bootstrap】优秀小插件收集
Bootstrap中不乏很多优秀的小插件来让界面更加漂亮.比如之前做过笔记的bootstrap-fileinput,select2,datetimepicker等都是属于这一系列的.这些相对而言比较大 ...
- 【BootStrap】 概述 & CSS
BootStrap BootStrap由Twitter开发,基于HTML,CSS,JS,是一套前端框架.它的特点是对浏览器良好的支持(目前市面上所有流行浏览器都可以),兼容移动设备,以及响应式设计(响 ...
- 【Python】 用户图形界面GUI wxpython I 基本用法和组件
wxpython - 基本用法和组件 wxpython是python对跨平台GUI库wxWidgets的封装.wxWidgets是由C++写成的. wxpython被包装进了wx模块中,用它设计GUI ...
- linux --> 为什么寄存器比内存快?
为什么寄存器比内存快 计算机的存储层次(memory hierarchy)之中,寄存器(register)最快,内存其次,最慢的是硬盘. 原因一:距离不同 距离不是主要因素,但是最好懂,所以放在最前面 ...
- java排序算法(二):直接选择排序
java排序算法(二) 直接选择排序 直接选择排序排序的基本操作就是每一趟从待排序的数据元素中选出最小的(或最大的)一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完,它需要经过n- ...
- phpcms v9 搜索结果列表页时间显示1970问题解决方案
对于喜欢用phpcms v9 的小伙伴来说,在调用时间时,总会出现时间1970这样的问题,对于这个问题,网上的说法很多,内容页时间显示通常不会问题,搜索结果页就不行了,通过总结,发现使用{format ...