MyBatis-映射文件
MyBatis 的真正强大在于它的语句映射,这是它的魔力所在
映射文件指导着Mybatis如何进行数据库CRUD,有着非常重要的意义
cache-命名空间的二级缓存配置
cache-ref-其他命名空间缓存配置的引用
resultMap-自定义结果集映射
sql抽取可重用语句块
insert -映射插入语句
update-映射更新语句
delete -映射删除语句
select-映射查询语句
SQL映射文件一般命名为接口名+Mapper
如EmployeeMapper、EmployeeMapperpro、EmployeeMapperpromax
下面我们来分别介绍sql映射文件中的这些元素~
增删改查元素
这里值得一提的是,获取到的openSession不会自动提交
因为openSession不会自动提交事务,对数据库进行修改操作后,要手动提交事务
==sqlSession.commit();==
1、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> <!--读取外部properties配置文件--> <properties resource="jdbc.properties"></properties> <!-- <settings>--> <!-- <setting name="logImpl" value="LOG4J"/>--> <!-- </settings>--> <!--数据源--> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments> <!--映射文件扫描包路径--> <mappers> <package name="com.caq.study.mapper"></package> </mappers> </configuration>
2、jdbc配置文件
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/heima_ssm?useSSL=false jdbc.username=root jdbc.password=root
3、mapper接口
package com.caq.study.mapper; import com.caq.study.entity.Account; public interface AccountMapper { // 查询 Account selectById(Integer id); // 增加 boolean save(Account account); boolean updateById(Account account); boolean deleteById(Integer id); }
4、mapper映射文件
useGeneratedKeys="true",使用自增主键获取主键值策略 keyProperty,指定对应的生键属性,也就是mybatis获取到主键值以后,将这个值封装给javaBean的对应字段
<?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"> <mapper namespace="com.caq.study.mapper.AccountMapper"> <insert id="save" parameterType="com.caq.study.entity.Account" useGeneratedKeys="true" keyProperty="id"> insert into account(name, money) values (#{name}, #{money}) </insert> <update id="updateById"> update account set name=#{name}, money=#{money} where id = #{id} </update> <delete id="deleteById"> delete from `account` where id = #{id} </delete> <select id="selectById" resultType="com.caq.study.entity.Account"> select * from account where id = #{id} </select> </mapper>
5、测试
public class demo { public static SqlSessionFactory getSqlSessionFactory() throws IOException { // 1. 创建SqlSessionFactoryBuilder对象 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); // 2. 加载SqlMapConfig.xml配置文件 InputStream inputStream = Resources.getResourceAsStream("MybatisConfig.xml"); // 3. 创建SqlSessionFactory对象 SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream); return sqlSessionFactory; } @Test public void testSave() throws IOException { //这里获取的sqlsession不会自动提交 SqlSession sqlSession = getSqlSessionFactory().openSession(true); AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class); Account account = new Account(); account.setName("test1"); account.setMoney("5000"); boolean save = accountMapper.save(account); System.out.println(save); sqlSession.commit(); sqlSession.close(); } @Test public void testSelect() throws IOException { SqlSession sqlSession = getSqlSessionFactory().openSession(); AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class); Account account = accountMapper.selectById(1); System.out.println(account); sqlSession.close(); } @Test public void testDelete() throws IOException { SqlSession sqlSession = getSqlSessionFactory().openSession(); AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class); boolean account = accountMapper.deleteById(8); System.out.println(account); sqlSession.commit(); sqlSession.close(); } @Test public void testUpdate() throws IOException { SqlSession sqlSession = getSqlSessionFactory().openSession(); AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class); Account account = new Account(); account.setId(9); account.setName("test1"); account.setMoney("7000"); accountMapper.updateById(account); System.out.println(account); sqlSession.commit(); sqlSession.close(); } }
参数处理
参数位置支持的属性
javaType、jdbcType、mode、numericScale、resultMap、typeHandler、jdbcTypeName
实际上通常被设置的是∶
可能为空的列名指定jdbcType
#{key}:获取参数的值,预编译到SQL中。安全。
key:获取参数的值,拼接到SQL中。有SQL注入问题。ORDERBY{key}:获取参数的值,拼接到SQL中。有SQL注入问题。ORDER BY key:获取参数的值,拼接到SQL中。有SQL注入问题。ORDERBY{name}
大多数情况选择#{key}的方式来获取参数的值
联合查询:级联属型封装结果集
<resultMap id="MyEmpPlus" type="com.caq.mybatis.bean.Employee"> <id column="id" property="id"/> <result column="last_name" property="lastName"/> <result column="gender" property="gender"/> <result column="did" property="dept.id"/> <result column="dept_name" property="dept.departmentName"/> </resultMap> <select id="getEmpAndDept" resultMap="MyEmpPlus"> SELECT e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,d.id did,d.dept_name dept_name FROM tbl_employee e,tbl_dept d where e.d_id = d.id and e.id = 1 </select>
上述方式的确可以解决这个问题
但是你看它是不是写的太麻烦了啊,那有没有简单的方法查询呢?
association可以指定联合的javaBean对象 指定哪个属型是联合的对象 javaType指定属型对象的类型【不能省略】 使用association定义关联的单个对象的封装规则
<resultMap id="MyEmpByStep" type="com.caq.mybatis.bean.Employee"> <!-- 先按照员工id查询员工信息--> <!-- 根据查询员工信息中的d_id值去查部门查处部门信息--> <!-- 部门设置到员工中--> <id column="id" property="id"/> <result column="last_name" property="lastName"/> <result column="email" property="email"/> <result column="gender" property="gender"/> <!-- association来定义关联对象的封装规则 select表明当前属性是调用sekect指定的方法查出的结果 流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性--> <association property="dept"select="com.caq.mybatis.dao.DepartmentMapper.getDeptById" column="d_id"> </association> </resultMap> <select id="getEmpByIdStep" resultMap="MyEmpByStep"> select * from tbl_employee where id = #{id} </select>