Mybatis笔记 一
2018-11-05 本文已影响0人
卿云云云云
Mybatis笔记 一
为什么学Mybatis
- 目前最主流的持久层框架为hibernate与mybatis,而且国内目前情况使用Mybatis的公司比hibernate要多。
- Hibernate学习门槛不低,要精通门槛更高。门槛高在怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate缓存与数据加载策略方面需要你的经验和能力都很强才行。国内目前的情况精通hibernate技术大牛非常少。
- sql优化方面,Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。当然了,Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。说得更深入一些,如果有个查询要关联多张表,比如5张表,10张表时,而且,我们要取的字段只是其中几张表的部分字段。这时用hibernate时就会显得非常力不从心。就算用hibernate的sqlquery,后续的维护工作也会让人发狂。
JDBC编程回顾与存在的问题分析
-
开发步骤:
- 导入数据脚本,在课前资料中有
- 创建工程,导入mysql jar包
- 编码
-
Jdbc访问数据库的过程:
- 加载数据库驱动
- 创建数据库连接
- 创建statement
- 设置sql语句
- 设置查询参数
- 执行查询,得到ResultSet
- 解析结果集ResultSet
- 释放资源
-
Jdbc存在的问题:
- 频繁创建和打开、关闭数据连接,太消耗资源
- Sql语句存在硬编码,不利于维护
- Sql参数设置硬编码,不利于维护
- 结果集获取与遍历复杂,存在硬编码,不利于维护,期望能够查询后返回一个java对象
Mybatis介绍
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
Mybatis是面向sql的持久层框架,他封装了jdbc访问数据库的过程,我们开发,只需专注于sql语句本身的拼装,其它复杂的过程全部可以交给mybatis去完成。
Mybaits入门
需求列表
* 根据用户ID查询用户信息
* 根据用户名查找用户列表
* 添加用户
* 修改用户
* 删除用户
工程搭建
- 导入依赖jar包
- 配置SqlMapConfig.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>
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<!-- 加载配置文件 -->
<mappers>
<mapper resource="mybatis/user.xml" />
</mapper>
</configuration>
```
3. 配置log4j.properties
``` 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
```
4. 在课前资料复制pojo到工程目录下
``` java
public class Order {
// 订单id
private int id;
// 用户id
private Integer userId;
// 订单号
private String number;
// 订单创建时间
private Date createtime;
// 备注
private String note;
get/set。。。
}
- 配置sql查询的映射文件,可参考课前资料
<?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="test">
</mapper>
- 加载映射文件
<!-- 加载配置文件 -->
<mappers>
<mapper resource="mybatis/user.xml" />
</mapper>
完成需求
>需求完成步骤
1. 编写sql语句
2. 配置user映射文件
3. 编写测试程序
根据用户ID查询用户信息
- 映射文件与sql
<!-- id:statementId
resultType:查询结果集的数据类型
parameterType:查询的入参
-->
<select id="getUserById" parameterType="int" resultType="com.itheima.mybatis.pojo.User" >
SELECT * FROM USER WHERE id = #{id1}
</select>
- MyBatis访问数据库代码
@Test
public void testGetUserByid() throws IOException {
// 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sfb = new SqlSessionFactoryBuilder();
// 查找配置文件创建输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 加载配置文件,创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = sfb.build(inputStream);
// 创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 执行查询,参数一:要查询的statementId ,参数二:sql语句入参
User user = sqlSession.selectOne("user.getUserById", 1);
// 输出查询结果
System.out.println(user);
// 释放资源
sqlSession.close();
}
<font color=red >3. 抽取SqlSessionFactoryUtils工具类,共享SqlSessionFactory创建过程</font>
/**
* SqlSessionFactory工具类
*
* @author Steven
*
*/
public class SqlSessionFactoryUtils {
/**
* 单例SqlSessionFactory
*/
private static SqlSessionFactory sqlSessionFactory;
static {
// 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sfb = new SqlSessionFactoryBuilder();
try {
// 查找配置文件创建输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 加载配置文件,创建SqlSessionFactory对象
sqlSessionFactory = sfb.build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取单例SqlSessionFactory
* @return
*/
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}
根据用户名查找用户列表
- 映射文件与sql
<!-- resultType:如果要返回数据集合,只需设定为每一个元素的数据类型 -->
<select id="getUserByName" parameterType="string" resultType="com.itheima.mybatis.pojo.User">
<!-- SELECT * FROM USER WHERE username LIKE #{name} -->
SELECT * FROM USER WHERE username LIKE '%${value}%'
</select>
- MyBatis访问数据库代码
@Test
public void getUserByName() {
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
//List<User> users = sqlSession.selectList("user.getUserByName", "%张%");
List<User> users = sqlSession.selectList("user.getUserByName", "张");
for (User user : users) {
System.out.println(user);
}
// 释放资源
sqlSession.close();
}
添加用户
- 映射文件与sql
<insert id="insertUser" parameterType="com.itheima.mybatis.pojo.User">
INSERT INTO USER
(`username`,
`birthday`,
`sex`,
`address`)
VALUES (#{username},
#{birthday},
#{sex},
#{address});
</insert>
- MyBatis访问数据库代码
@Test
public void testInsertUser() throws IOException {
// 创建SqlSession对象
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
User user = new User();
user.setUsername("张飞");
user.setAddress("深圳市黑马");
user.setBirthday(new Date());
user.setSex("1");
// 执行插入
sqlSession.insert("user.insertUser", user);
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
}
- Mysql自增返回
<!-- useGeneratedKeys:标识插入使用自增id
keyProperty:与useGeneratedKeys配套使用,用于绑定主键接收的pojo属性
-->
<insert id="insertUserKey" parameterType="com.itheima.mybatis.pojo.User" useGeneratedKeys="true" keyProperty="id">
<!-- selectKey:用于配置主键返回
keyProperty:要绑定的pojo属性
resultType:属性数据类型
order:指定什么时候执行,AFTER之后
-->
<!-- <selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey> -->
INSERT INTO USER
(`username`,
`birthday`,
`sex`,
`address`,
`uuid2`)
VALUES (#{username},
#{birthday},
#{sex},
#{address},
#{uuid2});
</insert>
```
4. Mysql的uuid返回主键
> 注:在使用uuid之前数据库user表要先加上uuid2字段、user的pojo也要加上相应属性
``` xml
<!-- useGeneratedKeys:标识插入使用自增id
keyProperty:与useGeneratedKeys配套使用,用于绑定主键接收的pojo属性
-->
<insert id="insertUserUUID" parameterType="com.itheima.mybatis.pojo.User">
<!-- selectKey:用于配置主键返回
keyProperty:要绑定的pojo属性
resultType:属性数据类型
order:指定什么时候执行,BEFORE之前
-->
<selectKey keyProperty="uuid2" resultType="string" order="BEFORE">
SELECT UUID()
</selectKey>
INSERT INTO USER
(`username`,
`birthday`,
`sex`,
`address`,
`uuid2`)
VALUES (#{username},
#{birthday},
#{sex},
#{address},
#{uuid2});
</insert>
```
##### 修改用户
``` xml
<update id="updateUser" parameterType="com.itheima.mybatis.pojo.User">
UPDATE USER SET username = #{username} WHERE id = #{id}
</update>
删除用户
<delete id="deleteUser" parameterType="int">
DELETE FROM `user` WHERE `id` = #{id1}
</delete>
小结与Mybatis架构图
-
<font color=red>映射文件Mapper标记中#与$的区别 </font>
-
{}:点位符,相当于jdbc的?
- ${}:字符串拼接指令,如果入参为普通数据类型,括号内部职能用value
-
-
架构图
Mybatis01.png