使用的sql:
SELECT * FROM `user` WHERE id = 1
在user.xml中添加select标签,编写sql:
测试程序步骤:
1. 创建SqlSessionFactoryBuilder对象
2. 加载SqlMapConfig.xml配置文件
3. 创建SqlSessionFactory对象
4. 创建SqlSession对象
5. 执行SqlSession对象执行查询,获取结果User
6. 打印结果
7. 释放资源
public class MybatisTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void before() throws Exception {
// 1. 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 2. 加载SqlMapConfig.xml配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 3. 创建SqlSessionFactory对象
this.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
}
@Test
public void testQueryUserById() throws Exception {
// 4. 创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 5. 执行SqlSession对象执行查询,获取结果User
// 第一个参数是User.xml的statement的id,第二个参数是执行sql需要的参数;
Object user = sqlSession.selectOne("test.queryUserById", 1);
// 6. 打印结果
System.out.println(user);
// 7. 释放资源
sqlSession.close();
}
}
查询sql:
SELECT * FROM `user` WHERE username LIKE '%马%'
user.xml配置
测试
@Test
public void testQueryUserByUsername() throws Exception {
// 4. 创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 5. 执行SqlSession对象执行查询,获取结果User
// 查询多条数据使用selectList方法
List
#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。
parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。
resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中
selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常
若是增删改的操作必须提交事务
增加用户
insert into t_user (name,sex,address,balance)
values (#{name},#{sex},#{address},#{balance})
-测试
@Test
public void testSaveUser() {
// 4. 创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 5. 执行SqlSession对象执行保存
// 创建需要保存的User
User user = new User();
user.setName("张飞");
user.setSex("1");
user.setAddress("蜀国");
sqlSession.insert("test.addUser", user);
System.out.println(user);
// 需要进行事务提交
sqlSession.commit();
// 7. 释放资源
sqlSession.close();
}
修改用户
update t_user
set name = #{name},sex = #{sex},address = #{address},balance=#{balance},companyId=#{companyId}
where id = #{id}
测试
@Test
public void testUpdateUserById() {
// 4. 创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 5. 执行SqlSession对象执行更新
// 创建需要更新的User
User user = new User();
user.setId(26);
user.setName("关羽");
user.setSex("1");
user.setAddress("蜀国");
sqlSession.update("test.updateUser", user);
// 需要进行事务提交
sqlSession.commit();
// 7. 释放资源
sqlSession.close();
}
删除用户
delete from t_user
where id = #{superman}
测试
@Test
public void testDeleteUserById() {
// 4. 创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 5. 执行SqlSession对象执行删除
sqlSession.delete("test.delUser", 48);
// 需要进行事务提交
sqlSession.commit();
// 7. 释放资源
sqlSession.close();
}
Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句。mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。
Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。
Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。
总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。
sqlSessionFactoryBuilder 读取配置文件 调用build方法
SqlSessionFactory 创建 sqlsession
Sqlsession 封装方法(每次都打开一个新的session)
Dao依赖于sqlSessionFactory
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User selectUserById(Integer id) {
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession.selectOne("test.selectUserById",id);
}
前提条件
接口名字 建议与 配置文件名字保持一致
注意事项:方法中的参数就只能有一个
Selectone 与 selectList根据,mapper的返回值类型决定
配置文件属性顺序必须如上图一致
TypeAliases 别名
Typehandlers 类型处理器
实现jdbc(数据库中的类型)和java类型的转换,一般不用自己去改,特殊情况下需要自己手动映射。
Properties 设置属性
Settings mybatis功能的设置
普通类型
使用#{}占位符,或者${}进行sql拼接。
使用pojo类型
Mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性名称。
Pojo包装类 既包含普通类型也包含其他类型
包装对象:Pojo类中的一个属性是另外一个pojo。
ResultType
自动装换(属性名 与数据库字段名一致)
ResultMap
手动转换 ,如果名字不一致则需要手动映射
ResultMap: type 将要转换的类型
Id:主键 property实体类的属性名 column 数据库列的字段名
result 普通属性
If标签
AND id =#{id}
AND name =#{name}
Test 使用ognl表达式的方式取值,可以if条件 并且and 或者 or
如果有多个条件,不知道是第一个成立and的位置不好放,放在任何一个位置都有可能有异常,使用where标签解决
Where标签 (自动去除前and)
若所有条件都不成立,那么where标签就去除
Foreach标签
#{id}
Collection 识别数据类型
数组:array set集合:set
List集合:list 封装类:必须是封装类的属性名
Index 下标
SQL片段
id, username, birthday, sex, address
SELECT FROM `user`
Include refid 属性对应的就是 SQL片段的id名
实现一对一查询的结果集封装
两种办法:
ResultType
新建一个实体类,这个实体类包含所有转换的列名
可以建一个类,让这个类去继承一个类
resultMap
在user实体类中增加一个引用类的属性,并添加get-set方法,在结果集处理时采用
resultMap
若字段名和属性不写转换,就不会转化,要想将查询到的结果全部封装到实体类中,就必须全部都写
ResultType(不建议使用)
新建一个实体类,这个实体类包含所有转换的列名
可以建一个类,让这个类去继承一个类
ResultMap
添加属性 并添加get-set方法
Collection property实体类的属性名,javaType(集合list set)
ofType 封装集合中每个元素的类型
(以下三种技术 可了解)
缓存(Redis memache)
延迟加载
逆向工程,通过一方生成另一方