—cache –命名空间的二级缓存配置
—cache-ref – 其他命名空间缓存配置的引用。
—resultMap – 自定义结果集映射
—parameterMap – 已废弃!老式风格的参数映射,原本是做复杂参数映射的
—sql –抽取可重用语句块。
—insert – 映射插入语句
—update – 映射更新语句
—delete – 映射删除语句
—select – 映射查询语句
[
](https://blog.csdn.net/qq_43284469/article/details/111287911)
3.1 增删改标签
—insert – 映射插入语句
—update – 映射更新语句
—delete – 映射删除语句
id要对应实现的方法名
<select id="getEmpById" resultType="com.achang.bean.Employee" >
select * from t_employee where id = #{id}
</select>
数据库支持主键:
dao.xml
</select>
<!--让MyBatis自动的将自增的id赋值给传入的employee对象的id属性
useGeneratedKeys属性:开启自动赋值id功能
keyProperty属性:将刚才自增的id封装给那个属性
-->
<insert id="insertEmp" useGeneratedKeys="true" keyProperty="id">
insert into t_employee(empname,gender,email)values(#{empName},#{gender},#{email})
</insert>
bean对象
public class Employee {
private Integer id;
private String empName;
private Integer gender;
private String email;
private String loginAccount;
}
EmployeeDao.java
public int insertEmployee(Employee employee);
测试
@Test
public void test02() {
SqlSession openSession = sessionFactory.openSession();
try {
Employee employee = new Employee(null, "hahaha", "haha@qq.com", 1,"o" );
EmployeeDao employeeDao = openSession.getMapper(EmployeeDao.class);
// int i = employeeDao.insertEmployee(employee);
int i = employeeDao.insertEmployee2(employee);
System.out.println("--->" + i);
System.out.println("刚才插入的id:" + employee.getId());
} finally {
openSession.commit();
openSession.close();
}
}
数据库没有主键:selectKey
通过order属性设置运行顺序,keyProperty属性来设置查询后结果赋值给javabean的哪个对象
然后通过useGeneratedKeys属性设置打开获取主键,keyProperty属性设置javabean的id属性接收结果值
3.2 参数(Parameters)传递
1、单个参数
基本类型:
取值:#{随便写}
2、多个参数:
取值:#{参数名}是无效的的
0,1(参数索引)或者param1,param2(第几个参数paramN)
原因:
只要传入多个参数,mybatis会自动的将这些参数封装到一个map中;封装时使用的key就是参数的索引和参数的第几个标识
@param:为参数指定封装map时的key;命名参数
我们可以告诉mybatis,封装参数map的时候别乱来
3、传入map
封装多个参数为map,直接传递
4、传入bean
取值:#{bean属性名}
public Employee getEmpByIdAndEmployee(@Param("id")Integer id,@Param("empname")String empName);
3.3 设置参数规则
#{}和¥{}的区别
•实际上通常被设置的是:
可能为空的列名指定 jdbcType
•#{key}:获取参数的值,预编译到SQL中。安全。
•${key}:获取参数的值,拼接到SQL中。有SQL注入问题。ORDER BY ${name}
3.4 查询返回List
EmployeeDao:
public interface EmployeeDao {
public List<Employee> getAllEmps();
}
dao.xml
<!--resultType:如果返回的是集合,写的是集合里面元素的类型-->
<select id="getAllEmps" resultType="com.achang.bean.Employee">
select * from t_employee
</select>
test
@Test
public void test3(){
SqlSession sqlSession = factory.openSession();
EmployeeDao mapper = sqlSession.getMapper(EmployeeDao.class);
List<Employee> allEmps = mapper.getAllEmps();
for (Employee employee:allEmps){
System.out.println(employee);
}
3.5 查询返回Map
1、单条记录返回Map
dao
public interface EmployeeDao {
/****
* 列名为Key,值为value
*/
public Map<String,Object> getEmpByIdReturnMap(Integer id);
}
dao.xml
resultType属性中的map已经被mybatis自动写入别名为map了
<select id="getEmpByIdReturnMap" resultType="map">
select * from t_employee where id = #{id}
</select>
test
@Test
public void test4(){
SqlSession sqlSession = factory.openSession();
EmployeeDao mapper = sqlSession.getMapper(EmployeeDao.class);
Map<String, Object> empByIdReturnMap = mapper.getEmpByIdReturnMap(3);
System.out.println(empByIdReturnMap);//{empname=欧尼, gender=1, id=3, login_account=b, email=achang@qq.com}
}
2、多条记录返回Map
通过@MapKey()注解来告诉mybatis数据库中哪个字段作为key主键来,封装value
dao
public interface EmployeeDao {
//key是记录的主键,value就是记录封装好的对象
//@MapKey根据数据库里面的哪个字段作为key来查询封装value
@MapKey("id")
public Map<Integer,Employee> getEmpsByIdReturnMap();
}
dao.xml
<!--查询多个的情况下,resultType属性写value封装的元素类型-->
<select id="getEmpsByIdReturnMap" resultType="com.achang.bean.Employee">
select * from t_employee
</select>
test
@Test
public void test5(){
SqlSession sqlSession = factory.openSession();
EmployeeDao mapper = sqlSession.getMapper(EmployeeDao.class);
Map<Integer, Employee> empsByIdReturnMap = mapper.getEmpsByIdReturnMap();
System.out.println(empsByIdReturnMap);
}
3.6 自定义封装规则resultMap
reesultMap标签自定义封装
type属性:指定引入哪个javabaen与数据库封装对应
id属性:指定这个自定义封装的id,便于其他引用
id标签:指定主键
result标签:指定其他封装对象
property属性:指定javabean属性名
column属性:指定数据库字段名
通过resultMap属性引用那个自定义封装规则的id
3.7 联合查询
1、级联查询
- sql语句
``xml SELECT k.id,k.
keyname,k.
lockId,l.
idlid,l.
lockNameFROM t_key k LEFT JOIN t_lock l ON k.
lockId=l.
idWHERE k.
id`=1
![image.png](https://cdn.nlark.com/yuque/0/2021/png/2963105/1630847234584-bf783721-428f-45f5-a194-56f9078b7b3e.png#clientId=u20aa6144-6710-4&from=paste&height=91&id=u1c484e42&margin=%5Bobject%20Object%5D&name=image.png&originHeight=91&originWidth=525&originalType=binary&ratio=1&size=4670&status=done&style=none&taskId=u015cf15b-949e-49fa-99ae-2bc15a2e442&width=525)
- bean对象
```java
public class Lock {
private Integer id;//锁编号
private String LockName;//锁名
//省略get/set/toString/构造器
}
public class Key {
private Integer id;//钥匙编号
private String keyName;//钥匙名
private Lock lock;//当前钥匙能开哪把锁
//省略get/set/toString/构造器
}
- keyDao ```java public interface keyDao { //将钥匙和锁信息一起查出 public Key getKeyById(Integer id); }
- mybatis_config.xml
```xml
<mappers>
<mapper resource="keyDao.xml"/>
<mapper resource="EmployeeDao.xml"/>
</mappers>
- keyDao.xml
```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">
- test
```java
public class EmployeeDaoTest {
SqlSessionFactory factory;
@Before
public void initSqlSessionFactory() throws IOException {
String resource = "mybatis_config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
factory = new SqlSessionFactoryBuilder().build(inputStream);
}
//keyDao测试
@Test
public void test6(){
SqlSession sqlSession = factory.openSession();
keyDao mapper = sqlSession.getMapper(keyDao.class);
Key keyById = mapper.getKeyById(2);
System.out.println(keyById);
//Key{id=1, keyName='1号钥匙', lock=Lock{id=1, LockName='null'}}
}
}
2、联合查询association
下面的其他配置同上
用来自定义封装规则中,再次套娃封装bean对象属性里面的对象,若属性里面对象的属性还是对象可继续套娃封装
简单来说就是在一个javabean里面有一个属性是自定义javabean就推荐用
keyDao.xml ```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">
- test
```java
public class EmployeeDaoTest {
SqlSessionFactory factory;
@Before
public void initSqlSessionFactory() throws IOException {
String resource = "mybatis_config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
factory = new SqlSessionFactoryBuilder().build(inputStream);
}
//keyDao测试
@Test
public void test6(){
SqlSession sqlSession = factory.openSession();
keyDao mapper = sqlSession.getMapper(keyDao.class);
Key keyById = mapper.getKeyById(2);
System.out.println(keyById);
//Key{id=1, keyName='1号钥匙', lock=Lock{id=1, LockName='1号锁'}}
}
}
3、Collection查询
在一个javabean有集合属性就推荐用
- sql
``xml SELECT k.id,k.
keyname,k.
lockId,l.
idlid,l.
lockNameFROM t_key k LEFT JOIN t_lock l ON k.
lockId=l.
idWHERE k.
id`=3
![image.png](https://cdn.nlark.com/yuque/0/2021/png/2963105/1630847668306-c984c5db-dae5-4c2c-967a-9e654fafe320.png#clientId=u20aa6144-6710-4&from=paste&height=168&id=u557a080e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=168&originWidth=675&originalType=binary&ratio=1&size=69686&status=done&style=none&taskId=u42369c58-6842-4980-b24b-58f276d851e&width=675)
- bean对象
```java
public class Lock {
private Integer id;//锁编号
private String LockName;//锁名
private List<Key> keys//很多把钥匙可以开这把锁
//省略get/set/toString/构造器
}
public class Key {
private Integer id;//钥匙编号
private String keyName;//钥匙名
private Lock lock;//当前钥匙能开哪把锁
//省略get/set/toString/构造器
}
LockDao.xml ```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">
- test
```java
public class EmployeeDaoTest {
SqlSessionFactory factory;
@Before
public void initSqlSessionFactory() throws IOException {
String resource = "mybatis_config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
factory = new SqlSessionFactoryBuilder().build(inputStream);
}
//LockDao测试
@Test
public void test7(){
SqlSession sqlSession = factory.openSession();
keyDao mapper = sqlSession.getMapper(keyDao.class);
Lock lockById = mapper.getLockById(3);
System.out.println(keyById);
//lock对象为null是因为没自定义配置association;需要则可以在resultMap中继续配置association来继续套娃
//Key{id=3, keyName='303号钥匙1', lock=null}
// Key{id=4, keyName='303号钥匙2', lock=null}
// Key{id=5, keyName='303号钥匙3', lock=null}
}
}
3.8 分步查询【不推荐】
虽然sql简单,但是会有大量性能浪费,虽然可以用过设置来减少性能浪费,但还是不推荐使用!!!
1、association-分段查询
select:调用目标的方法查询当前属性的值【方法全类名】,即额外使用一条查询语句查询该属性
column:传入select调用的方法需要的参数,t_key表里面带有lockid
2、association-分段查询&延迟加载
开启延迟加载和属性按需加载
例如:只查钥匙则不会执行查锁子的查询语句
lazy为设置延迟加载,eager则相反
- 旧版本的MyBatis需要额外的支持包
–asm-3.3.1.jar
–cglib-2.2.2.jar