转载:https://blog.csdn.net/wei_li_2015/article/details/80832806
为什么需要mybatis
传统的jdbc编码中存在着许多不足之处,
- 频繁创建数据库连接对象、释放、容易造成系统资源浪费,影响系统性能。企业项目中可以使用连接池解决这个问题,但是使用Jdbc需要自己实现连接池。mybatis框架已经提供连接池。
- sql语句定义、参数设置、结果集处理存在硬编码。企业项目中sql语句变化的可能性较大,一旦发生变化,需要修改java代码,系统需要重新编译,重新发布。不好维护。
- 结果集处理存在重复代码,处理麻烦。如果可以映射成为java对象会比较方便。
mybatis的简介
mybatis是一个持久层的框架,是对JDBC操作数据库的封装,使开发者只需要关注业务本身,不需要花费精力去处理加载驱动、创建数据库连接对象、创建statement语句对象、参数设置、结果集处理等一系列繁杂的过程代码。mybatis通过xml或注解进行配置,将java对象与sql语句中的参数自动映射生成最终执行的sql语句,并将sql语句执行结果自动映射成java对象,返回给业务层(service)应用。
快速案例
- pom.xml文件中导入相关的jar包
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.7</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.17.1-GA</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.6</version>
<scope>test</scope>
</dependency>
- 配置mybatis的运行环境mybatis.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>
<!-- 加载属性文件 -->
<properties resource="com/it/config/db.properties">
<!-- 这里可以配置属性名和属性值 -->
<!-- <property name="" value=""/> -->
</properties>
<!-- 和spring整合后 environments配置将废除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理,事务控制由mybatis-->
<transactionManager type="JDBC" />
<!-- 数据库连接池,由mybatis管理-->
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}" />
<property name="url" value="${mysql.url}" />
<property name="username" value="${mysql.user}" />
<property name="password" value="${mysql.pwd}" />
</dataSource>
</environment>
</environments>
<!--加载映射文件-->
<mappers>
<!-- 当的映射文件的加载 -->
<mapper resource="com/it/bean/Student.xml"/></mappers>
</configuration>
- 配置db.properties文件
mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/test
mysql.user=root
mysql.pwd=123456
- 创建实体bean
public class User implements Serializable{
private int userid;
private String username;
private String usersex;
private Date userbirth;
private String useraddr;
- 实体bean对应的映射文件Student.xml
namespace:mapper的名称,本质是虚拟路径
id:statement的唯一标识符
parameterType:输入参数类型,不是名称和值。
resultType:输出参数类型,输出参数类型只能写单条数据的类型
例如加入返回值是List<Student>, resultType=”Student”
resultType解决的就是类属性和表字段的一一映射,默认类属性和表字段刚好一样。
#{id}:占位符,当传入参数类型是简单类型的时候,括号中的名称可以随意起名字。
<?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="mybatis">
<!-- 新增用户 -->
<insert id="addUser" parameterType="com.liwei.mybatis.domain.User">
insert into user (id,username,birthday,sex,address)
values (#{id},#{username},#{birthday},#{sex},#{address})
</insert>
<!-- 根据用户id删除用户 -->
<delete id="deleteUser" parameterType="int">
delete from user where id = #{id}
</delete>
<!-- 根据用户id修改用户 -->
<update id="updateUserById" parameterType="com.liwei.mybatis.domain.User">
update user set username=#{username},sex=#{sex} where id=#{id}
</update>
<!-- 根据id查询 -->
<select id="queryUserById" parameterType="int" resultType="com.liwei.mybatis.domain.User">
select id,username,birthday,sex,address from user where id = #{id}
</select>
<!-- 方式一:根据用户名称模糊查询用户 -->
<select id="queryUserByName1" parameterType="string" resultType="com.liwei.mybatis.domain.User">
select id,username,birthday,sex,address from `user` where username like #{username}
</select>
<!-- 方式二:根据用户名称模糊查询用户 -->
<select id="queryUserByName2" parameterType="string" resultType="com.liwei.mybatis.domain.User">
select id,username,birthday,sex,address from `user` where username like '%${value}%'
</select>
</mapper>
- 测试
package com.liwei.mybatis.test;
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;
import com.liwei.mybatis.domain.User;
public class MyBatisTest {
/**
* @Title: getSqlSessionFactory
* @Description: 将增、删、改、查公共使用的部分提出来
* @param: @return
* @param: @throws
* IOException
* @return: SqlSession
* @throws @author
* Li_Wei
*/
public SqlSessionFactory getSqlSessionFactory() throws IOException {
// 1.加载核心配置文件
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 2.读取配置文件的内容
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(inputStream);
return sqlSessionFactory;
}
/**
* @Title: addUser
* @Description: 新增用户
* @param:
* @return: void
* @throws IOException
* @throws @author
* Li_Wei
*/
@Test
public void addUser() throws IOException {
// 3.使用sqlSessionFactory对象,创建SqlSession对象,开启自动提交事务
SqlSession sqlSession = this.getSqlSessionFactory().openSession(true);
// 调用方法执行
User user = new User();
user.setId(4);
user.setUsername("林诗音");
user.setBirthday(new Date());
user.setSex("女");
user.setAddress("来自大明朝");
sqlSession.insert("mybatis.addUser", user);
// 事务提交
// sqlSession.commit();
// 释放资源
sqlSession.close();
}
/**
* @Title: deleteUser
* @Description: 根据用户id删除用户
* @param:
* @return: void
* @throws IOException
* @throws @author
* Li_Wei
*/
@Test
public void deleteUser() throws IOException {
// 创建SqlSession对象
SqlSession sqlSession = this.getSqlSessionFactory().openSession(true);
// 调用方法执行
sqlSession.delete("mybatis.deleteUser", 3);
// 释放资源
sqlSession.close();
}
/**
* @Title: updateUser
* @Description: 根据用户id修改用户
* @param:
* @return: void
* @throws IOException
* @throws @author
* Li_Wei
*/
@Test
public void updateUserById() throws IOException {
// 创建SqlSession对象
SqlSession sqlSession = this.getSqlSessionFactory().openSession(true);
// 调用方法执行
// 创建用户对象
User user = new User();
user.setId(1);
user.setUsername("林诗音和小李飞刀");
user.setSex("1");
sqlSession.update("mybatis.updateUserById", user);
// 释放资源
sqlSession.close();
}
/**
* @Title: queryUserById
* @Description: 根据id查询用户(查询)
* @param:
* @return: void
* @throws IOException
* @throws @author
* Li_Wei
*/
@Test
public void queryUserById() throws IOException {
// 3.使用sqlSessionFactory对象,创建SqlSession对象
SqlSession sqlSession = this.getSqlSessionFactory().openSession();
// 4.使用sqlSession对象,调用方法执行
Object user = sqlSession.selectOne("mybatis.queryUserById", 24);
System.out.println(user);
// 5.释放资源
sqlSession.close();
}
/**
* @Title: queryUserNameLike
* @Description: 方式一:根据用户名称模糊查询用户
* @param:
* @return: void
* @throws IOException
* @throws @author
* Li_Wei
*/
@Test
public void queryUserByName1() throws IOException {
// 3.使用sqlSessionFactory对象,创建SqlSession对象
SqlSession sqlSession = this.getSqlSessionFactory().openSession();
// 4.使用sqlSession对象,调用方法执行
List<Object> userList = sqlSession.selectList("mybatis.queryUserByName1", "%小明%");
for (Object object : userList) {
System.out.println(object);
}
// 5.释放资源
sqlSession.close();
}
/**
* @Title: queryUserNameLike
* @Description: 根据用户名称模糊查询用户
* @param:
* @return: void
* @throws IOException
* @throws @author
* Li_Wei
*/
@Test
public void queryUserByName2() throws IOException {
// 3.使用sqlSessionFactory对象,创建SqlSession对象
SqlSession sqlSession = this.getSqlSessionFactory().openSession();
// 4.使用sqlSession对象,调用方法执行
List<Object> userList = sqlSession.selectList("mybatis.queryUserByName2", "小明");
for (Object object : userList) {
System.out.println(object);
}
// 5.释放资源
sqlSession.close();
}
}
占位符#{}与字符串拼接符${}区别
占位符#{}:
表示一个占位符号,通过#{}可以实现 preparedStatement 向占 位符中设置值, 自动进行 java
类型和 jdbc 类型转换。#{}可以有效防止 sql 注入。 #{}可以接 收简单类型值或 pojo 属性值。 如果
parameterType 传输单个简单类型值,#{} 括号中可以是 value 或其它名称。
拼接符
:
表
示
拼
接
s
q
l
串
,
通
过
可
以
将
p
a
r
a
m
e
t
e
r
T
y
p
e
传
入
的
内
容
拼
接
在
s
q
l
中
且
不
进
行
j
d
b
c
类
型
转
换
,
可
以
接
收
简
单
类
型
值
或
p
o
j
o
属
性
值
,
如
果
p
a
r
a
m
e
t
e
r
T
y
p
e
传
输
单
个
简
单
类
型
值
,
{}: 表示拼接 sql 串,通过可以将parameterType传入的内容拼接在sql中且不进行jdbc类型转换,{}可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,
:表示拼接sql串,通过可以将parameterType传入的内容拼接在sql中且不进行jdbc类型转换,可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,{}括号中只能是 value。
mybatis原理图
别名配置与映射文件加载方式
ResultMap
详见:https://blog.csdn.net/u012843873/article/details/80198185