摘要:Mybatis笔记_07-2021.06.19
1.Mybatis注解开发
1.1 作用:使用注解开发,实现CRUD
1.2 局限性:
- 使用注解开发时,我们只能处理简单的SQL语句,比如:数据库表中字段名和实体类属性名之间有对应关系
- 当我们数据库字段名与实体类中属性名没有对应关系时,我们需要进行结果集(resultMap)映射,然而使用注解开发不适用解决此情况
1.3 面向接口编程:
-
定义与实现相分离,接口只负责定义方法而不用负责方法如何实现
-
接口分为两类: 第一类是对一个个体的抽象,它可对应为一个抽象体(abstract class);
第二类是对一个个体某一方面的抽象,即形成一个抽象面(interface);
1.4 面向对象是指,我们考虑问题时,以对象为单位,考虑它的属性及方法
/*
面向对象:强调具备了功能的对象,以类/对象为最小单位,通常需要考虑的是由谁来做。
面向对象的三大特性:封装、继承、多态。
例:“人把大象装进冰箱”的需要什么功能,然后将功能封装到类/对象中
对象1:人{
打开(冰箱) {
冰箱.open();
}
抬起(大象) {
大象.enter(冰箱);
}
关闭(冰箱) {
冰箱.close();
}
}
对象2:冰箱{
open();
close();
}
对象3:大象{
enter(冰箱);
}
*/
1.5 面向过程面向过程)是指,我们考虑问题时,以一个具体的流程(事务过程)为单位,考虑它的实现
/*
面向过程:强调的是功能行为,以函数为最小单位,通常需要考虑的是怎么去做的过程。
例:“人把大象装进冰箱”的操作过程
1.打开冰箱;
2.抬起大象,装进冰箱;
3.关闭冰箱。
*/
1.6 #{}和${}的区别:
-
#{} 是 占位符 :动态解析 -> 预编译 -> 执行;可以防止sql 注入
-
${} 是 拼接符 :动态解析 -> 编译 -> 执行;不可以防止sql 注入
-
sql注入:传入的参数会改变SQL语句原本规则
例子:传入参数"1 or 2",通常我们把引号("")中的认为是一个字符串,然后当我们使用${}传入sql时却会产生id = 1 or id = 2这样的情况,我们把产生这种情况的操作称为sql注入,试想一下当你传入的是一整个字符串时,参数发生变化会造成什么影响。
1.SQL代码:#{},参数:value = “1 or 2”
select * from user where id = #{value},此时 id = “1 or 2”;
2.SQL代码:${},参数:value = “1 or 2”
select * from user where id = ${value},此时 id = 1 or id = 2,这就是SQL语句进行拼接时会发生的SQL注入。
情景假设:我们传入SQL语句中的参数由用户进行输入,如果用户输入死语句,如:1 or 0,SQL执行,程序是否进入死循环等错误(个人一点小理解哈,尽量按自己方式来,理解以及如何防止即可)。
-
能用 #{} 的地方就用 #{},尽量少用 ${}
-
#{},传参时使用@Param("")注解
1.7 @Param("")注解
-
什么时候使用:采用#{}的方式通过@Param("")注解括号内的参数进行引用;
//1.单一属性: @Select("select * from t_user where id = #{id};") User getUserById(@Param("id") int id); //2.JavaBean对象 @Insert("insert into t_user values(#{user.id},#{user.username},#{user.password},#{user.email});") void addUser(@Param("user") User user);
-
引用级别:括号内@Param(“id”)(“id”)比 int id(id)优先级更高,即当需要获取参数时,括号(“id”)优先被使用
2.MySQL数据库(t_user)
create table t_user(
id int primary key auto_increment,
username varchar(20) not null unique,
password varchar(40) not null,
email varchar(200)
);
insert into t_user(username,password,email) values('admin','admin','admin@qq.com');
insert into t_user(username,password,email) values('abc','abc123','abc@qq.com');
insert into t_user(username,password,email) values('login','login123','login@qq.com');
insert into t_user(username,password,email) values('pojo','pojo123','pojo@qq.com');
insert into t_user(username,password,email) values('user','user123','user@qq.com');
select * from t_user;
3.工具类(MybatisUtils.java)
package com.riove.utils;
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;
//sqlSessionFactory -->sqlSession
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
//官网有相关代码,固定代码块
static {
try {
//使用Mybatis第一步:1.获取sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
/*
*使用Mybatis第二步:2.获取sqlSessionFactory对象后,可以从中获取SqlSession的实例
* SqlSession 完全包含了面向数据库执行SQL命令所需要的方法
*/
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
4.实体类(pojo)
package com.riove.pojo;
import org.apache.ibatis.type.Alias;
@Alias("user")
public class User {
private int id;
private String username;
private String password;
private String email;
public User() {
}
public User(int id, String username, String password, String email) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
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 String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
'}';
}
}
5.接口(UserMapper.java)
package com.riove.dao;
import com.riove.pojo.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
import java.util.Map;
public interface UserMapper {
//查询所有用户
@Select("select * from t_user;")
List<User> getUserList();
//模糊查询
@Select("select * from t_user where username like #{value};")
List<User> getUserListByLike(@Param("value") String value);
//通过id查询用户
@Select("select * from t_user where id = #{id};")
User getUserById(@Param("id") int id);
//插入一个新的用户,参数是User对象
@Insert("insert into t_user values(#{user.id},#{user.username},#{user.password},#{user.email});")
void addUser(@Param("user") User user);
//通过id,修改用户信息
@Update("update t_user set username = #{user.username}, password = #{user.password}, email = #{user.email} where id = #{user.id};")
void updateUserById(@Param("user") User user);
//通过id,删除用户
@Delete("delete from t_user where id = #{id};")
void deleteUserById(@Param("id") int id);
}
6.核心配置文件(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">
<!--Mybatis-->
<configuration>
<!--引入外部properties文件-->
<properties resource="db.properties">
<!--这里也可以添加相应的属性,不过调用的优先级比外部属性低-->
<!--<property name="driver" value="com.mysql.jdbc.Driver"/>-->
</properties>
<!--设置-->
<settings>
<!--全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。-->
<!--<setting name="cacheEnabled" value="true"/>-->
<!--懒加载-->
<!--<setting name="lazyLoadingEnabled" value="true"/>-->
<!--其他设置-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--类型别名-->
<typeAliases>
<!--1.全类名的类型,type="全类名",alias="自定义别名";-->
<!--<typeAlias alias="user" type="com.riove.pojo.User"/>-->
<!--2.指定包名,那么="指定的实体类包名",alias:如果没有注解,别名默认为实体类名,不区分大小写;-->
<!--<package name="com.riove.pojo"/>-->
<!--3.注解提供别名,alias:注解值;-->
<package name="com.riove.pojo"/>
</typeAliases>
<!--environments可以有多个环境,但在进行实例时只能选择一个默认环境,只有默认环境会生效-->
<environments default="mysql">
<environment id="mysql">
<!--transactionManager,事务管理:JDBC|MANAGED-->
<transactionManager type="JDBC"/>
<!--dataSource,数据源:UNPOOLED|POOLED|JNDI-->
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
<environment id="sqlserver">
<transactionManager type="" />
<dataSource type="">
<property name="driver" value=""/>
<property name="url" value=""/>
<property name="username" value=""/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>
<!--使用注解开发,绑定接口-->
<mappers>
<mapper class="com.riove.dao.UserMapper"/>
</mappers>
</configuration>
7.测试(UserMapperTest.java)
package com.riove.dao;
import com.riove.pojo.User;
import com.riove.utils.MybatisUtils;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class UserMapperTest {
@Test
public void getUserListTest() {
//1.获取的SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
//2.执行Sql,面向接口,通过获取接口实现方法
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//3.实现方法
List<User> userList = mapper.getUserList();
//4.输出
for (User user : userList) {
System.out.println(user);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//5.关闭SqlSession
sqlSession.close();
}
}
@Test
public void getUserListByLikeTest() {
//1.获取的SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
//2.执行Sql,面向接口,通过获取接口实现方法
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//3.实现方法
List<User> userList = mapper.getUserListByLike("%o%");
//4.输出
for (User user : userList) {
System.out.println(user);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//5.关闭SqlSession
sqlSession.close();
}
}
@Test
public void getUserByIdTest() {
//1.获取的SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
//2.获取SqlSession绑定的接口类,然后通过接口实现方法
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//3.测试(实现)方法
User userById = mapper.getUserById(8);
System.out.println(userById);
} catch (Exception e) {
e.printStackTrace();
} finally {
//4.关闭资源
sqlSession.close();
}
}
@Test
public void addUserTest() {
//1.获取的SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
//2.获取SqlSession绑定的接口类
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//3.测试方法
mapper.addUser(new User(8,"BABA","baba","BABA@qq.com"));
//4.提交事务
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
//5.关闭资源
sqlSession.close();
}
}
@Test
public void updateUserByIdTest() {
//1.获取的SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
//2.获取SqlSession绑定的接口类
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//3.测试方法
mapper.updateUserById(new User(8,"AABB","abc123","AABB@qq.com"));
//4.提交事务
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
//5.关闭资源
sqlSession.close();
}
}
@Test
public void deleteByIdTest() {
//1.获取的SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
//2.获取SqlSession绑定的接口类
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//3.测试方法
mapper.deleteUserById(6);
//4.提交事务
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
//5.关闭资源
sqlSession.close();
}
}
}