失之东偶,收之桑榆
文章目录
前言
基于mybatis可以做的各种优化和拓展
一、@Before和@After
在测试类中
使用@Before注解的方法会在所有test方法执行之前执行
使用@After注解的方法会在所有test方法执行之后执行
二、注册实体类(pojo)的别名
在ns中可看到
typeAliases应该出现的位置
<typeAliases>
<!--单个注册-->
<!--<typeAlias type="org.example.pojo.Student" alias="student"/>-->
<!--
批量注册
别名是类名的驼峰命名法
-->
<package name="org.example.pojo"/>
</typeAliases>
三、设置日志输出
在setting中设置,位置如图:
参数固定
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
可以在控制台看到输出的日志
可以看到更细致的操作
四、动态代理
对于MVC来说
业务的执行是由V==》C==》M==》
而在mybatis中M层(DAO)使用的是UsersMapper.xml的方式来实现
数据访问的功能
所以对于MVC来说
无法在Service层访问Dao层的功能
解决方案:动态代理
即在业务逻辑层依然使用接口调用xml文件中的功能,此功能由动态代理对象代理出来
目标:在业务逻辑层通过接口访问数据访问层的功能
动态代理的实现规范
- UsersMapper.xml文件与UsersMapper.java的接口必须在同一个目录下
- UsersMapper.xml文件与UsersMapper.java的接口的文件名必须一直,后缀不管
- UsersMapper.xml文件中标签的id值与UsersMapper.java的接口中方法的名称完全一直
- UsersMapper.xml文件中标签的parameterType的属性值UsersMapper.java的接口中方法的参数类型完全一致
- UsersMapper.xml文件中标签的resultType值与UsersMapper.java的接口中方法的返回值类型完全一致
- UsersMapper.xml文件中namespace属性必须是接口的完全限定名称。org.example.mapper.UsersMapper
- 在SqlMapConfig.xml文件中注册mapper文件时,使用class=接口的完全限定名称org.example.mapper.UsersMapper
五、动态代理访问的步骤
- 建表Users
- 新建maven,刷新可视化
- 修改目录
- 修改pom.xml,添加依赖
- 添加jdbc.properties文件到resources目录下
- 添加SqlMapConfig.xml文件
- 添加POJO
- 添加mapper文件夹,新建UsersMapper接口
- 在mapper文件夹下,新建UsersMapper.xml文件,完成CRUD
- 添加测试类,测试功能
动态代理对象(test中)
由mybatis框架代理
UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
将字符串格式化为Date (日期的格式化刷子)
SimpleDateFormat sf =new SimpleDateFormat("yyyy-MM-dd");
sf.parse("2001-01-01")
六、#{}和${}
6.1 #{}
百分之90的情况都是#{}的使用
#{} 用来进行参数的占位,底层是用的PrepareStatement,是安全的数据库访问
可以防止sql注入(用?占位)
#{}里如何写,看parameterType参数的类型
- 如果parameterType的类型是简单类型(8种基本(封装)+String),则#{}里随便写
<select id="getById" parameterType="int" resultType="users">
select id,username,birthday,sex,address
from users
where id=#{id}
</select>
</select>
- 如果parameterType的类型是实体类的类型,则#{}里只能是类中成员变量的名称,而且区分大小写
<insert id="insert" parameterType="users">
insert into users (username,birthday,sex,address) values(#{userName},#{birthday},#{sex},#{address})
</insert>
6.2 ${}
字符串拼接或字符串替换
6.2.1 字符串拼接
字符串拼接一般用于模糊查询种,建议少用,因为有sql注入的风险
也分两种情况,同样看parameterType的类型
- parameterType的类型是简单类型,则${}里随便写,但是分版本,如果是3.5.1及以下版本,只能写value
<select id="getByName" parameterType="string" resultType="users">
select id,username,birthday,sex,address
from users
where username like '%${name}%'
</select>
- parameterType的类型是实体类的类型,则${}里只能是类中成员变量的名称(现在已经少用)
- 优化后的模糊查询(以后都要使用这种方式(避免sql注入))
<select id="getByNameGood" parameterType="string" resultType="users">
select id,username,birthday,sex,address
from users
where uasername like concat('%',#{name},'%')
</select>
6.2.1 字符串替换
需求:模糊地址或用户名查询
select *
from users
where username like ‘%小%’;
select *
from users
where address like ‘%市%’;
<!--
//模糊用户名和地址查询
//如果参数超过一个,则parameterType不写
List<Users> getByNameOrAddress(
@Param("columnName")
String columnName,
@Param("columnValue")
String columnValue);
-->
<select id="getByNameOrAddress" resultType="users">
select id,username,birthday,sex,address
from users
where ${columnName} like concat('%',#{columnValue},'%')
</select>
七、返回主键值
<insert id="insert" parameterType="users">
<selectKey keyProperty="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into users (username,birthday,sex,address) values(#{userName},#{birthday},#{sex},#{address})
</insert>
标签:
<selectKey>
的参数详解:
keyProperty:users对象的哪个属性来接返回的主键值
resultType:返回主键的类型
order:在插入语句执行前(BEFORE),还是执行后返回主键的值(AFTER)
总结
看代码即可
别忘了除了查询其他需要手动提交事务