先学习一下做mapper。
数据库中先建一张表:
-- Create table
create table system_users
(
user_id varchar2(32),
user_number varchar2(32),
user_name varchar2(32),
remark varchar2(255)
)
;
-- Create/Recreate primary, unique and foreign key constraints
alter table system_users
add constraint pk_system_users primary key (USER_ID);
insert into SYSTEM_USERS (USER_ID, USER_NUMBER, USER_NAME, REMARK)
values ('1', '001', '张三', '备注');
commit;
说到这,就不得不啰嗦几句了。
以前数据库用Oracle,所以一般性规则如下:
1、因Oracle对象名不区分大小写(除非强行用双引号,但程序写SQL时也必须加),所以一般是各单词间用下划线分隔;
2、表名:实体+S(表示复数),有时为了区分不同的子系统,也会加个前缀,比如用户表,归到system,一般会建为“sys_users”
3、字段名在实体相关的主要属性上,会加上实体信息,比如user_id,user_number,user_name,如果不加的话,在几个表关联查询时,会很讨厌,并且容易与保留字冲突。比如:用户表(id,number,name),角色(id,number,name),功能(id,number,name),这样命名SQL写起来太不爽了。
但一般在java中,不是按上面3种规则来定义。以前也看到过争论,是先设计实体,还是先设计数据库,以前做C/S不觉得,答案肯定是先数据库。现在这个可真得考虑一下了。
在想,如果能保持一致,或者说有一些规则,就可以用一些工具来自动生成,或者说,某些java的方法就可以抽取为公共的。继续吧。
在src/test/resources中,新建user.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">
<mapper namespace="mybatistest.mapper.User">
<select id="getByID" parameterType="String" resultType="mybatistest.entity.User">
select user_id as userid,
user_number as usernumber,
user_name as username,
remark
from system_users
where user_id = #{userID}
</select>
</mapper>
将该mapper.xml加入到mybatis的配置文件中
<mappers>
<mapper resource="user.xml" />
</mappers>
在src/main/java中,建一个package:mybatistest.entity
再在该包下面建一个Class:
package mybatistest.entity;
public class User {
private String userID;
private String userNumber;
private String userName;
private String remark;
。。。getter和setter。。。
}
好了,再把Test改一下:
// sqlSessionFactory.openSession().commit();
User user = sqlSessionFactory.openSession().selectOne("mybatistest.mapper.User.getByID", "1");
System.out.println(user.getUserName());
运行一下,应该出来“张三”了。
上面是在SQL中用别名来处理数据库字段与Bean的字段名不同的映射,MyBatis也提供了另外一种方式:resultMap,user.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">
<mapper namespace="mybatistest.mapper.User">
<resultMap id="userResultMap" type="mybatistest.entity.User">
<id property="userID" column="user_id" />
<result property="userNumber" column="user_number"/>
<result property="userName" column="user_name"/>
</resultMap>
<select id="getByID" parameterType="String" resultMap="userResultMap">
select user_id ,
user_number,
user_name,
remark
from system_users
where user_id = #{id}
</select>
</mapper>
注意一下的就是property="userNumber"是要区分大小写的,而对于没有映射到resultMap的字段,也是会处动映射到User类上去的,比如remark。
Test.java稍改一下:
User user = sqlSessionFactory.openSession().selectOne("mybatistest.mapper.User.getByID","1");
System.out.println(user.getRemark());
运行一下,可以看到取了到remark的值。
OK,这是最基本的了,其他的参考一下官网都可以操作。
我这个人是比较懒的,到这个地方,我要思考的就是,如果做一个系统,面对成百上千张表,这样搞mapper不弄死人?应该要从设计上考虑一下:
1、前面说的数据库字段与Bean的属性,如果不一致,每个都得配resultMap,工作量大,容易出错,所以这个地方是设计系统时需要考虑的。至少得有一些规律,可以从bean生成建表SQL,或者从表生成Bean,这样可以写个小工具,来自动生成;
2、对于像根据PK得到一个Bean回来、update、insert等操作单个对象的,需要设计为公用的,减少配置工作。初步想法是配置通用SQL,然后用map和mybatis的字符串替换(即$)来,这样只需要配置3个SQL(select * from ${table} where ${pk} = #{id},update ${table} set XXX where ${pk}=#{id},insert into ${table}(XX) values(XX))就可以完成基本的操作(当然得小心SQL注入攻击)。而对于有关联的SQL或复杂SQL,就需要像上面的方法进行配置了。(以前做C/S也是这样,基本只需要配置select的SQL,这3个只需要知道表名和主键名就可以了)。
3、对于select,能否定义成几个map,来实现字段、条件、排序呢,这样很多就可以在前台公用化和控制了。
这些个就留到后面再来研究了。