Java-Mybatis-01
学习视频:B站 狂神说Java – https://www.bilibili.com/video/BV1NE411Q7Nx
学习资料:mybatis 参考文档 – https://mybatis.org/mybatis-3/zh/index.html
1、Mybatis框架
学习使用Mybatis框架, 我使用的开发环境是:JDK1.8、Mysql5.7、maven3.6.3、IDEA
Mybatis简介:
-
MyBatis 是一款优秀的持久层框架
-
它支持自定义 SQL、存储过程以及高级映射。
-
MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
-
MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
数据持久化:
-
持久化就是将程序的数据在持久状态和瞬时状态转化的过程
-
内存:断电即失
-
数据库 JDBC,IO 文件持久化
持久层:
MVC三层架构中有 Model、View、Control。其中Model 代码架构有Dao层、Service层。Service层就是逻辑业务代码,去调用底层 dao。
持久层对应于我们的Dao层、Service层、Controller层。
- 完成持久化工作的代码块。
- 层界限十分明显
对于DAO这一层专注于处理数据库 sql 的操作。前面的 JDBC 涉及到数据库连接、加载、获取对象等重复性的工作,为了专注于只去修改sql语句,为了更加便捷,所以需要这个框架。
MyBatis的优点:
-
不用再去编写一堆JDBC代码,简单易学。框架。自动化
-
sql和代码的分离,增加了可维护性
-
提供映射标签,支持对象与数据库的 ORM关系映射
-
提供XML标签,支持编写动态sql
回顾JDBC:JDBC 就是 Java Database Connectivity,用来规定客户端程序如何来访问数据库的应用程序接口。
具体步骤为:
- 加载数据库驱动
- 需要连接的数据库的用户和配置信息 URL
- 连接数据库,表示数据库对象 connection
- 创建执行SQL的 Statement 对象(会有SQL注入现象) 使用prepareStatement 进行预编译,防止SQL注入
- 执行sql
- 关闭连接
JDBC-demo
文件格式:
原有的demo和格式:
code:
package com.AL.lessom1;
import java.sql.*;
public class jdbcFirstDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver"); //固定写法,加载驱动
//2.用户信息和url。 url指网络地址,在这里指的就是具体数据库路径地址
//useUnicode=true 支持中文编码 characterEncoding=utf8设置中文字符为utf8 useSSL=true 使用安全连接
String url="jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&useSSL=true"; //需要连接的数据库具体文件
String username="root"; //用户名字
String password="123456"; //用户密码
//3.连接成功,数据库对象 connection就代表数据库了
Connection connection = DriverManager.getConnection(url, username, password);
//4.执行SQL的对象 Statement 表示执行SQL的对象,此时就相当于 school.student这个表
Statement statement = connection.createStatement();
//5.执行SQL的对象去执行 sql 可能存在结果,查看返回结果
String sql="select * from student";
ResultSet resultSet = statement.executeQuery(sql);
while(resultSet.next()){
System.out.println("id="+resultSet.getObject("id")); //假如不知道数据类型,就用 getObject()
System.out.println("name="+resultSet.getObject("name"));
System.out.println("password="+resultSet.getObject("pwd"));
System.out.println("sex="+resultSet.getObject("sex"));
System.out.println("birthday="+resultSet.getObject("birthday"));
System.out.println("address="+resultSet.getObject("address"));
System.out.println("email="+resultSet.getObject("email"));
System.out.println("========================================");
}
//5.关闭连接
resultSet.close();
statement.close();
connection.close();
}
}
2、第一个Mybatis程序
2.1、Mybatis的准备工作
- maven仓库
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
- maven依赖的 jar包:mysql驱动、mybatis、junit测试
<!--导入依赖 -->
<dependencies>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<!--mybatis -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
-
专注于处理数据库 sql。那么还需要搭建一个数据库
CREATE DATABASE `mybatis`; USE `mybatis`; CREATE TABLE `user`( `id` INT(20) NOT NULL PRIMARY KEY, `name` VARCHAR(30) DEFAULT NULL, `pwd` VARCHAR(30) DEFAULT NULL )ENGINE=INNODB CHARSET=utf8; INSERT INTO `user`(`id`, `name`, `pwd`) VALUES (1,'鑫仔','123456'), (2,'天啊','123456'),(3,'好胖','123890')
2.2、创建Maven项目
1.创建一个普通的maven项目,没有maven模板。
2.删除src目录
3.导入maven依赖
4.创建一个子项目
此时的子项目 mybatis-01 会继承父项目中的 jar包,不用再次导入。
Mybatis框架的步骤:
- 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。
- SqlSessionFactory 的实例需要通过SqlSessionFactoryBuilder 来得到。
- 这个SqlSessionFactoryBuilder 是要在xml配置文件中进行配置 config, 然后才能去构建SqlSessionFactory 实例。
2.2.1 编写mybatis的核心配置文件
如下所示:在资源文件 resource 中的 xml文件中进行预定义配置 config,才能去构建 SqlSessionFactoryBuilder。
<?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">
<!--XML 配置文件或者预先定义的一个 config,去SqlSessionFactoryBuilder, 配置数据库,便于创建sqlSessionFactory实例-->
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&charsetEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--关联映射文件-->
<mappers>
<mapper resource="com/AL/dao/UserMapper.xml"/>
</mappers>
</configuration>
2.2.2、编写mybatis工具类
在这里我们预定义配置了mybatis-config.xml。我们是从 XML文件中去构建 SqlSessionFactory的实例。使用类路径下资源文件进行配置,即 String resource = “mybatis-config.xml”;
SqlSessionFactoryBuilder 从配置文件 mybatis-config.xml中 使用输入流InputStream 获得SqlSessionFactory,并从中获取sqlsession。
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
mybatis工具类:
package com.AL.utils;
import org.apache.ibatis.jdbc.SQL;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
//import javax.annotation.Resources;
import org.apache.ibatis.io.Resources;
import java.io.InputStream;
// sqlSessionFactory --> sqlSession
public class MybatisUtils {
// 创建这个sqlSessionFactory,是从资源文件resource中的去获得。
private static SqlSessionFactory sqlSessionFactory;
static {
try {
//利用mybatis第一步: 获取一个sqlSessionFactory对象
String resource = "mybatis-config.xml";
/** 注意:不需要修改,是因为导入的包不正确.不是 import javax.annotation.Resources
* 将ResourcesgetResourceAsStream(resource);改为
* Resources.class.getResourceAsStream(resource);
* //得到配置文件流
* InputStream inputStream = Resources.class.getResourceAsStream(resource);
*/
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (Exception e) {
e.printStackTrace();
}
}
//有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
// SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
public static SqlSession getSqlSession() {
//SqlSession sqlSession = sqlSessionFactory.openSession();
//return sqlSession;
return sqlSessionFactory.openSession();
}
}
2.2.3、实体类
编写实体类。实体类 class中的属性对应着 数据库 mybatis.user中的字段, 即 id,name, pwd。
package com.AL.pojo;
public class User {
private int id;
private String name;
private String pwd;
public User() {
}
public User(int id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = pwd;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
2.2.4、Dao接口
package com.AL.dao;
import com.AL.pojo.User;
import java.util.List;
public interface UserDao {
// 获取全部的用户
List<User> getUserList();
}
2.2.5、Mapper配置文件
接口实现类:sql语句功能。
接口实现类由原来的 UserDaoImpl转变为一个 Mapper配置文件。
<?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">
<!--namespace= 绑定一个对应的Dao/Mapper接口
<mapper namespace="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
-->
<mapper namespace="com.AL.dao.UserDao">
<!--select 查询语句 -->
<select id="getUserList" resultType="com.AL.pojo.User">
select * from mybatis.user
</select>
</mapper>
2.2.6、测试代码
在测试的里面,我们也建立和main中的java 对应的结构,这样更加规范:
package com.AL.dao;
import com.AL.pojo.User;
import com.AL.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import java.util.List;
public class UserDaoTest {
@Test
public void test(){
//1.拿到sqlSessionFactory对象
//SqlSessionFactory sqlSessionFactory = MybatisUtils.getSqlSession();
//2.通过sqlSessionFactory对象openSession()创建一个sqlSession。
//SqlSession sqlSession = sqlSessionFactory.openSession();
SqlSession sqlSession = MybatisUtils.getSqlSession();
//3.通过sqlSession获得mapper对象 , 参数为映射文件对应的接口类的class对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
//4.通过mapper对象来执行操作;
List<User> userList = userDao.getUserList();
//获得结果集
for (User user : userList) {
System.out.println(user);
}
//关闭sqlSession
sqlSession.close();
}
}
2.2.7、结果
发现错误:
org.apache.ibatis.exceptions.PersistenceException:
### Error building SqlSession.
### The error may exist in com/AL/dao/UserMapper.xml
.......
Caused by: java.io.IOException: Could not find resource com/AL/dao/UserMapper.xml
可以发现是这个资源无法找到。
很明显是Could not find resource com/xxx/xxx/Xxx.xml的错误。本人使用的是idea编译器,在idea中是不会编译src的java目录的xml文件,所以在Mybatis的配置文件中找不到xml文件!(也有可能是Maven构建项目的问题)。
资源配置导出出现了问题,所以在 pom.xml文件中进行添加配置资源导出:
<build>
<!--希望maven在导出项目的时候,能够将我们的配置及资源导出-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
关于作用域和生命周期的问题
自己在学习的时候,会发现
-
private static SqlSessionFactory sqlSessionFactory; // 静态变量
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
-
public static SqlSession getSqlSession() { //SqlSession sqlSession = sqlSessionFactory.openSession(); //return sqlSession; return sqlSessionFactory.openSession(); }
为什么这么写呢? https://mybatis.org/mybatis-3/zh/getting-started.html
不同作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。
-
依赖注入框架可以创建线程安全的、基于事务的 SqlSession 和映射器,并将它们直接注入到你的 bean 中,因此可以直接忽略它们的生命周期。
-
SqlSessionFactoryBuilder
这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。
-
SqlSessionFactory
SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。
-
SqlSession
每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 finally。
3、CRUD
增删查改实现:只需要修改三个地方
- 编写接口
- 编写接口对应的mapper中的sql语句
- 测试,编写对应的CRUD方法 对应的测试方法。
接口 Dao/mapper: 在这里定义想要完成某个sql功能的方法名和参数
接口实现类: xml配置文件, 在这里完成sql功能的方法的具体实现。
其中的namespace = 绑定的一个接口 dao/mapper。
id对应着 接口中的方法名; resultType是返回的类型。
接口实现类中的 namespace中的包名, 要和接口 Dao/mapper中的包名一致。如下方代码所示:
<mapper namespace="com.AL.dao.UserDao">
<!--select 查询语句 -->
<select id="getUserList" resultType="com.AL.pojo.User">
select * from mybatis.user
</select>
</mapper>
上述的xml中的代码分析:
- select:sql中的查询语句。
- id:对应着namespace中的包名的方法名。 对应着此时的接口中的某个方法
- resultType: sql语句执行的返回值。是这个数据库 mybatis.user,是一个User类,里面包含了表格的字段(属性): id /name/pwd
3.1、查找指定id用户
通过指定的id进行查找用户: 在这里,为了 更好的映射,我将 userDao接口改成了 userMapper接口
3.1.1、接口代码的修改:
package com.AL.dao;
import com.AL.pojo.User;
import java.util.List;
public interface UserMapper {
// 获取全部的用户
List<User> getUserList();
// 根据ID查找用户
User getUserById(int id);
}
3.1.2、mapper中的sql语句
接口实现类:编写对应的sql语句.
-
id:对应着Mapper接口中的方法名,此时增加了一个 getUserId方法,
-
resulttype: sql语句返回的值,是这个数据库 mybatis.user,是一个User类,里面包含了表格的属性: id /name/pwd
-
parameterType: 参数类型, 即数据库中的参数,即User类中的参数,属性. 如果是 int类型,可以不用写这个
<?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"> <!--namespace= 绑定一个对应的Dao/Mapper接口 <mapper namespace="org.mybatis.example.BlogMapper"> <select id="selectBlog" resultType="Blog"> select * from Blog where id = #{id} --> <mapper namespace="com.AL.dao.UserMapper"> <!--select 查询语句 --> <select id="getUserList" resultType="com.AL.pojo.User"> select * from mybatis.user </select> <select id="getUserById" parameterType="int" resultType="com.AL.pojo.User"> select * from mybatis.user where id = #{id} </select> </mapper>
3.1.3、测试
测试代码中, 对接口中的sql语句,进行对应的方法测试。 这里增加的是getUserById方法。
package com.AL.dao;
import com.AL.pojo.User;
import com.AL.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class UserDaoTest {
@Test
public void test(){
//1.拿到sqlSessionFactory对象
//SqlSessionFactory sqlSessionFactory = MybatisUtils.getSqlSession();
//2.通过sqlSessionFactory对象openSession()创建一个sqlSession。
SqlSession sqlSession = MybatisUtils.getSqlSession();
//3.通过sqlSession获得mapper对象 , 参数为映射文件对应的接口类的class对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//4.通过mapper对象来执行操作;
List<User> userList = userMapper.getUserList(); //查询全部用户
//获得结果集
for (User user : userList) {
System.out.println(user);
}
//关闭sqlSession
sqlSession.close();
}
@Test
public void getUserById(){
//1.拿到sqlSessionFactory对象
//2.通过sqlSessionFactory对象openSession()创建一个sqlSession。
SqlSession sqlSession = MybatisUtils.getSqlSession();
//3.通过sqlSession获得mapper对象 , 参数为映射文件对应的接口类的class对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//4.通过mapper对象来执行操作;
User userById = userMapper.getUserById(1);
//获得结果
System.out.println(userById);
//关闭sqlSession
sqlSession.close();
}
}
#{}和${}的区别是什么?
-
** 是 P r o p e r t i e s ⽂ 件 中 的 变 量 占 位 符 ∗ ∗ , 它 可 以 ⽤ 于 标 签 属 性 值 和 s q l 内 部 , 属 于 静 态 ⽂ 本 替 换 , ⽐ 如 {} 是 Properties ⽂件中的变量占位符**,它可以⽤于标签属性值和 sql 内部,属于静态⽂本替换,⽐如 是Properties⽂件中的变量占位符∗∗,它可以⽤于标签属性值和sql内部,属于静态⽂本替换,⽐如{driver}会被静态替换为 com.mysql.jdbc.Driver 。
-
**#{} 是 sql 的参数占位符,**Mybatis 会将 sql 中的 #{} 替换为?号,在 sql 执⾏前会使⽤PrepareStatement 的参数设置⽅法,
按序给 sql 的?号占位符设置参数值,⽐如 ps.setInt(0, parameterValue), #{item.name} 的取值⽅式为使⽤反射从参数对象中获取item 对象的 name 属性值,相当于 param.getItem().getName() 。
-
#{}是预编译处理,${}是字符串替换
1、Mybatis 在处理 #{} 时,会将 SQL 中的 #{} 替换为 ? 号,调用 PrepareStatement 的 set 方法来赋值;使用 #{} 可以有效的防止 SQL 注入,提高系统安全性;
2、Mybatis在处理 ${} 时,
就是把 ${} 替换成变量的值。
3.2、增删改
3.2.1、接口代码的修改
package com.AL.dao;
import com.AL.pojo.User;
import java.util.List;
public interface UserMapper {
// 获取全部的用户
List<User> getUserList();
// 根据ID查找用户
User getUserById(int id); //依据的是 id,所以用 int id
//insert 一个用户
int addUser(User user); //插入一个用户,即插入了一个完整的实例 class,对象,所以用 user
//修改一个用户
int updateUser(User user);
//删除一个用户
int deleteUser(int id);
}
3.2.2、mapper中的sql语句
<?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">
<!--namespace= 绑定一个对应的Dao/Mapper接口
<mapper namespace="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
-->
<mapper namespace="com.AL.dao.UserMapper">
<!--select 查询语句 -->
<select id="getUserList" resultType="com.AL.pojo.User">
select * from mybatis.user
</select>
<select id="getUserById" parameterType="int" resultType="com.AL.pojo.User">
select * from mybatis.user where id = #{id}
</select>
<!--对象中的属性,可以直接取出来。 如id name -->
<insert id="addUser" parameterType="com.AL.pojo.User">
insert into mybatis.user (id, name, pwd) values (#{id},#{name}, #{pwd});
</insert>
<update id="updateUser" parameterType="com.AL.pojo.User">
update mybatis.user set name=#{name}, pwd=#{pwd} where id=#{id};
</update>
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id=#{id};
</delete>
</mapper>
3.2.3、测试
package com.AL.dao;
import com.AL.pojo.User;
import com.AL.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class UserDaoTest {
@Test
public void test(){
//1.拿到sqlSessionFactory对象
//SqlSessionFactory sqlSessionFactory = MybatisUtils.getSqlSession();
//2.通过sqlSessionFactory对象openSession()创建一个sqlSession。
SqlSession sqlSession = MybatisUtils.getSqlSession();
//3.通过sqlSession获得mapper对象 , 参数为映射文件对应的接口类的class对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//4.通过mapper对象来执行操作;
List<User> userList = userMapper.getUserList(); //查询全部用户
//获得结果集
for (User user : userList) {
System.out.println(user);
}
//关闭sqlSession
sqlSession.close();
}
@Test //查询
public void getUserById(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User userById = userMapper.getUserById(1);
//获得结果
System.out.println(userById);
//关闭sqlSession
sqlSession.close();
}
@Test //插入
public void addUser(){
//1.拿到sqlSessionFactory对象
//2.通过sqlSessionFactory对象openSession()创建一个sqlSession。
SqlSession sqlSession = MybatisUtils.getSqlSession();
//3.通过sqlSession获得mapper对象 , 参数为映射文件对应的接口类的class对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//4.通过mapper对象来执行操作;
int res = userMapper.addUser(new User(4,"the shy","123456"));
if (res>0){
System.out.println("我插入成功了啊");
}
//提交事务
//提交事务
//提交事务
sqlSession.commit();
//关闭sqlSession
sqlSession.close();
}
@Test //更新
public void updateUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.updateUser(new User(4, "jack", "978654321"));
sqlSession.commit(); //提交事务
sqlSession.close();
}
@Test //删除
public void deleteUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.deleteUser(4);
sqlSession.commit(); //提交事务
sqlSession.close();
}
}
3.3、总结
在Mybatis框架中,其实dao接口中的一个方法,对应着接口实现类xml中的 id 方法名, 一个xml 语句 具体实现,即 id,parameter,result. 然后对应着测试里面的一个方法(这里面用于测试CRUD),去完成CRUD的工作。
注意点:
-
所有的增删改,需要提交事务:sqlSession.commit()
-
在接口中,注意类型 parameterType, 这个其实在对应的 mapper文件中,写sql语句时也有对应, 在@Test方法中,返回的类型也对应。
// 查询指定Id的用户 User getUserById(int id); //依据的是 id,所以用 int id //insert 一个用户 int addUser(User user); //插入一个用户,即插入了一个完整的实例 class,对象,所以用 user
-
标签需要一致, 即接口中的(Mapper)方法插入/修改,需要在接口实现类,(xml文件)中的sql语句里面的 要对应为 inesrt/update 对应起来.
-
namesapce + id=“getUserList” 去构成全限定名,匹配对应的类、方法。
-
参数类型和返回类型:
<select id="getUserById" parameterType="int" resultType="com.AL.pojo.User">
Mybatis框架的步骤:
- pom.xml 配置文件。导入依赖的jar包, 以及防止maven资源配置文件导出失败的xml文件
- 编写mybatis的核心配置文件。在资源文件 resource 中的 xml文件中进行配置 SqlSessionFactoryBuilder.
- 编写mybatis工具类。 由SqlSessionFactoryBuilder来构建SqlSessionFactory 以及 session
- 实体类。 对应着数据库的表。 ORM关系映射
- Dao接口。
- Mapper配置文件。 sql语句,是接口实现类,
- 测试代码。Dao接口、sql语句、测试方法都对应着。
4、Map和模糊查询扩展
4.1、万能Map
当我们的实体类,或者数据库中的表,字段或者参数多的时候,我们应该去考虑使用Map。这样我们就不用把每一个参数写出来,像下面这样:
insert into mybatis.user (id, name, pwd) values (#{id},#{name}, #{pwd});
万能的map:利用的是键值对. 只需要针对特定的,需要的参数 写出来, 不用全部都写出来。如:我们进行查询,只需要 id值, 且此时的参数类型不是 parameterType=“int” ,而是parameterType=“map” 。
<select id="getUserById2" parameterType="map" resultType="com.AL.pojo.User">
select * from mybatis.user where id = #{kkkid};
</select>
对应的,在调用方法 getUserById2() 时,使用 kkkid这个映射的map键,向map中传递参数:
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("kkkid", 1);
User userById2 = mapper.getUserById2(map);
利用map 进行 插入和查询的例子:
1、接口mapper的代码修改:
package com.AL.dao;
import com.AL.pojo.User;
import java.util.List;
import java.util.Map;
public interface UserMapper {
// 获取全部的用户
List<User> getUserList();
// 根据ID查找用户
User getUserById(int id); //依据的是 id,所以用 int id
User getUserById2(Map<String,Object> map); // map
//insert 一个用户
int addUser(User user); //插入一个用户,即插入了一个具体的实例,对象,所以用 user
// 万能的 Map
int addUser2(Map<String,Object> map);
}
2.UserMapper.xml 修改:映射路径,sql语句
<mapper namespace="com.AL.dao.UserMapper">
<!--select 查询语句 -->
<select id="getUserList" resultType="com.AL.pojo.User">
select * from mybatis.user
</select>
<select id="getUserById" parameterType="int" resultType="com.AL.pojo.User">
select * from mybatis.user where id = #{id}
</select>
<select id="getUserById2" parameterType="map" resultType="com.AL.pojo.User">
select * from mybatis.user where id = #{kkkid};
</select>
<!--对象中的属性,可以直接取出来。 如id name -->
<insert id="addUser" parameterType="com.AL.pojo.User">
insert into mybatis.user (id, name, pwd) values (#{id},#{name}, #{pwd});
</insert>
<insert id="addUser2" parameterType="map">
insert into mybatis.user (id, name, pwd) values (#{userid},#{userName},#{passWord});
</insert>
</mapper>
3、测试代码修改:
package com.AL.dao;
import com.AL.pojo.User;
import com.AL.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
public class UserDaoTest {
@Test
public void test(){
//1.拿到sqlSessionFactory对象
//SqlSessionFactory sqlSessionFactory = MybatisUtils.getSqlSession();
//2.通过sqlSessionFactory对象openSession()创建一个sqlSession。
//SqlSession sqlSession = sqlSessionFactory.openSession();
SqlSession sqlSession = MybatisUtils.getSqlSession();
//3.通过sqlSession获得mapper对象 , 参数为映射文件对应的接口类的class对象
UserMapper userDao = sqlSession.getMapper(UserMapper.class);
//4.通过mapper对象来执行操作;
List<User> userList = userDao.getUserList();
//获得结果集
for (User user : userList) {
System.out.println(user);
}
//关闭sqlSession
sqlSession.close();
}
@Test
public void addUser2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("userid", 5);
map.put("userName", "clearlove");
map.put("passWord", 77777);
int res = mapper.addUser2(map);
if (res>0){
System.out.println("我插入成功了啊");
}
//提交事务
sqlSession.commit();
//关闭sqlSession
sqlSession.close();
}
@Test
public void getUserById2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("kkkid", 1);
User userById2 = mapper.getUserById2(map);
//获得结果
System.out.println(userById2);
sqlSession.close();
}
}
注意:增删改的时候 一定要提交事务。否则完成不了sql 任务。
4.2、模糊查询
模糊查询的语法:
-
Java代码执行的时候, 使用通配符 % %
List<User> userList = mapper.getUserLike("%嗯%")
-
SQL中,使用通配符 “%” “%”
select * from mybatis.user where name like “%”#{value}“%”
例子:
1、接口 mapper代码:
//模糊查找用户
List<User> getUserLike(String s);
2.UserMapper.xml 修改:映射路径,sql语句
<select id="getUserLike" resultType="com.AL.pojo.User">
select * from mybatis.user where name like #{value}
</select>
3、测试代码修改:
@Test
public void getUserLike(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserLike("%c%");
for (User user : userList) {
System.out.println(user);
}
//关闭sqlSession
sqlSession.close();
}
结果为:
User{id=4, name='jack', pwd='978654321'}
User{id=5, name='clearlove', pwd='77777'}