目录
MyBatis中主要的类
1、Resources
:负责读取主配置文件
//定义主配置文件名
String config = "mybatis.xml";
//获取输入流,将主配置文件输入程序
InputStream in = null;
try {
in = Resources.getResourceAsStream(config);
} catch (IOException e) {
e.printStackTrace();
}
2、SqlSessionFactoryBuilder
:负责获取 SqlSessionFactory
对象
//创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
3、SqlSessionFactory
:作用: 获取SqlSession
对象
重量级对象:指 程序创建这个对象耗时较长、消耗资源较多,在整个项目中,有一个就够了
其本身是一个接口:默认实现类为DefaultSqlSessionFactory
//创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
//*获取SqlSession对象,从SqlSessionFactory中获取sqlSession
SqlSession sqlSession = factory.openSession();
openSession()
方法:无参表示获取的是非自动提交事务的对象
openSession(true)
:则是获取自动提交事务的对象,false也是获取的是非自动提交事务的对象
4、SqlSession
:作用是执行各种操作数据库的方法
其本身是一个接口,其中定义了增删查改、提交事务、回滚等操作数据库的方法
他的默认实现类是DefaultSqlSession
使用要求:SqlSession
不是线程安全的,需要在方法内部使用,在执行sql语句前使用openSession()
方法获取,使用完必后用sqlSession.close();
关闭
Mybatis工具类
package org.example.utils;
import org.apache.ibatis.annotations.Result;
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 MybatisUtil {
private static SqlSessionFactory factory = null;
static {
String config = "mybatis.xml";
try {
InputStream inputStream = Resources.getResourceAsStream(config);
factory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
SqlSession sqlSession = null;
if (factory != null){
sqlSession = factory.openSession();
}
return sqlSession;
}
}
实现dao接口操作数据库
首先在dao包下创建一个impl包,在其中编写对dao接口的实现类。
package org.example.dao.impl;
import org.apache.ibatis.session.SqlSession;
import org.example.dao.UserDao;
import org.example.domain.User;
import org.example.utils.MybatisUtil;
import java.util.List;
public class UserDaoImpl implements UserDao {
@Override
public List<User> selectUsers() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
String sqlId = "org.example.dao.UserDao.selectUsers";
List<User> users = sqlSession.selectList(sqlId);
sqlSession.close();
return users;
}
@Override
public int insertUser(User user) {
SqlSession sqlSession = MybatisUtil.getSqlSession();
String sqlId = "org.example.dao.UserDao.insertUser";
int insert = sqlSession.insert(sqlId, user);
sqlSession.commit();
sqlSession.close();
return insert;
}
}
之后再调用其方法就可以了
@Test
public void testSelectUser(){
UserDaoImpl userDao = new UserDaoImpl();
List<User> userList = userDao.selectUsers();
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void testInsertUserImpl(){
UserDaoImpl userDao = new UserDaoImpl();
User user = new User();
user.setName("孙八");
user.setPwd("12312");
int i = userDao.insertUser(user);
System.out.println(i);
}
动态代理
概述
mybatis根据dao的方法调用,获取执行sql语句的信息。
mybatis根据你的dao接口,创建出一个dao接口的实现类,并创建其对象
完成SQLSession调用方法,访问数据库。
**也就是说,你只需要编写数据库操作接口,而实现和创建对象的工作交给mybatis去做即可。**mybatis是通过方法的返回值来判断调用的是什么方法(查询、插入…)
使用
@Test
public void testSelectUser(){
//使用动态代理的方式操作数据库
SqlSession sqlSession = MybatisUtil.getSqlSession();
//通过getMapper获取对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> userList = userDao.selectUsers();
System.out.println(userList);
}
向sql语句中传参
传入一个简单参数
简单参数:java中的基本数据类型(包括其包装类)和String
在接口中加入相应的方法
public User selectUserById(Integer id);
配置sql mapper
<!--
parameterType="" 告诉mybatis传入的值的类型
它的值是java数据类型全限定名称,或者是mybatis定义的别名
如:parameterType="java.lang.Integer"、parameterType="int"
注意:它不是强制的,mybatis可以通过反射机制获取,所以可以没有,一般我们也不写。
在mapper文件中获取简单类型的参数值,用 #{任意字符}
-->
<select id="selectUserById" parameterType="java.lang.Integer" resultType="org.example.domain.User">
select * from user where id=#{id}
</select>
动态代理操作数据库
@Test
public void testSelectUserById(){
//使用动态代理的方式操作数据库
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = userDao.selectUserById(1);
System.out.println(user);
}
相对应的 jdbc 操作
使用#{ } 之后,mybatis执行sql是使用的JDBC中的PreparedStatement
对象
由mybatis执行以下代码:
//mybatis创建Connection、PreparedStatement 对象
String sql = "select * from user where id=?" //每一个#{ } 都会变成?占位符
ps = conn.prepareStatement(sql);
ps.setInt(1, id);
rs = ps.executeQuery();
//执行sql,封装结果集为 resultType="org.example.domain.User"
User user = null;
while ( rs .next()){
user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setPwd(rs.getString("pwd"));
}
return user;
多个参数
注解:@Param
多个简单参数,推荐使用这种方式
首先在接口方法的参数前使用:@Param("name") String name
然后在mapper的sql语句中用 #{ name }使用
public User login(@Param("name") String name, @Param("pwd") String pwd);
<select id="login" resultType="org.example.domain.User">
select * from user where name=#{name} and pwd=#{pwd}
</select>
@Test
public void testLogin(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
User login = userDao.login("ls", "123");
System.out.println(login);
sqlSession.close();
}
使用对象封装
即使用一个封装的对象作为方法参数,对象其中的属性作为查询的条件
在sql mapper中使用#{name,javaType=java.lang.String,jdbcType=VARCHAR}
表示参数
javaType:是在java实体类中,这个属性的类型。
jdbcType:是在数据库中这个字段的类型。
public User login(User user);
<select id="login" resultType="org.example.domain.User">
select * from user
where name=#{name,javaType=java.lang.String,jdbcType=VARCHAR}
and pwd=#{pwd,javaType=java.lang.String,jdbcType=VARCHAR}
</select>
当然,上面哪种方式显然很麻烦,太长了,所以mybatis简化了这一操作:
只需要提供#{ 属性名 } 即可,javaType、jdbcType,mybatis可以通过反射获取。
<select id="login" resultType="org.example.domain.User">
select * from user
where name=#{name} and pwd=#{pwd}
</select>
@Test
public void testLogin(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = new User();
user.setName("ls");
user.setPwd("123");
User login = userDao.login(user);
System.out.println(login);
sqlSession.close();
}
按参数位置
参数位置从0开始,使用#{ arg位置 },表示参数占位
注意:mybatis从3.4版本开始使用{arg0}这种方式,之前使用的是{0}、{1}。
<select id="login" resultType="org.example.domain.User">
select * from user
where name=#{arg0} and pwd=#{arg1}
</select>
使用Map传值
#{ map中的key }
占位符#和$
#用的是PreparedStatement:最终执行是使用的?代替#{ }
$用的是Statement:直接拼接字符串。因此可以用来替换列名…,比如有时需要以id排序,有时需要以name