Mybatis简介摘自Mybatis官网网址(https://mybatis.org/mybatis-3/zh/index.html)
什么是 MyBatis?
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
mybatis三个核心对象的生命周期:
SqlSessionFactoryBuilder 用过即丢,其生命周期只存在于方法体内。
它负责构建SqlSessionFactory,并且提供了多个build的重载方法。
构建一个SqlSessionFactory的两种方式:
一:读取xml文件构造方式。
读取xml文件构造方式:
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//创建sqlSessionFactory工厂
SqlSessionFactoryBuilder sqlSessionFactoryBuilder= new SqlSessionFactoryBuilder(); //使用了构造者模式
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
二:编程构造方式。
SqlSessionFactory
SqlSessionFactory是每个Mybatis应用的核心。
单例,存在于整个应用运行时,并且同时只存在一个对象实例。
SqlSession
包含了执行sql所需的所有方法,可以通过SqlSession实例直接运行映射的sql语句。
SqlSession对应着一次数据库的会话,它的生命周期不是永久的,在每次访问数据库时都需要创建它。
每个线程都有自己的SqlSession实例,SqlSession实例是不能被共享的,也不是线程安全的。
注意: 并不是说在SqlSession里只能执行一次sql,你可以执行多次,当一旦关闭了SqlSession就需要重新创建它。
注意:关闭SqlSession是非常重要的,你必须要确保SqlSession在finally方法体中正常关闭。
什么是框架:它是我们软件开发中的一套解决方案,不同的框架解决的是不同的问题。
三个对象的作用域:
**使用框架的好处:**框架封装了很多细节,使开发者可以使用极简的方式实现功能,大大提高开发效率
三层框架:
表现层:用于展示数据的
业务层:处理业务的需求
持久层:和数据库交互的
持久层技术解决方案:
JDBC技术:
Connection
preparedStatement
ResultSet
spring的jdbcTemplate:
spring中对jdbc的封装
Apache的DBUtils:
它和Spring中的jdbcTemplate很像,也是对jdbc的封装。
以上都不是框架
jdbc是规范
spring的jdbcTemplate和Apache的DBUtils都只是工具类。
mybatis的概述:
mybatis是一个持久层的框架,用java编写的。它封装了jdbc操作的很多细节,使开发者只需要关注sql语句本身,而无需关注注册驱动,创建连接等繁杂的过程,它使用了ORM思想实现了结果集的封装。
ORM:
Object Relational Mapping 对象关系映射
简单说:就是把数据库表和实体类及实体类的属性对应起来让我们可以操作实体类就实现操作数据库表。
mybatis入门:
mybatis的环境搭建:
第一步:创建maven工程并导入坐标。
第二步:创建实体类和dao的接口。
第三步:创建mybatis的主配置文件 mybatis-config.xml。
第四步:创建映射配置文件 userDaoMapper.xml。
环境搭建的注意事项:
第一个:创建userDaoMapper.xml和UserDao.java时名称是为了和我们之前的知识保持一致,
第二个:在idea中创建目录的时候,它和包是不一样的。
包在创建的时候:com.aliwo.dao它是三级结构。
目录在创建的时候:com.aliwo.dao是一级结构。
第三个:mybatis的映射文件位置必须和dao接口的包结构相同。
第四个:映射文件的mapper标签namespace属性的取值必须是dao接口的全限定类名。
第五个:映射文件的操作配置(select),id属性的取值必须是dao接口的方法名
mybatis的入门案例
第一步:读取配置文件
第二步:创建SqlSessionFactory工厂
第三步:使用工厂创建sqlSession
第四步:使用sqlSession创建Dao接口的代理对象
第五步:使用代理对象执行方法
第六步:释放资源
配置环境
**使用maven首先导入坐标mybatis和mysql的坐标**
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
连接数据库 语句
create database spring;
/*
Navicat Premium Data Transfer
Source Server : mysql主库
Source Server Type : MySQL
Source Server Version : 50727
Source Host : localhost:3306
Source Schema : spring
Target Server Type : MySQL
Target Server Version : 50727
File Encoding : 65001
Date: 24/03/2020 13:10:50
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(2) NOT NULL AUTO_INCREMENT,
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 38 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'admin', 'admin');
INSERT INTO `user` VALUES (2, 'root', 'root');
INSERT INTO `user` VALUES (3, 'roots', 'root');
INSERT INTO `user` VALUES (4, 'rootss', 'root');
INSERT INTO `user` VALUES (5, 'ceshi', 'ceshi');
INSERT INTO `user` VALUES (6, 'inset_last_id', 'root');
SET FOREIGN_KEY_CHECKS = 1;
项目结构如图:
配置实体类User在entity包下:
package com.mybatis.entity;
import java.io.Serializable;
/**
* package_name:com.mybatis.entity
*
* @author:徐亚远 Date:2020/2/23 10:38
* 项目名:springDemo01
* Description:TODO
* Version: 1.0
**/
public class User implements Serializable {
private Integer id;
private String username;
private String password;
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", id=" + id +
'}';
}
public User() {
}
public User(String username, String password, Integer id) {
this.username = username;
this.password = password;
this.id = id;
}
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 Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
配置实体类UserVo在entity包下:
package com.mybatis.entity;
/**
* package_name:com.mybatis.entity
*
* @author:徐亚远 Date:2020/2/24 10:56
* 项目名:springDemo01
* Description:TODO
* Version: 1.0
**/
public class UserVo {
private User user;
@Override
public String toString() {
return "UserVo{" +
"user=" + user +
'}';
}
public UserVo() {
}
public UserVo(User user) {
this.user = user;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
配置UserDao在dao层下
package com.mybatis.dao;
import com.mybatis.entity.User;
import com.mybatis.entity.UserVo;
import java.util.List;
/**
* package_name:com.mybatis.dao
*
* @author:徐亚远 Date:2020/2/23 10:39
* 项目名:springDemo01
* Description:TODO
* Version: 1.0
**/
public interface UserDao {
/**
* @param username
* @return User
* 通过用户名查询
*/
//@Select("select * from User where username=#{username}")
User selectByUserName(String username);
/*
*/
/**
* 使用注解开发
*//*
@Select("select * from User")*/
/**
* @return list
* 查询所有
*/
//@Select("select * from User")
List<User> selectByUserAll();
/**
* @param id 删除通过id
*/
Integer deleteByid(Integer id);
/**
* 删除用户通过用户名
*
* @param username
*/
//@Delete("delete from User where username=#{username}")
void deleteByUsername(String username);
/**
* 修改用户信息通过id
*
* @param user
*/
//@Update("update User set username=#{username},password=#{password} where id=#{id}")
void updateUser(User user);
/**
* 添加用户信息
*
* @param user
*/
//@Insert("insert into User(username,password) values (#{username},#{password})")
void insertUser(User user);
/**
* 通过用户id查询
*
* @param id
*/
User selectById(Integer id);
/**
* 统计用户数
*/
Integer totalUser();
/**模糊查询*/
List<User> findUnClear(String username);
/**模糊查询*/
List<User> findVo(UserVo userVo);
}
配置连接数据库信息jdbc.properties 在Resources目录下
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
配置日志信息log4j.properties 在Resources目录下
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\\mybatis日志\\mybatis黑马.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
配置userDaoMapper.xml文件在Resources目录下的com.mybatis.dao
<?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.mybatis.dao.UserDao">
<!--配置查询结果的列名和实体属性名的对应关系-->
<resultMap id="userMap" type="com.mybatis.entity.User">
<!--主键字段的对应-->
<id property="id" column="id"/>
<!--非主键字段的对应-->
<result property="username" column="username"/>
<result property="password" column="password"/>
</resultMap>
<select id="selectById" parameterType="java.lang.Integer" resultType="com.mybatis.entity.User">
select * from user where id=#{id}
</select>
<select id="selectByUserName" parameterType="java.lang.String" resultType="com.mybatis.entity.User">
select * from user where username=#{username}
</select>
<select id="selectByUserAll" resultType="com.mybatis.entity.User">
select * from user
</select>
<delete id="deleteByid" parameterType="Integer">
delete from user where id=#{id}
</delete>
<delete id="deleteByUsername" parameterType="java.lang.String">
delete from user where username=#{username}
</delete>
<update id="updateUser" parameterType="com.mybatis.entity.User">
update user set username=#{username},password=#{password} where id=#{id}
</update>
<insert id="insertUser" parameterType="com.mybatis.entity.User">
<selectKey keyProperty="id" keyColumn="id" resultType="java.lang.Integer" order="AFTER">
select last_insert_id()
</selectKey>
insert into user(username, password) values (#{username},#{password})
</insert>
<select id="totalUser" resultType="java.lang.Integer">
select count(1) from user;
</select>
<select id="findUnClear" parameterType="java.lang.String" resultType="com.mybatis.entity.User">
<!--select * from user where username like #{username}-->
select * from user where username like '%${value}%'
</select>
<select id="findVo" parameterType="com.mybatis.entity.UserVo" resultType="com.mybatis.entity.User">
select * from user where username like #{user.username}
</select>
</mapper>
书写mybatis-config.xml文件在Resources目录下
<?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">
<!--mybatis的主配置文件-->
<configuration>
<!--配置mysql环境-->
<environments default="mysql">
<environment id="mysql">
<!--配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置连接池-->
<dataSource type="POOLED">
<!--配置连接数据库的基本信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--指定映射文件的位置-->
<mappers>
<mapper resource="com/mybatis/dao/userDaoMapper.xml"/>
<!--使用注解开发在dao层的方法上使用@Select-->
<!--<mapper class="com.mybatis.dao.UserInfoDao"/>-->
</mappers>
</configuration>
书写测试类在util包下
package com.mybatis.util;
import com.mybatis.dao.UserDao;
import com.mybatis.entity.User;
import com.mybatis.entity.UserVo;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
/**
* package_name:com.mybatis.utils
*
* @author:徐亚远 Date:2020/2/23 13:28
* 项目名:springDemo01
* Description:TODO
* Version: 1.0
**/
public class testAll implements Serializable {
private InputStream inputStream;
private SqlSessionFactory sqlSessionFactory;
private SqlSession sqlSession;
private UserDao userDao;
/**
* @Before表示在测试方法执行之前执行
*/
@Before
public void init() throws Exception {
//第一步读取配置文件
inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//第二步创建sqlSessionFactory工厂
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
//第三步使用工厂创建sqlSession
sqlSession = sqlSessionFactory.openSession();
//第四步使用sqlSession创建Dao接口的代理对象
userDao = sqlSession.getMapper(UserDao.class);
//第五步使用代理对象执行方法
}
/**
* After表示在测试方法执行之后执行
*/
@After
public void destroy() throws Exception {
//第六步释放资源
sqlSession.close();
inputStream.close();
}
/**
* 查询所有用户信息
*/
@Test
public void selectAll() {
List<User> list = userDao.selectByUserAll();
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
/**
* 通过用户名查询
*/
@Test
public void selectByUsername() {
User user = userDao.selectByUserName("admin");
if (user != null) {
System.out.println("用过用户名查询信息:" + user);
} else {
System.out.println("查询失败");
}
}
/**
* 通过用户名查询
*/
@Test
public void deleteById() {
Integer i = userDao.deleteByid(21);
sqlSession.commit();
if (i > 0) {
System.out.println("删除成功");
} else {
System.out.println("删除失败");
}
}
/**
* 通过用户名删除
*/
@Test
public void deleteByUsername() {
userDao.deleteByUsername("root");
sqlSession.commit();
}
/**
* 更新用户信息
*/
@Test
public void update() {
User user = new User();
user.setId(21);
user.setUsername("xiaoxu");
user.setPassword("root");
userDao.updateUser(user);
sqlSession.commit();
}
/**
* 添加用户信息
*/
@Test
public void insert() {
User user = new User();
user.setUsername("inset_last_id");
user.setPassword("root");
System.out.println("插入前id:"+user.getId());
userDao.insertUser(user);
sqlSession.commit();
System.out.println("插入后id:"+user.getId());
}
/**
* 根据用户id查询
*/
@Test
public void selectById() {
User user = userDao.selectById(1);
sqlSession.commit();
System.out.println("user:" + user);
}
/**
* 统计总用户数
*/
@Test
public void totalUser() {
Integer i = userDao.totalUser();
System.out.println("总个数:" + i);
}
/**
* 根据用户名模糊查询
*/
@Test
public void findUnClear() {
//List<User> list = userDao.findUnClear("%roo%");
List<User> list = userDao.findUnClear("r");
Iterator<User> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
/**
* 根据用户名模糊查询
*/
@Test
public void findVo() {
UserVo userVo = new UserVo();
User user = new User();
user.setUsername("%r%");
userVo.setUser(user);
//List<User> list = userDao.findUnClear("%roo%");
List<User> list = userDao.findVo(userVo);
sqlSession.commit();
Iterator<User> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}