Mybatis是一个应用于dao层框架(持久层框架)。持久层:数据访问层。
他也是一个ORM框架(对象 关系 映射),相比于hibernate,他是一个半自动的框架。
重复工作多,每次都要创建连接(连接池),获得执行sql语句的对象,执行sql语句,然后处理结果集,最后释放资源。
为处理结果集,工作非常复杂,参数的处理比较麻烦。
让程序员关注sql语句。
参数的设置,结果集的处理,框架自动帮你生成。
简单易学。
灵活。
sqlMapConfig.xml
① .导入约束
PUBLIC "-//mybatis.org//DTDConfig 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
② .配置内容
PUBLIC "-//mybatis.org//DTDMapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
SELECT * FROM t_user WHERE id= #{id}
SELECT * FROM t_user WHEREusername LIKE "%"#{username}"%"
SELECT LAST_INSERT_ID()
INSERT INTOt_user(name,sex,address,balance) VALUES (#{name},#{sex},#{address},#{balance})
DELETE FROM t_user WHERE id = #{id}
UPDATE t_user SET name = #{name}WHERE id = #{id}
# Global logging configuration
#在开发环境下日志级别设置为debug,生产环境下设置成info或error
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
1.SqlMapConfig
命名可以修改,位置任意。当然我们建议的名字是SqlMapConfig,位置放在目录下。
(1).environments
表示SqlMapConfig的运行环境。
数据库的基本信息,事务。
(3).mppers
表示数据源。
2.UserMapper.xml
名字可以修改,位置任意。
名字建议User.xml(ibatis) UserMpper.xml(Mybatis)我们建议命名为类名+Mapper.xml
所有的sql语句都写在USerMaper中。
mapper的namespace属性
解决在不同表中查询的sql语句的名字冲突,比如:
User表 findById order表 findById名字冲突,不识别,所以可以给不同的表的数据源加上一个前缀,对应的是namespace属性。
SELECT* FROM t_user WHERE id = #{id}
id 给当前的sql语句起一个识别id,parameterType:参数类型
resultType:结果集封装的类型。
#{id}:占位符 里面对的名字任意
简单实用的Mybatis的增删改查
SELECT * FROM t_user WHERE id= #{id}
测试代码
@Test
public voidfun1() throws IOException {
InputStream in =Resources.getResourceAsStream("sqlMapConfig.xml");
/*获得SessionFactory,读取流*/
SqlSessionFactory sessionFactory =new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession =sessionFactory.openSession();
User user =sqlSession.selectOne("test.findUserById", 1);
System.out.println(user);
sqlSession.close();
}
测试代码
@Test
public void fun2() throws IOException {
InputStream in =Resources.getResourceAsStream("sqlMapConfig.xml");
/*获得SessionFactory,读取流*/
SqlSessionFactory sessionFactory =new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession =sessionFactory.openSession();
List
System.out.println(list);
sqlSession.close();
}
INSERT INTOt_user(name,sex,address,balance) VALUES (#{name},#{sex},#{address},#{balance})
测试代码
@Test
public void fun3() throws IOException {
InputStream in =Resources.getResourceAsStream("sqlMapConfig.xml");
/*获得SessionFactory,读取流*/
SqlSessionFactory sessionFactory =new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession =sessionFactory.openSession();
User user = new User();
user.setName("杨二狗");
user.setAddress("坑");
user.setSex("nv");
user.setBalance(1000);
int insert =sqlSession.insert("test.addUser", user);
System.out.println(insert);
sqlSession.commit();
System.out.println(insert);
sqlSession.close();
}
这种操作并不会把新生成的记录中的主键保存到对象中,但是有一种需求,在保存用户的同时,要利用用户主键去保存一条新的记录。所以为满足该需求,提供了新的标签。
keyProperty:将查询到主键设置到parameterType指定的对象的哪个属性
order:SELECTLAST_INSERT_ID()的执行顺序,相对于insert语句来说他的执行顺序。
-->
SELECT LAST_INSERT_ID()
INSERT INTOt_user(name,sex,address,balance) VALUES (#{name},#{sex},#{address},#{balance})
keyProperty:对应的是对象中的属性名KeyCloumn对应的是数据库中的字段名。
resultType:对应的是返回值结果类型(intString)分别对应数据库生成代理主键的策略。Int 对应自动递增,String对应uuid。
order 顺序跟数据库底层有关,自动递增默认先添加数据,再生成主键 。但是uuid就是先生成id再去添加数据。
如果是增删改,必须要提交事务才能持久化到数据库。
SELECT LAST_INSERT_ID()适用于自动递增。
SELECT uuid() 适用于uuid。通过id删除用户
4.通过id删除用户
DELETE FROM t_user WHERE id =#{id}
测试代码
@Test
public void fun4() throws IOException {
InputStream in =Resources.getResourceAsStream("sqlMapConfig.xml");
/*获得SessionFactory,读取流*/
SqlSessionFactory sessionFactory =new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession =sessionFactory.openSession();
int delete =sqlSession.delete("test.deleteUser", 5);
sqlSession.commit();
System.out.println(delete);
sqlSession.close();
}
UPDATEt_user SET name = #{name},sex = #{sex},address = #{address},balance=#{balance}WHERE id = #{id}
测试代码
@Test
public void fun5() throws IOException {
InputStream in =Resources.getResourceAsStream("sqlMapConfig.xml");
/*获得SessionFactory,读取流*/
SqlSessionFactory sessionFactory =new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession =sessionFactory.openSession();
User user = new User();
user.setId(8);
user.setName("杨二狗");
user.setAddress("水");
user.setSex("男");
user.setBalance(1000);
int update =sqlSession.update("test.updateUser", user);
sqlSession.commit();
System.out.println(update);
sqlSession.close();
}
原始dao层开发
package cn.hd.dao.impl;
import cn.hd.dao.UserDao;
import cn.hd.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactorysqlSessionFactory) {
this.sqlSessionFactory =sqlSessionFactory;
}
@Override
public User findUserById(Integer id){
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.findUserById",1);
sqlSession.commit();
sqlSession.close();
return user;
}
@Override
public Integer addUser(User user) {
SqlSession sqlSession = sqlSessionFactory.openSession();
int insert = sqlSession.insert("test.addUser",user);
sqlSession.commit();
sqlSession.close();
return insert;
}
@Override
public Integer deleteUser(Integer id){
return null;
}
}
测试代码
package cn.hd.dao;
import cn.hd.dao.UserDao;
import cn.hd.dao.impl.UserDaoImpl;
import cn.hd.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class Demo {
private UserDao userDao;
@Before
public void before() throws IOException{
InputStream in = Resources.getResourceAsStream("cn/hd/mapper/sqlMapConfig.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(in);
userDao = new UserDaoImpl(build);
}
@Test
public void fun1(){
User userById = userDao.findUserById(1);
System.out.println(userById);
}
}
dao层的mapper开发
不用去写实现类,他会使用代理的方式自动生成实现代码,想要使用mapper开发,必须遵循以下原则:
1、 接口的名字建议和mapper映射文件的名字保持一致,并且在同一目录下。
namespace必须和接口的完整路径名保持一致。
2、 接口中的方法名必须和mapper中的id保持一致。
3、 方法的返回值和配置文件中的resultType保持一致。
4、 参数的类型必须保持一致。
在代码中,就不需要关注SqlSession对象的方法调用了insert、update、delete、selectOne、selectList
sqlSession.getMapper(UserMapper.class);
返回一个接口的代理对象,直接调用该对象的方法即可。
@Test
public void fun1() throws IOException {
InputStream in =Resources.getResourceAsStream("cn/hd/dao/sqlMapConfig.xml");
SqlSessionFactory build = newSqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = build.openSession();
UserMapper mapper =sqlSession.getMapper(UserMapper.class);
User userById =mapper.findUserById(1);
System.out.println(userById);
}
注意:使用mapper开发,它的参数永远只有一个,如果有多个参数,需要将多的参数封装成pojo类。
Mybatis自动识别接口中的方法的返回值,从而调用session.selectOne和selectList方法。
SqlMapConfig配置详解
配置文件中的属性顺序不能更改。
设置配置信息
全局设置 mybatis的二级缓存 设置mybatis的加载属性。
3、 typeAliases
别名
决定着mapper.xml文件中的数据类型可以使用简短的名字。
类型控制器,将数据库中的数据类型和Java中的数据类型进行匹配。一般情况下不需要我们去书写。
• objectFactory
• plugins
• environments
• environment
• transactionManager
• dataSource
• databaseIdProvider
• mappers
映射文件,书写方式一共有四种。
1、mapper
2、通过接口来读取配置文件
①.接口的名字必须和配置文件保持一致
②.接口和配置文件必须在同一目录下
3、通过绝对路径来读取
4、读取的是接口的包名,因此要求多有的接口和对应的配置文件都要保持一致(名字和位置)
总结:推荐使用的第四种,你的接口和配置文件同名且在同一个包下。