框架学习笔记之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框架相对 ...
随机推荐
- 如何进入MySQL
C:\Users\电脑ID>D:D:\> cd D:\wamp\wamp64\bin\mysql\mysql5.7.19\binD:\wamp\wamp64\bin\mysql\mysql ...
- Ubuntu上安装和使用RabbitMQ
1. 安装RabbitMQ服务软件包 输入以下命令进行安装 #apt install rabbitmq-server 2.安装完成后在rabbitMQ中添加用户 命令:#rabbitmqctl add ...
- linux拓展下:批量改扩展名的方法
[root@oldboy oldboy]# ll total 0 -rw-r--r-- 1 root root 0 Nov 13 19:38 stu_102999_1_.jpg -rw-r--r-- ...
- java 二叉树排序
1 class BinaryTree{ 2 class Node{ 3 private Comparable data; 4 private Node left; 5 private Node rig ...
- HttpServletRequest对象方法的用法
1. 获得客户机信息 getRequestURL方法返回客户端发出请求时的完整URL. getRequestURI方法返回请求行中的资源名部分. getQueryString 方法返 ...
- java中equals相同,hashcode一定相同ma
一.jdk中equals和hashcode的定义和源码进行分析 1.java.lang.Object中对equals()方法的定义 java.lang.Object中对hashCode()方法的定义 ...
- [日常] PKUWC 2018爆零记
吃枣药丸...先开个坑... day -1 上午周测...大翻车... 下午被查水表说明天必须啥啥啥...(当时我差点笑出声) 晚上领到笔记本一枚和一袋耗材(袜子) 然而班会开太晚回去没来得及收拾就晚 ...
- 记录python接口自动化测试--利用unittest生成测试报告(第四目)
前面介绍了是用unittest管理测试用例,这次看看如何生成html格式的测试报告 生成html格式的测试报告需要用到 HTMLTestRunner,在网上下载了一个HTMLTestRunner.py ...
- c语言字符类型作业
一.PTA实验作业 题目1:7-2 统计一行文本的单词个数 1. 本题PTA提交列表 2. 设计思路 1.定义整形变量i=0,count=0,flag. 2.定义数组str[999] 3.输入str[ ...
- 201621123050 《Java程序设计》第2周学习总结
1.本周学习总结 java的数据类型 基本数据类型:介绍了java特有的boolean 引用数据类型 String:不变性:需要频繁修改时使用StringBuilder 包装类:自动拆.装箱 数组 一 ...