mybatis入门步骤
1.下载安装mybaits,对于maven工程只需要在pom.xml文件添加mybatis的坐标依赖。
2.建立一个maven工程
3.在pom.xml文件中添加mybatis核心包+mybatis依赖包+数据库驱动包(mysql)
<packaging>jar</packaging> <!--这个表示纯java工程 war 表示包含了web页面的工程-->
<dependencies>
<!--引入mybatis的坐标依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version><!--这个是mybatis的版本-->
</dependency>
<!--引入数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version><!--这个是数据库的版本-->
<scope>runtime</scope><!--表示运行时所需要的包,不是编译时所修要的包-->
</dependency>
<!--引入junit单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version><!--表示版本-->
<scope>test</scope><!--表示测试的时候回用到的包-->
</dependency>
<!--引入日志依赖-->
<!--这个需要去resource里面找到log4j.properties里面看详细的解释-->
<!--写了这个之后你运行的时候就不仅仅只会出来结果,还会有运行的过程-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<!--配置maven的编译器-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
# 这是前面提到的,日志文档,写在resource下面
# Global logging configuration
# 下面这一行注释之后我们就不显示细节了
#log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
4.创建mybaits的核心配置文件mybatis-config.xml文件,是在resource里面创建一个mybatis-config.xml文件
<configuration>
<!--<properties >
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis01?characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</properties>-->
<!--上面注释的愿意是因为,我们下面这个一行代替了上面的数据,这里我们的配置就写在了db.properties里面-->
<!--引入数据源的组件-->
<properties resource="db.properties"></properties>
<!--给包起别名-->
<typeAliases>
<!--配置单个类的别名-->
<!-- <typeAlias type="com.zhiyou100.pojo.User" alias="user" />-->
<!--给pojo整个包下面所有的类起别名-->
<package name="com.zhiyou100.pojo"/>
</typeAliases>
<!--配置文件,就是链接数据库,下面value里面的数据就是我们之前之前在db.properties里面哦配置出来的数据-->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--配置映射文件 接口文件、接口对应的xml文件-->
<mappers>
<!--映射xml文件-->
<!--<mapper resource="com/zhiyou100/dao/IUserDao.xml"/> -->
<!--映射接口文件-->
<!--<mapper class="com.zhiyou100.dao.IUserDao"/> -->
<!--不能在同一个方法上面既使用注解开发,又使用xml配置 -->
<!--<mapper class="com.zhiyou100.dao.IUserDao"/>
<mapper resource="com/zhiyou100/dao/IUserDao.xml"/> -->
<!--上面的注释,就是我们本来应该写的状态,但是由于我们的dao包下可能有很多的接口和xml配置文件,一个一个的写实在太麻烦了-->
<!--所以我们用到了下面的这个直接一步到位,直接包dao包下所有的接口和xml文件都直接配置了-->
<!--package 替换mapper接口文件和xml配置文件 可以同时加载这两个文件
注意事项:
两个保持一致:
①:文件名称一致
②:路径一致
name = com.zhiyou100.dao 能够加载到dao包下面的所有的接口文件和xml文件
-->
<package name="com.zhiyou100.dao"/>
</mappers>
</configuration>
上面说到会用的db.properties,是写在resource下面的
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///mybatis01?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root
5。分别在src下面和resource下面创建com.zhiyou100.dao包,注意resource下面的只能一个一个文件的段都创建,下面放接口的哦欸之文件 src下面的dao里面放接口,并且在test文件夹下面创建测试类,
src里面的dao层
创建接口写接口方法确保4个一致
- 方法名称和文件中的id一致
- 方法的返回值和对应标签内的resultType一致
- 方法的参数和parameterType一致
- namespace和接口的全名称一致
package com.zhiyou100.dao;
import com.zhiyou100.pojo.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* dao接口
*
*/
public interface IUserDao {
// 查询用户表中的所有信息 HashMap key
//这是注解开发,在这里写了sql之后就不用去xml配置文件里面继续写sqlk语句了。相当于省略了去xml里卖弄写sql的步骤
@Select("select * from user")
List<User> queryAllUsers();
// 注解开发
// 根据用户id查询对应的用户信息 select * from user where id = ?
@Select("select * from user where id = #{id}")
User queryUserById(int id);
// crud操作 insert update delete select
// 添加一条用户信息
void addUser(User user);
// 根据id修改用户信息
void modifyUser(User user);
// 根据id值删除用户信息
//这里用#{字段} 是OGNL表达式,我们在实现这个接口的时候传入我们想要的数据这里就能接收到
@Delete("delete from user where id = #{id}")
void removeUserById(int id);
// 根据用户名查询用户信息 模糊查询 '%' #{username} '%' 这是模糊查询的格式
@Select("select * from user where username like '%' #{username} '%'") //使用预编译 占位符方式 #{username}会自动添加''
//@Select("select * from user where username like '%' '${value}' '%'") // 字符串拼接
//@Select("select * from user where username like #{username}") // 字符串拼接
//@Select("select * from user where username like '${value}' ") // 字符串拼接
List<User> fuzzyQueryUsersByUsername(String username);
// 查询总记录数 count()
@Select("select count(*) from user")
int queryTotal();
// 查询用户信息 根据用户名和年龄进行查询 多参数。没有使用注解开发,可以去接口对应的xml文件里面找到sql语句
User queryUserByCondition(String username,int age);
//User queryUserByCondition(User user);
// 根据地址和性别查询用户信息 @Param 在形参类型相同时,在dao层中的相应位置注释上@Param,会根据其中的值映射过去,
User queryUserByCondition2(@Param("address") String address,@Param("gender") String gender);
}
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.zhiyou100.dao.IUserDao">
<!--
xml sql配置和接口中的抽象方法四个保持一致:
xml配置中 dao接口
id 接口里面的方法名
parameterType 方法的参数类型
resultType 返回值类型
namespace 抽象方法的的全路径名一样
-->
<select id="queryAllUsers" resultType="user">
<!--
select * from user where id = #{id}
select * from user where id = 正常的sql语句
#{id}
OGNL 表达式
Object Graphic Navigation Language
对象 图 导航 语言
它主要是通过对象的取值方法来获取到数据,在写法上个get名字省略掉。
类似于 EL表达式 ${user.username} jsp页面中
比如说: user对象中的username值 #{username} 可以省略掉前面那的user对象
省略的原因就是因为 通过parameterType引入了user对象类型
-->
select * from user
</select>
<!--添加用户信息-->
<insert id="addUser" parameterType="user" >
insert into user values(null,#{username},#{age},#{address},#{gender})
</insert>
<!--修改用户信息-->
<update id="modifyUser" parameterType="user">
update user set username = #{username},age = #{age},address = #{address},gender = #{gender} where id = #{id}
</update>
<!--删除一条信息-->
<!--<delete id="removeUserById" parameterType="int" >
delete from user where id = #{id}
</delete>-->
<!--根据用户名和年龄进行查询用户信息
当多个参数数据类型不一致时,不写parameterType 让它自适应
-->
<!---->
<select id="queryUserByCondition" parameterType="user" resultType="user">
<!--Available parameters are [arg1, arg0, param1, param2] -->
<!-- 使用参数对应的索引 来匹配参数的值 版本3.4.1 -->
select * from user where username = #{0} and age = #{1}
</select>
<!--第二种解决办法-->
<select id="queryUserByCondition2" resultType="user">
select * from user where address = #{address} and gender = #{gender}
</select>
</mapper>
注意。一个方法不能同时使用xml配置文件写代码又使用注解写代码
test测试代码
-
加载mybatis-config.xml核心配置文件(存放在类路径下 classpath)
-
使用构建者类SqlSessionFactoryBuilder构建SqlSessionFactory工厂对象
-
通过工厂对象创建SqlSession对象
-
使用sqlSession对象创建UserMapper对应的代理对象
-
使用UserMapper代理对象调用对应的接口方法完整对数据库的操作。
package com.zhiyou100.test;
import com.zhiyou100.dao.IUserDao;
import com.zhiyou100.dao.impl.IUserDaoImpl;
import com.zhiyou100.pojo.User;
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.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.PrimitiveIterator;
/**
* @author: admin
* @date: 2021/2/26
*
* 测试用户类
*/
public class UserTest {
private IUserDao userDao;
private InputStream is;
private SqlSession sqlSession;
@Before /*就是每个测试之前都要执行这个*/
public void init() throws IOException {
// 准备mybatis核心配置文件的路径 类路径 classpath 存放在本地磁盘中classes目录里面的路径
String path = "mybatis-config.xml";
// 使用mybatis内置IO类 Resources
is = Resources.getResourceAsStream(path);
// 通过构建者类去构建SqlSessionFactory工厂对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
// 通过工厂生产SqlSession对象
//sqlSession = factory.openSession(true);// setAutoCommit(false) ---> start transaction
sqlSession = factory.openSession();// setAutoCommit(false) ---> start transaction
// 使用SqlSession对象 调用getMapper方法 获取对应接口代理对象
userDao = sqlSession.getMapper(IUserDao.class);
}
@After /*就是每个测试之后都要执行这个*/
public void release() throws IOException {
sqlSession.commit(); // 提交事务 让修改的数据进行持久化,存储到磁盘中
is.close();
sqlSession.close();
}
/**
* mybatis的入门案例 查询所有用户信息 增删改
*/
@Test
public void testQueryAllUsers() throws IOException {
// 调用userDao接口中的方法
List<User> users = userDao.queryAllUsers();
for (User user : users) {
System.out.println(user);
}
}
/**
* mybatis应用到dao层,借助于接口的实现类 不推荐
*/
@Test
public void testQueryAllUsers2() throws IOException {
// 准备mybatis核心配置文件的路径 类路径 classpath 存放在本地磁盘中classes目录里面的路径
String path = "mybatis-config.xml";
// 使用mybatis内置IO类 Resources
InputStream is = Resources.getResourceAsStream(path);
// 通过构建者类去构建SqlSessionFactory工厂对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
// 实例化 接口实现类对象
IUserDao userDao = new IUserDaoImpl(factory); // 硬编码
// 调用userDao接口对象中方法
List<User> users = userDao.queryAllUsers();
for (User user : users) {
System.out.println(user);
}
}
/**
* mybatis的注解开发 根据id值查询对应的用户信息
*/
@Test
public void testQueryUserById() throws IOException {
// 调用userDao接口中的queryUserById方法
User user = userDao.queryUserById(4);
// User{id=4, username='小赵', age=25, address='开封', gender='男'}
System.out.println(user);
}
/**
* 添加用户信息
*/
@Test
public void testAddUser() {
// 调用userDao的方法
User user = new User(null, "小周", 25, "河南南阳", "女");
userDao.addUser(user);
}
/**
* 根据id修改用户信息
*/
@Test
public void testModifyUser(){
User user = new User(4, "小赵", 25, "开封", "女");
userDao.modifyUser(user);
}
/**
* 根据id值删除用户信息
*/
@Test
public void testRemoveUserById() {
userDao.removeUserById(13);
}
/**
* 模糊查询 根据用户名称查询用户信息
*/
@Test
public void testFuzzyQueryUsersByUsername() {
// List<User> users = userDao.fuzzyQueryUsersByUsername("%花%");
List<User> users = userDao.fuzzyQueryUsersByUsername("花");
for (User user : users) {
System.out.println(user);
}
}
/**
* 查询总记录数
*/
@Test
public void testQueryTotal() {
int count = userDao.queryTotal();
System.out.println(count);// 6
}
/**
* 根据用户名和年龄 多参数查询用户信息
*/
@Test
public void testQueryUserByCondition() {
// User{id=12, username='小花', age=20, address='河南信阳', gender='女'} 3.4.1 3.2.7
User user = userDao.queryUserByCondition("小花", 20);
System.out.println(user);
}
@Test
public void testQueryUserByCondition2() {
// User{id=12, username='小花', age=20, address='河南信阳', gender='女'} 3.4.1 3.2.7
// User{id=19, username='小周', age=25, address='河南南阳', gender='女'}
User user = userDao.queryUserByCondition2("河南南阳", "女");
System.out.println(user);
}
}
mybatis的多参数
在使用mybatis动态代理模式开发的时候,如果接口中的参数有多个的话如:
多参接口代码
// 根据用户名和性别检查用户是否存在
User checkUser( String username,char sex);
多参调用代码
@Test
public void testCheckUser() {
User user = userMapper.checkUser("老王", '女');
System.out.println(user);
}
通过@Param注解设置参数
在接口中给参数添加注解
User checkUser(@Param("username") String username,@Param("sex") char sex);
- 在mapper的配置文件中不写parameterType
<select id="checkUser" resultType="com.zhiyou100.pojo.User">
select * from user where username = #{username} and sex = #{sex}
</select>
调用代码
// 根据用户名和性别检查用户是否存在
@Test
public void testCheckUser() {
User user = userMapper.checkUser("老王", '女');
System.out.println(user);
}