发表于: 2018-03-15 23:23:45
1 552
今日完成
优化mybatis配置文件
1,在db.properties文件编写连接数据库需要使用到的数据库驱动,连接URL地址,用户名,密码:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf-8
username=root
password=root
然后在config.xml文件中引用da.properties文件
<!-- 引用db.properties配置文件 -->
<properties resource="db.properties"/>
2,为实体类定义别名,简化sql映射xml文件中的引用
首先在mybatis配置文件中定义别名
<typeAliases>
<typeAlias type="com.ycc.model.User" alias="_User"/>
</typeAliases>
之后,在需要引用实体类User的地方可直接用"_User"。
3,如何解决表中的字段名和实体类的属性名不一致
假设标中字段名为:order_id , ordr_name , order_age
实体类中属性为:id,name,age
解决办法一: 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致,这样就可以表的字段名和实体类的属性名一一对应上了,这种方式是通过在sql语句中定义别名来解决字段名和属性名的映射关系的。
在sql语句中将查询的字段名都起一个和实体类属性名相同的别名,就可以将属性名和字段名一一对应。
<select id="selectOrder" parameterType="int"
resultType="com.ycc.model.Order">
select order_id id, order_name name,order_age age from orders where order_id=#{id}
</select>
解决办法二: 通过<resultMap>来映射字段名和实体类属性名的一一对应关系。这种方式是使用MyBatis提供的解决方式来解决字段名和属性名的映射关系的。
<!-- 通过<resultMap>映射实体类属性名和表的字段名一一对应关系 ,可以正常查询-->
<select id="selectOrderResultMap" parameterType="int" resultMap="orderResultMap">
select * from orders where order_id=#{id}
</select>
<!--通过<resultMap>映射实体类属性名和表的字段名对应关系 -->
<resultMap type="com.ycc.model.Order" id="orderResultMap">
<!-- 用id属性来映射主键字段 -->
<id property="id" column="order_id"/>
<!-- 用result属性来映射非主键字段 -->
<result property="name" column="order_name"/>
<result property="age" column="order_age"/>
</resultMap>
然后今天又用了基于注解方式的mybatis
项目结构跟基于配置文件的差不多,只是将userMapper.xml换位User Mapper接口。
定义sql映射的接口,而且我们不需要针对UserMapperImpl去写实现类,这个具体的实现类由MyBatis帮我们动态构建出来,我们只需要直接拿来使用即可。
public interface UserMapperImpl {
@Insert("insert into users(name,age) values(#{name},#{age})")
int addUser(User user);
@Delete("delete from users where id=#{id}")
int deleteUser(User user);
@Update("update users set name=#{name},age=#{age} where id=#{id}")
int updateUser(User user);
@Select("select * from users where id=#{id}")
User getUserById(int id);
@Select("select * from users")
List<User> getAllUser();
}
其他配置跟之前一样,接下来是测试类
增加:
@Test
public void testAdd() {
SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
//得到UserMapperI接口的实现类对象mapper,
// UserMapperI接口的实现类对象由sqlSession.getMapper(UserMapperI.class)动态构建出来
UserMapperImpl mapper = sqlSession.getMapper(UserMapperImpl.class);
User user=new User();
user.setName("模拟出的");
user.setAge(12);
int retResult = mapper.addUser(user);
sqlSession.close();
System.out.println(retResult );
}
删除:
@Test
public void testDelete() {
SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
UserMapperImpl mapper = sqlSession.getMapper(UserMapperImpl.class);
User user=new User();
user.setId(7);
int retResult = mapper.deleteUser(user);
sqlSession.close();
System.out.println(retResult );
}
更新:
@Test
public void testUpdate() {
SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
UserMapperImpl mapper = sqlSession.getMapper(UserMapperImpl.class);
User user = new User();
user.setId(6);
user.setName("找你的看法");
user.setAge(22);
int retResult = mapper.updateUser(user);
sqlSession.close();
System.out.println(retResult );
}
查询ID:
@Test
public void testGetUserById() {
SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
UserMapperImpl mapper = sqlSession.getMapper(UserMapperImpl.class);
User user= mapper.getUserById(6);
sqlSession.close();
System.out.println(user );
}
查询所有:
@Test
public void testGetAllUser() {
SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
UserMapperImpl mapper = sqlSession.getMapper(UserMapperImpl.class);
List<User> userList=mapper.getAllUser();
sqlSession.close();
System.out.println(userList);
}
然后看到网上的教程,关于mybatis的联表查询,学着实现了一对一的查询,但是还有很多不懂,在这里记录一下,明天在研究研究。
首先建立两个表:教师表和班级表,一个教师对应一个班级
项目结构如下:
其中主要的是映射文件
<!z-
方式一:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集
封装联表查询的数据(去除重复的数据)
select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=1
-->
<select id="getClass" parameterType="int" resultMap="ClassResultMap">
select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=#{id}
</select>
<!-- 使用resultMap映射实体类和字段之间的一一对应关系 -->
<resultMap type="com.ycc.model.Classes" id="ClassResultMap">
<id property="id" column="c_id"/>
<result property="name" column="c_name"/>
<association property="teacher" javaType="com.ycc.model.Teacher">
<id property="id" column="t_id"/>
<result property="name" column="t_name"/>
</association>
</resultMap>
然后这里介绍下resultMap标签:用来建立SQL查询结果字段与实体属性的映射关系信息
<resultMap type="com.ycc.model.Classes" id="ClassResultMap">
如上type为Java返回值的全限定类名,或类型别名。id为此resultMap的标识。
子元素说明:
<id property="id" column="c_id"/>
<result property="name" column="c_name"/>
id元素 ,用于设置主键字段与领域模型属性的映射关系
result元素 ,用于设置普通字段与领域模型属性的映射关系
property:记录实体类的属性
column:记录表的字段名称
association联合元素:
<association property="teacher" javaType="com.ycc.model.Teacher">
<id property="id" column="t_id"/>
<result property="name" column="t_name"/>
</association>
联合元素用来处理“一对一”的关联查询。需要指定映射的Java实体类的属性,属性的javaType(通常MyBatis 自己会识别)。对应的数据库表的列名称。如果想覆写的话返回结果的值,需要指定typeHandler。
ssociation标签可用的属性如下:
- property:对象属性的名称
- javaType:对象属性的类型
- column:所对应的外键字段名称
- select:使用另一个查询封装的结果
测试类
@Test
public void testGetClass(){
SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
String statement = "com.ycc.mapping.classMapper.getClass";//映射sql的标识字符串
//执行查询操作,将查询结果自动封装成Classes对象返回
Classes clazz = sqlSession.selectOne(statement,1);//查询class表中id为1的记录
//使用SqlSession执行完SQL之后需要关闭SqlSession
sqlSession.close();
System.out.println(clazz);
}
结果如下
遇到的困惑
对于联表查询的配置文件,其嵌套结构还看不懂,
<association property="teacher" javaType="com.ycc.model.Teacher">
<id property="id" column="t_id"/>
<result property="name" column="t_name"/>
</association>
我理解的是用标签association嵌套表示的是:将teacher表中的t_id与class表中的teacher_id关联起来,如下
c.teacher_id=t.t_id
然后我输入id查询class表(班级)的时候,如下:
c.c_id=#{id}
会从class表的teacher_id字段与teacher表的t_id相互关联,这样就将teacher的属性传进来,进行输出。
明日计划
继续学习mybatis,然后好像mybatis可以和spring整合,也试着看看。
收获
学习了mybatis的注解实现方式,了解了其联表查询的方式:一对一,一对多,多对一。
评论