一、基于代理Dao实现CRUD操作
(一)案例背景
1、数据库中的user表结构和数据分别如下:
user表结构:
user表中的数据:
2、假设项目已经搭建完成,并且基本的类(User、IUserDao)都创建完成,以及映射配置文件(IUserDao.xml)和Mybatis主配置文件(SqlMapConfig.xml)都进行了正确的配置。
其中,User类的属性如下:
1 | public class User implements Serializable { |
项目结构如下图所示:
(二)查询操作
1、查询所有用户信息
a. 在IUserDao接口中添加findAll方法
1 | public interface IUserDao { |
b. 在IUserDao.xml中进行如下配置
1 |
|
c. 编写测试类MybatisTest.java及方法如下
1 | public class MybatisTest { |
2、根据id查询指定用户
a. 在IUserDao接口中添加findById方法
1 | public interface IUserDao { |
b. 在IUserDao.xml中进行如下配置
1 | <select id="findById" parameterType="int" resultType="com.zuobiao.domain.User"> |
c. 编写测试方法如下
1 |
|
3、根据用户名进行模糊查询
a. 在IUserDao接口中添加findByName方法
1 | public interface IUserDao { |
b. 在IUserDao.xml中进行如下配置
1 | <select id="findByName" resultType="com.zuobiao.domain.User" parameterType="String"> |
c. 编写测试方法如下
1 |
|
补充:
在步骤b中的sql语句也可以使用如下方法:
1 | <select id="findByName" resultType="com.zuobiao.domain.User" parameterType="String"> |
那么在测试的时候传递的参数就不用添加 % 了。
两者的不同:
这两者方法最主要的区别就是方式一是生成预编译sql,相当于JDBC中的PreparedStatement;
而方式二则是直接拼接sql,相当于JDBC中的Statement;
所以方式二可能会有SQL注入的危险,不推荐使用!
点击查看具体分析
4、查询时使用聚合函数
a. 在IUserDao接口中添加findTotalCount方法
1 | public interface IUserDao { |
b. 在IUserDao.xml中进行如下配置
1 | <select id="findTotalCount" resultType="int"> |
c. 编写测试方法如下
1 |
|
5、由多个对象组成查询条件进行查询
在QueryVo类中,有如下代码:
1 | public class QueryVo { |
现在需要使用该类对象中的user对象的username进行模糊查询。
a. 在IUserDao接口中添加findByVo方法
1 | public interface IUserDao { |
b. 在IUserDao.xml中进行如下配置
1 | <select id="findByVo" parameterType="com.zuobiao.domain.QueryVo" resultType="com.zuobiao.domain.User"> |
c. 编写测试方法如下
1 | @Test |
(三)添加操作
添加用户
a. 在IUserDao接口中添加saveUser方法
1 | public interface IUserDao { |
b. 在IUserDao.xml中进行如下配置
1 | <insert id="saveUser" parameterType="com.zuobiao.domain.User"> |
使用如下配置可以在添加完成后,将数据库表中自动生成的id查询出来并封装到user对象。
1 | <insert id="saveUser" parameterType="com.zuobiao.domain.User"> |
c. 编写测试方法如下
1 |
|
(四)删除操作
删除用户
a. 在IUserDao接口中添加delUser方法
1 | public interface IUserDao { |
b. 在IUserDao.xml中进行如下配置
1 | <delete id="delUser" parameterType="Integer"> |
c. 编写测试方法如下
1 |
|
(五)修改操作
更新用户信息
a. 在IUserDao接口中添加updateUser方法
1 | public interface IUserDao { |
b. 在IUserDao.xml中进行如下配置
1 | <update id="updateUser" parameterType="com.zuobiao.domain.User"> |
c. 编写测试方法如下
1 |
|
二、Java类的属性名与Mysql表中列名的对应
在之前的案例中都是没有将Java类的属性名与Mysql表中的列名进行一一对应的,这就要求属性名必须和表中的列名完全一致,但是如果不一致会出现什么样的问题呢?
其实很明显,如果不一致的话就会导致查询到的结果不能封装到对象中。因此如果类中的属性名不是和列名完全一样的话,那么将两者进行一一对应的步骤是非常重要的。
原因:因为在进行封装时,Mybatis会根据列名才知道调用该对象的哪一个set方法,所以两者必须要有对应关系才能够进行封装。
通常由两种方法将两者进行对应:
方法一:给表中的列名指定别名
方法二:在map的配置文件中进行对应
假设User类中的属性更改如下:
1 | public class User implements Serializable { |
那么以下就以findAll方法的配置进行举例。
(一)方法一
之前配置的findAll方法就可以更改如下:
1 | <select id="findAll" resultType="user"> |
(二)方法二
在IUserDao.xml配置文件中添加如下标签
1 | <resultMap id="user" type="com.zuobiao.domain.User"> |
select标签中使用resultMap属性
1 | <select id="findAll" resultMap="user"> |
三、配置补充
(一)Properties标签
之前我们配置连接数据库的参数时都是之前在dataSource标签中使用property标签,如:
1 | <environments default="mysql"> |
其实我们也可以在environments标签之外使用properties标签进行配置,然后在dataSource标签中的property标签中进行引用,如:
方式一:
1 | <properties> |
当然,properties标签中的内容也可以从外部配置文件中导入,如:
方式二:
在resources目录下有一个名为jdbcConfig.properties的配置文件
1 | driver=com.mysql.cj.jdbc.Driver |
在properties标签中导入
1 | <properties resource="jdbcConfig.properties">> |
(二)typeAliases标签
在进行配置的时候,经常都是需要写权限定类名,非常的长,而且一不小心就有可能写错了,因此Mybatis提供了typeAliases标签,可以让我们给类或者包起别名。
1、给类起别名
1 | <typeAliases> |
类起了别名之后,那么在map配置文件中需要使用该类的路径时就只需要填写别名就好了,不区分大小写。
2、给包起别名
1 | <typeAliases> |
给一个包起别名之后,那么这个包中的所有类都有了别名,其别名就是它的类名,并且不区分大小写。
3、typeAliases标签的其他好处
如果给mapper标签的resource或者class属性所使用的包起别名之后,那么这个这个包中的所有dao接口所对应的配置文件就都不需要导入了,如下:
1 | <mappers> |
1 | <mappers> |
Java新手,若有错误,欢迎指正!