目录
1.增加用户需要注意的是如果需要返回增加的id有2种方式(没有写顶部代码了复制上面即可,放入关键代码)
2.主键不一定是int类型... 主键也可以是字符串类型。有数据库合并,数据库集群的时候。
首先知道什么是框架:
框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面而后者是从目的方面给出的定义。简单来说框架是软件的半成品. 我们开发者使用框架开发, 更加的简单, 提高开发效率。
了解什么是MyBatis:
官方介绍是:MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。简单来说就是:持久层的一个框架, 封装了JDBC. 操作数据库。官网: mybatis – MyBatis 3 | Introduction
准备环境:
数据库:
CREATE TABLE user(
uid int PRIMARY KEY auto_increment,
username varchar(40),
sex varchar(10),
birthday date,
address varchar(40)
);
INSERT INTO `user` VALUES (null, 'zs', '男', '2021-09-08', '北京');
INSERT INTO `user` VALUES (null, 'ls', '女', '2021-09-30', '深圳');
INSERT INTO `user` VALUES (null, 'ww', '男', '2021-09-08', '上海');
创建用的Maven
idea:2020.1.3版本
jdk用的1.8版本
使用mybatis进行简单的查询案例:
-
创建Maven工程(java), 添加mybatis的依赖坐标
-
创建pojo (javabean)
-
创建UserDao接口
-
创建UserDao映射文件 (xml配置文件)
-
创建MyBatis核心配置文件SqlMapConfig.xml (xml配置文件)
-
编写java代码测试
1.添加依赖
<!--1. 添加依赖-->
<dependencies>
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--MyBatis坐标-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--lombok 依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
2.创建pojo (javabean)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
private int uid;
private String username;
private String sex;
private Date birthday;
private String address;
}
3.创建UserDao接口
public interface UserDao {
/**
* 查询所有用户
* @return
*/
List<User> FindAll();
}
4.创建UserDao映射文件 (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.demon.dao.UserDao">
<!--查询所有用户-->
<select id="FindAll" resultType="com.demon.bean.User" >
SELECT * FROM user
</select>
</mapper>
5.创建MyBatis核心配置文件SqlMapConfig.xml (xml配置文件)(引入的Dao接口的映射文件需要写全路径),并且内部的核心配置文件的顺序不可乱放,深入了解可以百度或者走官方查看。
其中4步骤和5步骤的代码最上开头部分不用记知道有这个就行,可以去官网复制或者其他地方或者下面复制,但要把MyBatis核心配置文件和Dao的映射文件开头那区分开来不是一样的
标签:environments : 用于配置环境,它里面可以定义多个环境,使用 environment来定义
到底是用哪一个环境,取决于 default属性写的是哪个 environment的id值
environment : 用于定义环境,
id :声明一个标识,唯一标识
transactionManager : 事务管理员
dataSource :用不用连接池 用:POOLED,不用UNPOOLED, 还有一个值是:JNDI MyBatis 会从 JNDI 服务上(tomcat ... jboss...)查找 DataSource 实例,然后返回使用. 只有在web项目里面才有的,用的是服务器里面的. 默认会使用tomcat里面的dbcp
<?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就是根标签-->
<configuration>
<!--数据库环境配置-->
<environments default="en">
<environment id="en">
<!--MyBatis的事务管理 采用的是JDBC事务控制-->
<transactionManager type="JDBC"/>
<!--MyBatis连接池配置 使用MyBatis默认的POOLED-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--数据库名称-->
<property name="url" value="jdbc:mysql://localhost:3306/userbe"/>
<!--数据库账号-->
<property name="username" value="root"/>
<!--数据库密码-->
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--mappers就对应dao接口映射文件-->
<!--引入dao接口映射文件 注意:需要写全路径-->
<mappers>
<mapper resource="com/demon/dao/UserDao.xml"/>
</mappers>
</configuration>
注意:Dao接口和Dao映射文件的地方和名字要一样。核心配置文件需要放置在resources下
7.编写java代码测试(格式建议可以用上图那样简单明了)
需要注意:图上单元测试说的,在Maven工程下或环境下他会认为你的测试类名要有test单词,所以一般建议用testxxx这样,简单明了而且不用写注释就知道,不然会出现单元测试时候运行了不打印的情况。(在导mybatis的包时候是也就是Resources的时候是:org.apache.ibatis.io,因为早期apache公司创建mybatis时用的ibatis名字后来才改的mybatis,只不过后来没改包名字一直用的ibatis)
import com.demon.bean.User;
import com.demon.dao.UserDao;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class TestUserDao {
//查询所有用户
@Test
public void testFindAll() throws IOException {
//1.读取核心配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建构建器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.使用构建器创建SqlSessionFactory工厂
SqlSessionFactory sqlSessionFactory = builder.build(is);
//4.问工厂要SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//5.问SqlSession对象要UserDao的代理对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
//6.直接调用方法
List<User> list = userDao.FindAll();
for(User user:list){
System.out.println(user);
}
//7.关闭sqlSession
sqlSession.close();
}
}
打印结果:
注意:打印的那出现那么多红的是正常的,因为我用了打印出日志的依赖。
数据库:
--------------------------------------------------------------------------------------------------------------------------------
在上面发现单元测试类中出现了一部分代码可封装,所以SqlSessionFactory工具类的抽取。
注意:工具类的提交事务,提交事务: mybatis没有默认提交事务 ,它把setAutoCommit(false), 所以对于增删改操作,要记得提交事务。
但可以在内部修改成默认的提交事务。也就是:sqlSessionFactory.openSession(true);自动提交事务。反之false
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 java.io.IOException;
import java.io.InputStream;
public class SqlSessionFactoryUtils {
private static SqlSessionFactory sqlSessionFactory =null;
//使用静态代码块是为了使得工厂只有一个
static {
try {
//读取核心配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建构建器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//使用构建器创建SqlSessionFactory工厂
sqlSessionFactory = builder.build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获得SqlSession对象
* @return
*/
public static SqlSession getsqlSession(){
//问工厂要SqlSession对象,
//openSession(true)手动修改为自动提交事务。false为不自动
return sqlSessionFactory.openSession();
}
/**
*关闭sqlSession提交事务
* @param sqlSession
*/
public static void commit(SqlSession sqlSession){
sqlSession.commit();
sqlSession.close();
}
/**
*关闭sqlSession
* @param sqlSession
*/
public static void close(SqlSession sqlSession){
sqlSession.close();
}
}
使用Mybatis完成CRUD:
增加用户:
UserDao接口:
/**
* 添加用户
* @param user
* @return 受影响的行数
*/
int AddUser(User user);
UserDao.xml(Dao接口的映射文件):
<insert id="AddUser" parameterType="com.demon.bean.User" keyProperty="uid" >
INSERT INTO user VALUES(null , #{username} , #{sex} , #{birthday} , #{address})
</insert>
单元测试:
//添加一个用户
@Test
public void testAddUser() throws IOException {
SqlSession sqlSession = SqlSessionFactoryUtils.getsqlSession();
//问SqlSession对象要UserDao的代理对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
//直接调用方法
User user = new User();
user.setUsername("zs1");
user.setSex("男");
user.setBirthday(new Date());
user.setAddress("深圳");
userDao.AddUser(user);
//关闭sqlsession和提交事务
SqlSessionFactoryUtils.commit(sqlSession);
}
1.增加用户需要注意的是如果需要返回增加的id有2种方式(没有写顶部代码了复制上面即可,放入关键代码)
1.1用SelectKey标签添加
<!--添加用户-->
<insert id="AddUser" parameterType="com.demon.bean.User" keyProperty="uid" >
INSERT INTO t_user VALUES(null , #{username} , #{sex} , #{birthday} , #{address})
<!--
selectKey: 主要使用来获取主键id
keyProperty : 用参数user里面的什么属性来接收主键值
resultType: 接收主键的属性是什么类型
order: 只能写两个值: before | after
BEFORE: 先执行获取id的操作,再去执行添加数据的操作
AFTER : 先执行添加的操作,再去执行获取id的操作。
-->
<selectKey keyProperty="uid" resultType="int" order="AFTER">
<!--不需要多了解入门阶段-->
SELECT LAST_INSERT_ID()
</selectKey>
</insert>
1.2.用属性配置
<!--
添加用户,获取id主键返回
keyProperty :表示,使用参数user对象里面的什么属性来接收主键id
useGeneratedKeys:
true: 使用数据库创建自增生成给出来的id值
false: 不是用数据库创建出来的id值,由mybatis自己生成给出来id值。
-->
<insert id="AddUser" parameterType="com.demon.bean.User" keyProperty="uid" useGeneratedKeys="true">
INSERT INTO t_user VALUES(null , #{username} , #{sex} , #{birthday} , #{address})
</insert>
2.主键不一定是int类型... 主键也可以是字符串类型。有数据库合并,数据库集群的时候。
字符串类型的主键通常就是UUID生成的一串32个字符的字符串。 数据库合并!
<!--添加用户,获取id主键返回,但是主键是字符串类型的主键-->
<insert id="AddUser" parameterType="com.demon.bean.User" >
INSERT INTO t_user VALUES(null , #{username} , #{sex} , #{birthday} , #{address})
<selectKey keyProperty="myId" resultType="String" order="BEFORE">
select uuid()
</selectKey>
</insert>
删除用户:
UserDao接口:
/**
* 删除一个用户
* @param id
* @return
*/
int deleteUser(int id);
UserDao.xml(Dao接口的映射文件):
<!--删除用户-->
<delete id="deleteUser" parameterType="int">
delete from user where uid=#{uid}
</delete>
单元测试:
//删除一个用户
@Test
public void testdeleteUser() throws IOException {
SqlSession sqlSession = SqlSessionFactoryUtils.getsqlSession();
//5.问SqlSession对象要UserDao的代理对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
//6.直接调用方法
userDao.deleteUser(4);
//关闭sqlsession和提交事务
SqlSessionFactoryUtils.commit(sqlSession);
}
修改用户:需要先根据id查用户在进行修改
UserDao接口:
public interface UserDao {
/**
* 查询一条用户
* @return 受影响的行数
*/
User FindUser(int uid);
/**
* 修改用户
* @param user
* @return
*/
int updateUser(User user);
}
UserDao.xml(Dao接口的映射文件):
<!--查找一条用户信息-->
<select id="FindUser" resultType="com.demon.bean.User" parameterType="int">
SELECT * FROM user WHERE uid=#{uid}
</select>
<!--修改用户-->
<update id="updateUser" parameterType="com.demon.bean.User">
update user set username=#{username} , sex=#{sex} , birthday=#{birthday} , address=#{address} where uid=#{uid}
</update>
单元测试:记得一定要提交事务否则数据库不会更改信息
public class TestUserDao {
//修改用户
@Test
public void testupdateUser() throws IOException {
SqlSession sqlSession = SqlSessionFactoryUtils.getsqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
//直接调用方法
User user = userDao.FindUser(1);
user.setUsername("王五");
int i = userDao.updateUser(user);
System.out.println(i);
//关闭sqlsession和提交事务
SqlSessionFactoryUtils.commit(sqlSession);
}
}
查询用户:
有以下的情况:
1.查询一条语句(参数为:id,name......)
1.1.参数一个(#{}和${}区别在查询代码后面)
1.1.1#{}
1.1.2${}
1.2参数为多个
1.3参数为多个且类型不同(注意:可以不给parameterType赋值)
UserDao接口:
/**
* 查询一条用户
* @return 受影响的行数
*/
//普通查询一条语句
//id查询
User FindUser(int uid);
//字符串查询
User FindUser7(String user)
;
//用mybatis自带的@Param注解取别名
User FindUser5(@Param("username") String username,@Param("sex") String sex);
UserDao.xml(Dao接口的映射文件):
<!--查找一条用户信息-->
<!--用id查询-->
<select id="FindUser" resultType="com.demon.bean.User" parameterType="int">
SELECT * FROM user WHERE uid=#{uid}
</select>
<!--或者用#{}或${value}查询-->
<select id="FindUser7" resultType="com.demon.bean.User" parameterType="string">
SELECT * FROM user WHERE username=#{username}
<!--或者用${value}查询 注:${}内部必须为value否则报错
SELECT * FROM user WHERE username='${value}'
-->
</select>
<!--用别名解决多个参数查一条数据时,如果参数不同类型可以直接不给parameterType赋值>
<select id="FindUser5" resultType="com.demon.bean.User" parameterType="string">
select * from user where username=#{username} and sex=#{sex}
</select>
单元测试:
@Test
public void testFindUser() throws IOException {
SqlSession sqlSession = SqlSessionFactoryUtils.getsqlSession();
//问SqlSession对象要UserDao的代理对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
//直接调用方法
//用id查询
User user= userDao.FindUser(1);
//用字符串查询
//User user= userDao.FindUser7("王五");
//查询一条数据多个参数时候
//User user= userDao.FindUser5("王五","男");
System.out.println(user);
//7.关闭sqlSession
SqlSessionFactoryUtils.close(sqlSession);
}
2.查询多条语句
3.模糊查询:4种
3.1外拼接%方法
3.2sql语句内追加%方法
3.2.1"%"#{}"%"
3.2.2"%${}%"
3.2.3concat("%",#{},"%") (推荐)
UserDao接口:
/**
* 模糊查询
* @param
* @return
*/
List<User> FindUser1(String username);
List<User> FindUser2(String username);
List<User> FindUser3(String username);
UserDao.xml(Dao接口的映射文件):
<!--模糊查询-->
<!--使用concat()-->
<select id="FindUser1" parameterType="string" resultType="com.demon.bean.User">
select * from t_user where username like concat("%",#{username},"%")
</select>
<!--使用#{}-->
<select id="FindUser2" parameterType="string" resultType="com.demon.bean.User">
select * from user where username like "%"#{username}"%"
</select>
<!--使用${}-->
<select id="FindUser3" resultType="com.demon.bean.User" parameterType="com.demon.bean.User">
<!--
必须下面格式写否则报错
也就是单引号或双引号,引起中间内容
${}内部也必须为value否则报错
-->
select * from user where username like '%${value}%'
</select>
单元测试:(把方法名改了就可验证)
//模糊查询
@Test
public void testFindUser1() throws IOException {
SqlSession sqlSession = SqlSessionFactoryUtils.getsqlSession();
//5.问SqlSession对象要UserDao的代理对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
//6.直接调用方法
List<User> list = userDao.FindUser3("a");
System.out.println(list);
//7.关闭sqlSession
SqlSessionFactoryUtils.close(sqlSession);
}
注意: #{}和${}区别
-
#{}
表示一个占位符号-
通过
#{}
可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 数据库 类型转换 -
#{}
可以有效防止 sql 注入 -
#{}
可以接收简单类型值或 pojo 属性值 -
如果 parameterType 传输单个简单类型值(String,基本类型),
#{}
括号中可以是 value 或其它名称。
-
-
${}
表示拼接 sql 串-
通过
${}
可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换. -
${}
不能防止 sql 注入 -
${}
可以接收简单类型值或 pojo 属性值 -
如果 parameterType 传输单个简单类型值.
${}
括号中只能是 value
-
=====以上就是小白的我对于mybatis的一个入门的理解,如果有错希望能帮我指出。QAQ=====
下面也是我用xmind做的一个
思维导图: