目录
1. MyBatis介绍
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
Mybatis的功能框架分为三成:
API接口层、数据处理层、基础支撑层
Mybatis核心部件
Configuration :MyBatis所有的配置信息都保存在Configuration对象之中,配置文件中的大部分配置都会存储到该类中
SqlSession :作为MyBatis工作的主要顶层API,表示和数据库交互时的会话,完成必要数据库增删改查功能
Executor :MyBatis执行器,调度核心,负责SQL语句的生成和查询缓存的维护,有他来实现真正对数据库的操作。
StatementHandler :封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数等
ParameterHandler : 负责对用户传递的参数转换成JDBC Statement 所对应的数据类型
ResultSetHandler : 负责将JDBC返回的ResultSet结果集对象转换成List类型的集合
TypeHandler: 负责java数据类型和jdbc数据类型(也可以说是数据表列类型)之间的映射和转换
MappedStatement : 其维护着一条<select | update| delete| insert>节点的封装
2. Mybatis实现CRUD操作详解
1)Mybatis中 # 和 $ 参数取值
在Mybatis的映射配置文件中可以通过#{ }或 ${ }这两种方式实现参数值的获取,一般来说能使用#{ } 就不要使用 ${ }
#{}进行参数获取时,会把参数转成字符串,即会自动加上一个引号,
如 select * from student where id= #{id} ,传入id=17413320
最终得到的是 :select * from student where id= '17413320'
${}是将传入的数据直接显示生成在sql中:
如 select * from student where id= #{id} ,传入id=17413320
最终得到的是 :select * from student where id= 17413320
直接运行报错,所以需要我们手动添加'' : select * from student where id= '${id}'
这样一来就容易引起sql注入漏洞的产生。所以说${ }方式一般用于传入数据库对象,例如传入表名 ,列名这种。
2)增删查改,在mapper.xml映射文件中添加
<!--增加操作-->
<insert id="AddUser" parameterType="com.chtw.entity.User" >
INSERT INTO user VALUES(#{id},#{username},#{password},#{address})
</insert>
<!--id对应dao中的AddUser方法-->
<!-- 增删查改,insert,delete,update,select
resultType:返回类型,集合写直属子元素类型,
parameterType:指定参数类型,多参数可写类类型
-->
<!--修改操作-->
<update id="upadateUserName" parameterType="entity.UserBean">
UPDATE bank SET user_name=#{user_name} WHERE id=#{id}
</update>
<!--删除操作-->
<delete id="deleteUserName" parameterType="String">
DELETE FROM bank WHERE id=#{id}
</delete>
<!--单条查询-->
<select id="getUserById" resultType="com.chtw.entity.User" parameterType="int">
select * from user where userId=#{uid}
</select>
<!--多条查询,当需要返回一个list的时候,返回类型写list的元素类型,而不是resultType="list";当返回类型是map,String的时候直接就行map或者string
-->
<select id="getAll" resultMap="userMap"> <!-- resultType="com.chtw.entity.User"> -->
select * from user
</select>
<!-- mysql(column)字段与类属性(property)的映射;property: 属性名,column:表的字段名 -->
<resultMap type="com.chtw.entity.User" id="userMap">
<!-- id映射使用id标签,其他使用result -->
<id column="userId" property="userId"/>
<result column="userName" property="userName"/>
<result column="password" property="password"/>
<result column="info" property="info"/>
</resultMap>
3. 搭建Mybatis工作环境
Mybatis工作流程
1、加载配置
方法一:xml文件配置
方法二:Java注解
2、sql解析
3、sql执行
4、结果映射,将其转换成HashMap,javaBean或者基本数据类型,并将最终的结果返回。
搭建Mybatis工作环境
导入jar包
mybatis-3.4.5.jar
mysql-connector-java-5.1.7-bin.jar
编写JavaBean和dao接口
package com.chtw.entity;
public class User {
private int userId;
private String userName;
private String password;
private String info;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
package com.chtw.dao;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.chtw.entity.User;
/**
* 这里只定义方法名,具体方法在业务层(service)中实现
* userDAO中如果涉及到sql语句,全部放到UserMapper.xml中,只要保持一个DAO对应一个mapper文件就可以了
*/
public interface UserDAO {
/**
* 获取所有用户
* @return用户列表
*/
public List<User> getAll();
/**
* 通过userId查询用户
* @param userId用户Id
* @return用户对象
*/
public User getUserById(@Param("uid") int userId);
public int addUser(User user);
public List<User> getByName(String search);
}
资源文件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>
<!-- 配置数据库环境 -->
<environments default="test"><!-- 默认环境:test -->
<environment id="test">
<!-- 配置mysql事务 -->
<transactionManager type="JDBC"/>
<!-- 配置数据源,在此不使用连接池 -->
<dataSource type="UNPOOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/javaweb_day7"/>
<property name="username" value="root"/>
<property name="password" value="1728aceAB7"/>
</dataSource>
</environment>
<environment id="main">
<!-- 配置mysql事务 -->
<transactionManager type="JDBC"/>
<!-- 配置数据源,在此使用连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3303/javaweb_day7"/>
<property name="username" value="root"/>
<property name="password" value="1728aceAB7"/>
</dataSource>
</environment>
</environments>
<!-- 配置dao映射文件 -->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
映射文件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.chtw.dao.UserDAO"><!-- 对应一个dao -->
<!-- 增删查改,insert,delete,update,select
id:指定方法名,
resultType:返回类型,集合写直属子元素类型,
parameterType:指定参数类型,多参数可写类类型
-->
<select id="getAll" resultMap="userMap"> <!-- resultType="com.chtw.entity.User"> -->
select * from user
</select>
<select id="getUserById" resultType="com.chtw.entity.User" parameterType="int">
select * from user where userId=#{uid}
</select>
<insert id="addUser" parameterType="com.chtw.entity.User">
insert into user(userName,password,info) value(#{userName},#{password},#{info})
</insert>
<!-- ${}一般用于传入数据库对象,表名,列名 -->
<select id="getByName" parameterType="String" resultType="com.chtw.entity.User">
select * from user where userName like '%${value}%'
<!-- select * from user where userName like CONCAT('%',#{search},'%'); -->
</select>
<!-- mysql(column)字段与类属性(property)的映射 -->
<resultMap type="com.chtw.entity.User" id="userMap">
<!-- id映射使用id标签,其他使用result -->
<id column="userId" property="userId"/>
<result column="userName" property="userName"/>
<result column="password" property="password"/>
<result column="info" property="info"/>
</resultMap>
</mapper>
创建数据库,添加数据
create database javaweb_day7;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`userId` int(11) NOT NULL AUTO_INCREMENT,
`userName` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`info` varchar(255) DEFAULT NULL,
PRIMARY KEY (`userId`)
) ENGINE=InnoDB AUTO_INCREMENT=1013 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1001', 'Alice', '654321', '大美女');
INSERT INTO `user` VALUES ('1002', 'Bob', '582413', '大帅哥');
INSERT INTO `user` VALUES ('1004', 'Alice', '654321', '大美女');
INSERT INTO `user` VALUES ('1005', 'Alice', '654321', '大美女');
INSERT INTO `user` VALUES ('1006', 'Alice', '654321', '大美女');
INSERT INTO `user` VALUES ('1007', 'Alice', '654321', '大美女');
INSERT INTO `user` VALUES ('1008', 'Bob', '1234658', '男团');
INSERT INTO `user` VALUES ('1009', 'Bo', '1234658', '男团');
INSERT INTO `user` VALUES ('1010', 'cl', '1234658', '男团');
INSERT INTO `user` VALUES ('1011', 'fuj', '1234658', '男团');
INSERT INTO `user` VALUES ('1012', '牛源', '1234658', '男团');
书写一个测试类:获取SqlSession 数据会话对象,调用其提供的方法实现对数据库的操作
package com.chtw.test;
import java.io.InputStream;
import java.util.List;
import org.apache.ibatis.io.ResolverUtil.Test;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.chtw.dao.UserDAO;
import com.chtw.entity.User;
public class MyTest {
public static void main(String[] args) {
InputStream is = Test.class.getClassLoader().getResourceAsStream("config/mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
System.out.println("---------------使用方法的全路径---------------");
//方法一:使用方法的全路径
String str = "com.chtw.dao.UserDAO.getUserById";
User user = sqlSession.selectOne(str,1001);
System.out.println(user.getUserName()+"\t"+user.getInfo());
System.out.println("------------------------------------------");
System.out.println("---------------通过类获取---------------");
//方法二:通过类获取;获取所有人
UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
List<User> uList = userDAO.getAll();
for (User u : uList) {
System.out.println(u.getUserName()+"\t"+u.getInfo());
}
System.out.println("------------------------------------------");
System.out.println("----------------添加用户测试--------------");
//添加用户测试
User u1 = new User();
u1.setUserName("TeacherWANG");
u1.setPassword("1111111");
u1.setInfo("教师");
int count = userDAO.addUser(u1);
if(count > 0) {
sqlSession.commit();//手动提交事务
System.out.println("添加成功");
}else {
System.out.println("添加失败");
}
System.out.println("------------------------------------------");
System.out.println("----------------模糊查询------------------");
//模糊查询
List<User> users = userDAO.getByName("牛");
for (User u3 : users) {
System.out.println(u3.getUserName()+"\t"+u3.getPassword());
}
}
}
本人联系方式2329095893,欢迎各位进行学习讨论
欢迎关注熊熊出没ING公众号,不定时跟新Java、python、信息安全等相关知识哦。