目录
---------------------------Mybatis入门使用-----------------------
-------------------------------mybatis反向代理--------------------------------
1.创建构建数据库操作Mapper.xml和Mapper接口
新建一个maven工程
一、导包
在pom.xml里输入依赖
数据库连接驱动
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--Mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
例如现在数据库有张user表, 要得到select * from user where id=1;的结果
package com;
public class User {
int id;
String name;
String pwd;
int age;
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;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
", age=" + age +
'}';
}
}
定义一个类用来接收从数据库查询到的结果,一定要有get/set方法,因为mybatis底层的JDBC就是通过调用set方法把结果集的数据封装到User对象里
---------------------------Mybatis入门使用-----------------------
二、配置
1.存放sql语句的Mapper.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">
<!--NameSpace 任意起名字,就是这个Mapper.xml的身份标签-->
<mapper namespace="aaa">
<!--sql语句是select类型,标签用select,
id随便起,是这条sql语句的身份标签,一个xml文件里可以有多个sql语句,但是id不能重复
resultType是执行sql的结果,mybatis底层会把statement执行sql的结果集解析出来。用set方法封装到User对象里,因为User的变量名和数据库列名一样,所以通过反射setXx可以封装成功
-->
<select id="cc" resultType="com.User">
select * from user where id = 1
</select>
</mapper>
mapper映射文件是用来写sql语句,以后修改sql语句只用修改映射文件,就不会对代码内容造成影响
parameterType可以不写
查询的时候resultType必须写
2、配置Mybatis的主配置文件
<?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">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!--dataSource的类型可以配置成其内置类型之一,如UNPOOLED、POOLED、JNDI。
UNPOOLED,mybaties会为每一个数据库操作创建一个新的连接,并关闭它。该方式适用于只有小规模数量并发用户的简单应用程序上。
POOLED,mybaties会创建一个数据库连接池,连接池的一个连接将会被用作数据库操作。一旦数据库操作完成,mybaties会将此连接返回给连接池。在开发或测试环境中经常用到此方式。
JNDI。mybaties会从在应用服务器向配置好的JNDI数据源DataSource获取数据库连接。在生产环境中优先考虑这种方式。-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/z29th"/>
<property name="username" value="root"/>
<property name="password" value="root1234"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 把上面的Mapper.xml 注册进来,路径写在resources目录下的路径-->
<mapper resource="com/UserMapper.xml"/>
</mappers>
</configuration>
三、执行SQL
查
查单个结果
//加载mybatis的配置文件
InputStream input = User.class.getClassLoader().getResourceAsStream("mybatis.xml");
//或者用这种方法加载配置文件,Resources是mybatis自己提供的类
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
// 用建造者模式,创造 生产SqlSession的工厂(这个工厂的类型由配置文件决定)
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(input);
// 工厂生产Sqlsession
SqlSession sqlSession = factory.openSession();
//执行sql,根据sql的类型选择是用select、insert、delete、update方法执行sql
//如果要修改数据库,最后要执行sqlSession.commit(),因为mybatis默认开启事务
// selectOne有两个重载方法,一参和二参(二参的是在sql语句里多了一个可变参数)
// 第一个形参是xml里面sql语句的坐标(哪个xml文件的哪条语句)
User user = sqlSession.selectOne("aaa.cc");
System.out.println(user);
//关闭IO资源(工厂对象会自动回收)
input.close();
sqlSession.close();
查多个结果
List<User> zs = sqlSession.selectList("aaa.selectList", "zs");
增
<insert id="insertUser" parameterType="com.User">
insert into user2 values (#{id}, #{username}, #{password},#{age})
</insert>
User user = new User();
user.setId(3);
user.setUsername("zs");
user.setPassword("bea");
user.setAge(30);
int affectedRows = sqlSession.insert("aaa.insertUser", user);
// 因为我们这里Mybatis默认事务是不提交的,我们需要手动提交事务
sqlSession.commit();
用map对象插入数据
删
<delete id="deleteUserById" parameterType="java.lang.Integer" >
<!--#{x}让id 变成一个参数,可以在执行sql时,再输入具体值-->
delete from user where id = #{id}
</delete>
@Test
public void testUserDelete() {
int affectedRows = sqlSession.delete("aaa.deleteUserById", 2);
System.out.println(affectedRows);
sqlSession.commit();
}
改
mapper.xml
<update id="updateUserById" parameterType="java.lang.String">
update user2 set username = #{username}
</update>
@Test
public void testUpdateUser(){
int affectedRows = sqlSession.update("aaa.updateUserById", "zs");
sqlSession.commit();
System.out.println("affectedRows:" + affectedRows);
}
总结:
sqlSession的参数类型:1 命名空间+id
2 参数(只能传一个,对应xml里面用#{}占位的元素)
如果sql语句里面的#{}只有一个,{}里面的变量名随便写
select标签才有resultType属性,insert没有
如果有多个#{param} ,每个param的变量名对应的javabean的参数名
mybatis配置文件讲解
包括主配置文件和映射的xml文件
主配置文件
mybatis的主配置文件的scheme约束了每个标签的放置位置
例如 properties在settings前面
<?xml version="1.0" encoding="UTF-8" ?>
<!--Mybatis的主配置文件-->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--日志输出,选定的日志框架是STDOUT_LOGGING-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--表示使用的是哪个环境的数据源-->
<environments default="development">
<!--声明数据源的环境名称-->
<environment id="development">
<!--声明事务管理器
JDBC : 表示底层使用JDBC的connection对象的commit,rollback来管理事务
Managed : 表示使用容器或者是其他的框架来管理事务,例如以后大家学习了Spring,就可以把事务交给Spring框架来管理
-->
<transactionManager type="JDBC"/>
<!--表示底层使用的是PooledDatasource-->
<dataSource type="POOLED">
<!--底层使用数据库连接配置-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/z29th"/>
<property name="username" value="root"/>
<property name="password" value="root1234"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--把Mapper.xml注册到我们的Mybatis.xml文件中-->
<!--配置mapper文件的位置-->
<mapper resource="mapper.xml"/>
<!--<mapper resource="org/mybatis/example/BlogMapper.xml"/>-->
</mappers>
</configuration>
<properties>标签
可以把mybatis.xml里的数据库连接信息放到另一个配置文件jbdc.properties里,再通过properties标签导入jdbc.properties,再Mybatis.xml 中通过 `${key}` 从properties文件里面获取数据
原来是:
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/z29th"/>
<property name="username" value="root"/>
<property name="password" value="root1234"/>
现在变成这样
jdbc.properties文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/29_back2?useSSL=false&characterEncoding=utf8
username=root
password=123456
<TypeAlaises>标签
是用来给一些类起别名的
在Mybatis.xml这个文件中配置别名
方式一
原来的全限定类名叫com.User,现在叫user
在xml里面可以直接用别名
总体没什么用,增加代码阅读难度
方式二
PS:在Mybatis3.5.x的版本中,还支持使用注解的方式去起别名
<typeAliases>
<!-- 表示要到下面这个包路径下扫描,看有没有注解符号-->
<package name="com.a"/>
</typeAliases>
package包所在路径最少是二级目录,不然就会报错,只用了com文件夹就会出错
映射配置
怎么把xml注册到主配置文件里
方式一
用<mapper>标签
<mappers>
<mapper resource="com/UserMapper.xml"/>
<mapper resource="com/UserMapper1.xml"/>
</mappers>
方式二(mapper接口和映射文件必须同名)
报这个错误,可能就是mapper接口和映射文件名字不一样
<mappers>
<package name="com.pack"/>
</mappers>
可以把com文件夹下的所有xml配置进来
假如在有多个mapper.xml的情况下,第一种方式就需要配置多次,第二种方式就可以直接配置到包即可
日志配置
配置日志,配置完成以后可以查看mybatis执行的sql语句,帮助我们去排查错误
stdout_logging是标准日志输出
maven增强
如果不想在resources文件夹下创建mapper.xml,而是想在mapper接口同路径下创建映射文件,那么这个时候就可以在Maven的pom.xml配置文件的末尾增加如下内容
当目录结构是以下形式时
想让maven把xml文件也编译到target目录下
那么这个时候就可以在Maven的pom.xml配置文件的末尾增加如下内容
<!-- build表示编译 -->
<build>
<!-- resources表示编译的时候去哪里找资源文件-->
<resources>
<resource>
<directory>src/main/resources</directory>
<!-- 该路径下的所有文件都当成资源文件-->
<includes>
<!-- ** 表示通配 -->
<include>**</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<!-- 该路径下的任意级目录的任意xml文件当成资源文件-->
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
-------------------------------mybatis反向代理--------------------------------
上面的方法,每次发送sql都要选择sqlSession的方法类型,而且方法的参数只能传一个
而且上面方法在使用Mybatis 的时候,要手动指定了sql语句的地址(xml地址.sql语句的id),这样做其实是很不方便的。因为我们的Java编程,其实是面向接口编程。也就是我们在使用Mybatis的时候,应该去调用接口,而不是去直接写死SQL语句的地址,然后去调用。
如果有以下情况,就可以用接口代替原来mybatis用SQL语句的地址执行sql
- mapper.xml的namespace和我们的Mapper.java的全限定名称保持一致
- 我们Mappe.xml里面的<insert> <select> <update> <delete> 这些标签的id和我们接口里面方法的名称保持一致
- 我们接口方法的参数和返回值的类型要和我们Mapper.xml 里面的resultType以及ParamterType保持一致
自己实现反向代理,有如下操作
在Mapper.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">
<!--NameSpace 是这个Mapper.xml的身份标签-->
<mapper namespace="com.UseMapper">
<select id="selectList" resultType="com.User">
select * from user
</select>
</mapper>
对应的接口
package com;
import java.util.List;
public interface UseMapper {
List<User> selectList();
}
接口实现类
package com;
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;
import java.util.List;
public class UserMapperImpl implements UseMapper {
static SqlSession sqlSession;
static {
try {
// 需要去加载Mybatis,然后启动Mybatis,然后执行sql,获取结果
InputStream input = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
sqlSession = sqlSessionFactory.openSession();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public List<User> selectList() {
List<User> users = sqlSession.selectList("com.UseMapper.selectList");
return users;
}
}
调用接口
public class Test {
@org.junit.Test
public void test01() {
UseMapper userMapper = new UserMapperImpl();
List<User> users = userMapper.selectList();
System.out.println(users);
}
}
实际MyBatis不需要我们自己写实现类,满足条件后MyBatis会帮助生成代理对象(功能和自己写的实现类相似)
1.创建构建数据库操作Mapper.xml和Mapper接口
xml文件和接口名字要一样,一般叫XxMapper,Xx是根据业务需求自定
package com;
public interface UserMapper {
//希望最后结果封装到User对象里,where后面的id可以根据形参输入发生变化
User select(int id);
}
dao接口是用来规范对数据库进行操作的那条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 一定要叫对应接口的全限定类名-->
<mapper namespace="aaa">
<!--sql语句是select类型,标签用select,
id要和接口里的对应方法同名,
parameterType是方法的形参类型(可以不写)
resultType是返回值类型
#{}相当于预编译的占位符?-->
<select id="selectList" parameterType="java.lang.Integer" resultType="com.User">
select * from user where id = #{xx}
</select>
</mapper>
mapper映射文件用来写sql语句,以后修改sql语句只用修改映射文件,就不会对代码造成影响
parameterType可以不写
查询的时候resultType必须写
注意:mapper/dao接口和Mapper映射文件编译后必须在同一级目录下
所以文件的位置得这么放
如果直接把Mapper映射文件和Dao接口写在一起,maven编译时不会把Java目录下的xml识别到target目录下,如果想让maven编译的时候也去识别java目录中的xml文件需要做一些配置(以后再说怎么配置)
2、配置Mybatis的主配置文件
创建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">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!--dataSource的类型可以配置成其内置类型之一,如UNPOOLED、POOLED、JNDI。
UNPOOLED,mybaties会为每一个数据库操作创建一个新的连接,并关闭它。该方式适用于只有小规模数量并发用户的简单应用程序上。
POOLED,mybaties会创建一个数据库连接池,连接池的一个连接将会被用作数据库操作。一旦数据库操作完成,mybaties会将此连接返回给连接池。在开发或测试环境中经常用到此方式。
JNDI。mybaties会从在应用服务器向配置好的JNDI数据源DataSource获取数据库连接。在生产环境中优先考虑这种方式。-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/z29th"/>
<property name="username" value="root"/>
<property name="password" value="root1234"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 把上面的Mapper.xml 注册进来,路径写在resources目录下的路径-->
<mapper resource="com/UserMapper.xml"/>
</mappers>
</configuration>
3、使用
@org.junit.Test
public void test() throws IOException {
//加载mybatis的配置文件
InputStream input = User.class.getClassLoader().getResourceAsStream("mybatis.xml");
//或者用这种方法加载配置文件,Resources是mybatis自己提供的类
// InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
// 用建造者模式,创造 生产SqlSession的工厂(这个工厂的类型由配置文件决定)
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(input);
// 工厂生产Sqlsession
SqlSession sqlSession = factory.openSession();
//执行sql,根据sql的类型选择是用select、insert、delete、update方法执行sql
//如果要修改数据库,最后要执行sqlSession.commit(),因为mybatis默认开启事务
// selectOne有两个重载方法,一参和二参(二参的是在sql语句里多了一个可变参数)
UseMapper mapper = sqlSession.getMapper(UseMapper.class);
List<User> users = mapper.selectList();
System.out.println(zs);
//关闭IO资源(工厂对象会自动回收)
input.close();
sqlSession.close();
}
UseMapper mapper = sqlSession.getMapper(UseMapper.class);
List<User> users = mapper.selectList();
这两句代码底层就是使用mybatis的第一种方式
- 命名空间=直接通过反射获取接口类的全限定名称
- sql的Id=通过反射获取到方法名
- 假如方法是返回参数是一个List,那么就会使用sqlSession的selectList方法 *(就是底层会帮你自动选择调用sqlSession的哪个方法)
- 假如是一个Integer或者是一个其他类型的参数,那么就去查看mapper配置文件中的标签,来判断是什么返回类型