MyBatis 学习笔记
一、MyBatis 概述
1. 什么是MyBatis
mybatis 是支持普通sql 查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC 代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的XML 或注解用于配置和原始映射,将接口和Java 的POJOS(Plan Old Java Objects,普通的java对象)映射成数据库中的记录。
每个MyBatis 应用程序主要都是使用SqlSessionFactory 实例的,一个SqlSessionFactory 实例可以通过SqlSessionFactory 获得。SqlSessionFactory 可以从一xml 配置文件或者一个预定义的配置类的实例获得。
用xml 文件构建SqlSessionFactory 实例是非常简单的事情。推荐在这个配置中使用类路径资源(classpath resource),但你可以使用任何Reader实例,包括用文件路径或file:// 开头的url 创建的实例。MyBatis 有一个使用类—Resources,它有很多方法,可以方便地从类路径及其他位置加载资源。
2. orm 工具的基本思想
ORM 是对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。
无论是用过的hibermate,mybatis,你都可以发现它们的共同点:
- 从配置文件(通常是xml配置文件中)得到sessionFactory
- 由sessionfactory 产生session
- 在session 中完成对数据的增删改查和事务提交等。
- 用完之后关闭session
- 在java 对象和数据库之间有做mapping 的配置文件,也通常是xml 文件
3. MyBatis 和JDBC 的比较
4. MyBaits 和Hibernate 主要的区别
- Mybatis 映射的是查询的结果集
select id as uId, name as uname from user
- Hibernate 映射的是表结构(即表中的字段名)
二、MyBatis 入门配置
1. 下载相关的jar 包(我用的是mybaits-3.3.0)
Mybatis官方下载地址:
-
核心jar包
-
辅助包
2. 引入数据库驱动包
3. 创建项目并导包
4. 创建数据库表
5. 创建mybatis.cfg.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>
<!-- 配置数据库的连接
default:默认使用哪一个数据库连接
-->
<environments default="development">
<environment id="development">
<!-- 事务管理 使用JDBC的事务 -->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
6. 创建User实体类
package com.lasing.domain;
import java.util.Date;
public class User {
private Integer id;
private String name;
private String address;
private Date birthday;
public User() {
}
public User(String name, String address, Date birthday) {
this.name = name;
this.address = address;
this.birthday = birthday;
}
public User(Integer id, String name, String address, Date birthday) {
this.id = id;
this.name = name;
this.address = address;
this.birthday = birthday;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", address=" + address + ", birthday=" + birthday + "]";
}
}
7. 创建UserMapper(数据持久层:三层mvc 中叫dao 层,在MyBatis 中成为Mapper)
- 不需要创建实现类,MyBatis会通过动态代理实现接口(也可以自己实现)
package com.lasing.mapper;
import java.util.List;
import com.lasing.domain.User;
public interface UserMapper {
public void add(User user);
public void delete(Integer id);
public void update(User user);
public void queryBuId(Integer id);
public List<User> queryAll();
}
8. 创建UserMapping.xml(mapper映射配置文件)
<?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="com.lasing.mapper.UserMapper">
<!-- parameterType:参数类型
parameterType:定义参数的map类型方法里面的传参数必须是map 要在mapper里面创建一个id=mysur的节点
说明:parameterType 和parameterType只能存在一个
<parameterMap type="com.lasing.domain.User" id="myuser">
<parameter property="name" javaType="java,lang.String"/>
<parameter property="address" javaType="java.lang.String"/>
</parameterMap>
<insert id="add" parameterMap="myuser">
insert into user(name, address, birthday) values(#{name}, #{address})
</insert>
userGeneratedKeys="true" 是否使用默认增长 默认为true
-->
<!-- 插入 -->
<insert id="add" parameterType="com.lasing.domain.User">
insert into user(name, address, birthday) values(#{name}, #{address}, #{birthday})
</insert>
<!-- 删除 -->
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id=#{value}
</delete>
<!-- 修改 -->
<update id="update" parameterType="com.lasing.domain.User">
update user set name=#{name},address=#{address},birthday=#{birthday} where id=#{id}
</update>
<!-- 查询一个 -->
<select id="queryById" parameterType="java.lang.Integer" resultType="com.lasing.domain.User">
select id,name,address,birthday from user where id=#{value}
</select>
<!-- 查询全部 -->
<select id="queryAll" resultType="com.lasing.domain.User">
select * from user
</select>
</mapper>
9使用log4j查看日志记录
- 配置log4j.properties
dirver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/springdemo
username=root
password=123456
- 在mybatis.cfg.xml 添加如下信息
10. 测试
//使用queryAll方法测试
SqlSession session = MybatisUtil.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list = mapper.queryAll();
for (User user : list) {
System.out.println(user.toString());
}
MybatisUtil.closeSession(session);
三、配置文件详解
1.核心配置文件详解
- 这里我拿上文中的mybatis.cfg.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>
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<!-- The content of element type "configuration" must match " (properties?,settings?,typeAliases?,typeHadlers?,
objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)". -->
<!-- 配置数据库的连接
default:默认使用哪一个数据库连接
-->
<environments default="mysql">
<!-- 配置mysql -->
<environment id="mysql">
<!-- 事务管理 使用JDBC的事务
JDBC【重点】 — 这个配置直接使用JDBC 的提交和回滚功能。它依赖从数据源获得连接来管理事务的生命周期。 从connection里面得到事务并管理事务;
MANAGED — 这个配置基本上什么都不做。它从不提交或者回滚一个连接的事务。而是让容器(例如:Spring,或者J2EE 应用服务器)来管理事务的生命周期;
-->
<transactionManager type="JDBC"></transactionManager>
<!-- 数据源配置
type:连接属性
UNPOOLED — 这个类型的数据源实现只是在每次需要的时候简单地打开和关闭连接;
POOLED — 这个数据源实现缓存JDBC 连接对象,用于避免每次创建新的数据库连接时都初始化和进行认证,加快程序响应。并发 WEB 应用通常通过这种做法来获得快速响应;
JNDI — 这个数据源的配置是为了准备与像Spring 或应用服务器能够在外部或者内部配置数据源的容器一起使用,然后再JNDI 上下文中引用它;
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/springdemo"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 配置映射 -->
<mappers>
<!-- 属性:
resource:使用配置文件
class:使用注解
-->
<mapper resource="com/lasing/mapping/Usermapping.xml"/>
</mappers>
</configuration>
2.mapping.xml 相关节点和属性说明
-
Mapper:定义了对应的数据库操作语句,完成对数据库的不同操作进行隔离(区分)
|-- namespace属性=“自定义” -
DML操作标签:insert、update、dalete定义了数据库的具体dml操作
|-- id 属性=“自定义”,用来namespace.id 获得对应的Statement对象(sql)
|-- parameterType=“Mapper 接口中方法形参的完全限定名” -
DQL操作标签:selete定义具体的DQL操作
|-- resultType属性=“Mapper 接口中方法的返回值的完全限定名,集合指定集合中元素的类型”
①insert节点:
②update节点:
③delete节点:
④select节点:
⑤配置字段别名
四、MyBatis 处理SQL语句的方法
1.mybatis的占位符处理
- 占位符一:#{ xxx }
|-- PreparedStatement 预编译sql 语句 有?占位符
|-- xxx表达式的写法
|-- 参数类型为javabean 类,xxx 表达式必须和javabean 中属性对应的get方法名字一样
|-- 参数类型为简单类型,xxx 表达式可以随表写,保持和参数的名字一致 - 占位符二:$ { xxx }
|-- Statement 拼接sql 语句 没有?占位符会有sql 注入的漏洞
|-- xxx表达式的写法
|-- 参数类型为javabean类,xxx 表达式必须和javabean 中属性对应的get 方法名字一样
|-- 参数类型为简单类型,xxx 表达式执行能写${ value }
2.模糊查询
①方法一:
<!-- UserMapping.xml -->
<select id="queryLike1" resultType="com.lasing.domain.User">
select * from user where name like #{name}
</select>
//测试类
@Test
public void test01() {
SqlSession session = MybatisUtil.openSession();
UserMapper Mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setName("%las%");//模糊查询的关键字自己拼接
List<User> list = Mapper.queryLike1(user);
for (User user2 : list) {
System.out.println(user2.toString());
}
MybatisUtil.closeSession(session);
}
②方法二:【推荐】使用%%拼接
<!-- UserMapping.xml -->
<select id="queryLike2" resultType="com.lasing.domain.User">
select * from user where name like "%"#{name}"%"
</select>
//测试类
@Test
public void test02() {
SqlSession session = MybatisUtil.openSession();
UserMapper Mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setName("las");
List<User> list = Mapper.queryLike2(user);
for (User user2 : list) {
System.out.println(user2.toString());
}
MybatisUtil.closeSession(session);
}
③方法三:使用$拼接
<!-- UserMapping.xml -->
<select id="queryLike3" resultType="com.lasing.domain.User">
select * from user where name like "%${name}%"
</select>
//测试类
@Test
public void test02() {
SqlSession session = MybatisUtil.openSession();
UserMapper Mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setName("las");
List<User> list = Mapper.queryLike3(user);
for (User user2 : list) {
System.out.println(user2.toString());
}
MybatisUtil.closeSession(session);
}
④方法四:使用数据库函数
<!-- UserMapping.xml -->
<select id="queryLike4" resultType="com.lasing.domain.User">
select * from user where name like CONCAT("%",#{name},"%")
</select>
//测试类
@Test
public void test02() {
SqlSession session = MybatisUtil.openSession();
UserMapper Mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setName("las");
List<User> list = Mapper.queryLike4(user);
for (User user2 : list) {
System.out.println(user2.toString());
}
MybatisUtil.closeSession(session);
}
⑤方法五:更改别名 bind
<!-- UserMapping.xml -->
<select id="queryLike5" resultType="com.lasing.domain.User">
<bind name="keywords" value="'%'+name+'%'" />
select * from user where name like keywords
</select>
//测试类
@Test
public void test02() {
SqlSession session = MybatisUtil.openSession();
UserMapper Mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setName("las");
List<User> list = Mapper.queryLike5(user);
for (User user2 : list) {
System.out.println(user2.toString());
}
MybatisUtil.closeSession(session);
}