1.1 MyBatis概述
1.1.1 什么是MyBatis
MyBatis框架也被称为ORM框架。所谓ORM,就是一种为了解决面向对象与关系型数据库中数据类型不匹配的技术,通过描述java对象与数据库表之间的映射关系自动将java应用程序中的对象持久化到关系型数据库的表中
使用ORM框架后,应用程序不再直接访问底层数据库,而是以面向对象的方式来操作持久化对象,而ORM框架则会通过映射关系将这些面向对象的操作转换成底层的SQL操作。> 常见的ORM框架有Hibernate和MyBatis
(1)Hibernate:一个全表映射的框架。开发者只需要定义好持久化对象到数据库表的映射关系,就可以通过Hibernate提供的方法完成持久层操作。开发者不需要熟练掌握SQL语句编写,Hibernate会根据指定的存储逻辑自动生成对应的SQL,并调用JDBC接口来执行,所以其开发效率会高于MyBatis。然后Hibernate自身存在一些缺点,例如在多表关联时,对SQL查询的支持较差;更新数据时,需要发送所有的字段;不支持存储过程;不能通过优化SQL来优化性能。这些问题导致其只适合在场景不太复杂且对性能要求不高的项目中使用。
(2)MyBatis:一个半自动映射框架。半自动是相对于Hibernate的全自动而言的,MyBatis需要手动匹配提供POJO、SQL和映射关系,而Hibernate只需要提供POJO和映射关系即可。与Hibernate相比,虽然使用MyBatis手动编写SQL要比使用Hibernate的工作量大,但MyBatis可以配置动态的SQL并优化SQL,可以通过配置决定SQL的映射规则,它还支持存储过程等。对于一些复杂的和需要优化性能的项目来说,显然使用MyBatis更加合适。
1.1.2 MyBatis的下载和使用
MyBatis下载
在项目中引用核心包和依赖包即可
1.2 MyBatis入门程序
1.2.1 查询用户
1.根据用户编号(id)查询用户信息
示例1-1
主要通过查询用户表中的主键
- 创建db_mybatis库,创建t_user表,预先添加几条数据。
create database db_mybatis;
use db_mybatis;
create table t_user(
id int(32) primary key auto_increment,
username varchar(50),
jobs varchar(50),
phone varchar(16)
);
insert into t_user values(1,'zhangsan','teacher','13907998372');
insert into t_user values(2,'lisi','worker','13907396542');
insert into t_user values(3,'wangwu','doctor','13817348729');
- 创建项目,添加jar包
- 创建log4j.properties文件
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging cofiguration...
log4j.logger.com.ssm=DEBUG
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
- 创建com.ssm.po包,在包下创建持久化类User,并在类中声明id username jobs phone属性,及其对应getter()/setter()方法。
package com.ssm.po;
public class User {
private Integer id;
private String username;
private String jobs;
private String phone;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getJobs() {
return jobs;
}
public void setJobs(String jobs) {
this.jobs = jobs;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String toString(){
return "User [id="+id+",username="+username+",jobs="+jobs+",phone="+phone+"]";
}
}
持久化类user和普通的JavaBean并没有什么区别,只是其属性字段与数据库中的表字段相对应。实际上,user就是一个POJO(普通java对象)MyBatis就是采用POJO作为持久化类来完成对数据库操作的。
- 创建com.ssm.mapper包,并在包中创建映射文件UserMapper.xml
<?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.ssm.mapper.UserMapper">
<select id="findUserById" parameterType="Interger" resultType="com.ssm.po.User">
select * from t_user where id=#{id}
</select>
</mapper>
前几行是约束配置,后面是需要自己编写的映射信息。其中<mapper>
元素是配置文件的根元素,包含一个namespace属性,该属性为<mapper>
指定了唯一的命名空间,通常会设置为“包名+SQL映射文件名”的形式。
子元素<select>
中的信息是用于执行查询操作的配置,其id属性是<select>
元素在映射文件中的唯一标识;parameterType属性用于指定传入参数的类型,这里表示传递一个Integer类型参数;resultType属性用于指定返回结果的类型,这里表示返回的数据是Customer类型。
在定义的查询SQL语句中,#{}
用于表示一个占位符,相当于?
。#{id}
表示该占位符接收参数的名称为id。
- 在src下创建MyBatis-config.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>
<!-- 1.配置环境,默认的环境id为mysql-->
<environments default="mysql">
<!-- 1.2 配置id为mysql的数据库环境-->
<environment id="mysql">
<!-- 使用JDBC事务管理-->
<transactionManager type="JDBC"></transactionManager>
<!-- 数据库连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/db_mybais"/>
<property name="username" value="root"/>
<property name="password" value="toot"/>
</dataSource>
</environment>
</environments>
<!-- 2.配置mapper位置-->
<mappers>
<mapper resource="com/ssm/mapper/UserMapper.xml"/>
</mappers>
</configuration>
这里安装<configuration>
子元素的功能将配置分为两个步骤:(1)配置环境;(2)配置mapper位置
- 创建com.ssm.test,创建测试类
package com.ssm.test;
import com.ssm.po.User;
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 javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
public class findUserByIdTest {
public static void main(String[] args) throws Exception {
// 1.读取配置文件;
String resource="mybatis-config.xml";
InputStream inputStream= Resources.getResourceAsStream(resource);
// 2.根据配置文件构建SqlSessionFactory实例;
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
// 3.通过SqlSessionFactory创建Sqlsession实例;
SqlSession sqlSession=sqlSessionFactory.openSession();
// 4.SQLSession执行映射文件中定义的SQL,并返回映射结果;
User user=sqlSession.selectOne("com.ssm.mapper.UserMapper.findUserById",1);
// 5.打印输出结果;
System.out.println(user.toString());
// 6.关闭sqlsession;
sqlSession.close();
}
}
首先通过输入流读取了配置文件,然后根据配置文件构建了SqlSessionFactory对象,接下来通过SqlSessionFactory对象又创建了SqlSession对象,并通过SqlSession对象的selectOne()方法执行查询操作。
selectOne()方法的第一个参数表示映射SQL的标识字符串,由UserMapper.xml中<mapper>
元素的namespace属性值+<select>
元素的id属性值组成;第二个参数表示查询所需要的参数这里查询的是用户表中id为1的用户。
为了查看查询结果,使用了输出语句输出查询结果信息。
最后,执行完毕后关闭SqlSession。
2.根据用户名模糊查询用户信息
示例1-2
模糊查询的实现只需要在映射文件中通过<select>
元素编写相应的sql语句,并通过SqlSession的查询方法执行即可。
- 在映射文件中添加sql语句
<!-- 根据用户名模糊查询-->
<select id="findUserByName" parameterType="String" resultType="com.ssm.po.User">
select * from t_user where username like '%${value}%'
</select>
其中,${}
用来表示拼接sql的字符串,即不加解释的原样输出。${value}
表示要拼接的是简单类型参数。
在使用
${}
时无法防止SQL注入。
想要实现模糊查询又防止SQL注入,可以使用mysql中的concat函数进行字符串拼接
select * from t_user where username like concat('%',${value},'%')
- 添加测试
package com.ssm.test;
import com.ssm.po.User;
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 javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class findUserByNameTest {
public static void main(String[] args) throws Exception {
String resourse = "mybatis-config.xml";
InputStream inputStream=Resources.getResourceAsStream(resourse);
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession=sqlSessionFactory.openSession();
List<User> users=sqlSession.selectList("com.ssm.mapper.UserMapper.findUserByName","g");
for (User user:users){
System.out.println(user.toString());
}
sqlSession.close();
}
}
MyBatis的操作大致分为以下几个步骤
- 读取配置文件
- 根据配置文件构建SqlSessionFactory
- 通过SqlSessionFactory创建SqlSession
- 使用SqlSession操作数据库
- 关闭SqlSession
1.2.2 添加客户
在MyBatis映射文件中,添加操作是通过<insert>
来实现的。
例如:
<!-- 添加用户信息-->
<insert id="addUser" parameterType="com.ssm.po.User">
insert into t_user(username,jobs,phone)values(#{username},#{jobs},#{phone})
</insert>
传入的参数是一个user类型,该类型的参数对象被传递到语句中时,#{username}
会查找参数对象user的username属性,并将其属性值传入sql语句中。
示例1-3
添加测试类addUserTest
package com.ssm.test;
import com.ssm.po.User;
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 javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
public class addUserTest {
public static void main(String[] args) throws IOException {
String resource="mybatis-config.xml";
InputStream inputStream= Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession=sqlSessionFactory.openSession();
// 创建user,添加数据
User user=new User();
user.setUsername("tom");
user.setJobs("worker");
user.setPhone("13624859654");
// 执行方法
int rows=sqlSession.insert("com.ssm.mapper.UserMapper.addUser",user);
// 返回结果
if(rows>0){
System.out.println("成功添加"+rows+"条数据。");
}else {
System.out.println("添加数据失败!");
}
sqlSession.commit();
sqlSession.close();
}
}
创建了user对象,并添加了数据。
通过SqlSession的insert方法执行插入操作,并通过返回数据来判断是否成功。
最后通过SqlSession的commit提交事务,close关闭。
1.2.3 更新用户
更新操作通过<update>
实现。
<!-- 更新用户信息-->
<update id="updateUser" parameterType="com.ssm.po.User">
update t_user set username=#{username},jobs=#{jobs},phone=#{phone} where id=#{id}
</update>
示例1-4
添加测试类,修改id为4的用户jobs属性为teacher
package com.ssm.test;
import com.ssm.po.User;
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 javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
public class updateUserTest {
public static void main(String[] args) throws IOException {
String resource="mybatis-config.xml";
InputStream inputStream= Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession=sqlSessionFactory.openSession();
// 创建user
User user=new User();
user.setId(4);
user.setUsername("tom");
user.setJobs("teacher");
user.setPhone("13624859654");
// 执行方法
int rows=sqlSession.update("com.ssm.mapper.UserMapper.updateUser",user);
if(rows>0){
System.out.println("成功更新了"+rows+"条数据。");
}else {
System.out.println("更新数据失败!");
}
sqlSession.commit();
sqlSession.close();
}
}
1.2.4 删除用户
通过<delete>
元素来实现
<!-- 删除用户信息-->
<delete id="deleteUser" parameterType="Integer" >
delete from t_user where id=#{id}
</delete>
示例1-5
添加测试类
package com.ssm.test;
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 javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
public class deleteUserTest {
public static void main(String[] args) throws IOException {
String resource="mybatis-config.xml";
InputStream inputStream= Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession=sqlSessionFactory.openSession();
// 执行
int rows=sqlSession.delete("com.ssm.mapper.UserMapper.deleteUser",4);
if(rows>0){
System.out.println("成功删除了"+rows+"条数据。");
}else {
System.out.println("删除数据失败!");
}
sqlSession.commit();
sqlSession.close();
}
}