MyBatis
1 Mapper代理开发
在mybatis中,映射文件中的namespace是用于绑定Dao接口的,即面向接口编程
当你的namespace绑定接口后,你可以不用写接口实现类,mybatis会通过该绑定自动完成。
开发规范:
1、mapper接口全限名(包名+接口名)要和映射文件namespace相同
2、mapper接口中的方法名要和mapper映射文件中的statement id相同
3、mapper接口的方法参数要和mapper映射文件中的parameterType相同
4、mapper接口方法的返回类型要和mapper映射文件中resultType相同
UserMapper userMapper=session.getMapper(UserMapper.class);
示例 1 传递多个参数
接口编程的功能非常方便和强大。
多个参数传递,可直接写成:
arg0 arg1…
也可以写成param1…
例如:分页
/**
* 分页查询
* @param offset
* @param rows
* @return
*/
public List<User> selectByPage(Integer offset,Integer rows);
Java代码:
SqlSession session=MyBatisUtil.getSession();
UserMapper userMapper=session.getMapper(UserMapper.class);
int pageNum=1;
int pageSize=3;
int offset=(pageNum-1)*pageSize;
List<User> list=userMapper.selectByPage(offset, pageSize);
for(User u:list){
System.out.println(u);
}
MyBatisUtil.closeAll(session);
<!-- 多个参数传递 -->
<select id="selectByPage" resultType="User">
select * from user limit #{arg0} , #{arg1}
</select>
2 优化
jdbc.properties 示例:
连接数据库的配置单独放在一个jdbc.properties文件中
#### key=value
jdbc_url=jdbc:mysql://localhost:3306/mybatis
jdbc_driver=com.mysql.jdbc.Driver
jdbc_user=root
jdbc_password=root
<configuration>
<properties resource="jdbc.properties"></properties>
<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_user}" />
<property name="password" value="${jdbc_password}" />
</dataSource>
</environment>
</environments>
.......................
</configuration>
类型别名(typeAliases)
类型别名是为 Java 类型设置一个短的名字。
它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。例如:
<typeAliases>
<typeAlias alias="User" type="com.qfjy.bean.User"/>
<typeAlias alias="Grade" type="com.qfjy.bean.Grade"/>
......
</typeAliases>
当这样配置时,User
可以用在任何使用 com.qfjy.bean.User
的地方。
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:
<typeAliases>
<package name="com.qfjy.bean"/>
</typeAliases>
3 插入Insert
属性 | 描述 |
---|---|
id | 命名空间中的唯一标识符,可被用来代表这条语句。 |
parameterType | 将要传入语句的参数的完全限定类名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器推断出具体传入语句的参数,默认值为未设置(unset)。 |
parameterMap | 这是引用外部 parameterMap 的已经被废弃的方法。请使用内联参数映射和 parameterType 属性。 |
flushCache | 将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:true(对于 insert、update 和 delete 语句)。 |
timeout | 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖驱动)。 |
statementType | STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。 |
useGeneratedKeys | (仅对 insert 和 update 有用)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系数据库管理系统的自动递增字段),默认值:false。 |
keyProperty | (仅对 insert 和 update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值,默认值:未设置(unset )。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。 |
示例1 添加(得到主键自增)
Article
列名 | 类型 | 描述 |
---|---|---|
id | int | 自增 |
title | 标题 | |
image | 图片 | |
content | 内容 | |
status | 状态 |
数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置到目标属性上就 OK 了。例如,如果上面的 Author 表已经对 id 使用了自动生成的列类型,那么语句可以修改为:
<mapper namespace="com.qfjy.mapper.ArticleMapper">
<insert id="add" useGeneratedKeys="true" keyProperty="id" >
insert into article(title,content) values(#{title},#{content})
</insert>
</mapper>
@Test
public void t1(){
SqlSession session=MyBatisUtil.getSession();
ArticleMapper articleMapper=session.getMapper(ArticleMapper.class);
Article ar=new Article();
ar.setTitle("qfjy学习Mybatis");
ar.setContent("内容描述");
articleMapper.add(ar);
System.out.println("打印:"+ar);
MyBatisUtil.closeAll(session);
}
4 sql标签
这个元素可以被用来定义可重用的 SQL 代码段,这些 SQL 代码可以被包含在其他语句中。
<sql id="Base_Column_List">
id,title,image,content,status
</sql>
<!-- 查询所有 -->
<select id="selectList" resultType="Article">
select
<include refid="Base_Column_List"/>
from article
</select>
5 注解(CRUD)
@Select("select *from article")
public List<Article> selectAll();
@Insert("insert into article(title,content) values(#{title},#{content}) ")
public int addArticle(Article a);
@Delete(" delete from article where id=#{id}")
public int delById(Integer id);
@Select(" select *from article where id=#{id} and content=#{content} ")
public Article selectById(@Param("id")Integer id,@Param("content")String content);
#号和$号组合使用:
@Select(" select * from article where ${column}=#{value} ")
public Article selectByColumn(@Param("column")String column,@Param("value")String value);
6 解决字段名与实体类属性名不相同的冲突
准备表和数据
CREATE TABLE GRADE(
g_id INT PRIMARY KEY AUTO_INCREMENT,
g_name VARCHAR(20)
);
定义实体类
public class Grade {
private int id;
private String gname;
}
实现查询
方式一: 通过在sql语句中定义别名
<select id="getGrade" parameterType="int" resultType="Grade">
select g_id as id,g_name gname from Grade where g_id=#{id};
</select>
方式二: 通过<resultMap>
<!-- 2、查询根据ID得到实体 通过resultMap完成 -->
<select id="getGradeMap" parameterType="int" resultMap="GradeMap">
select * from Grade where g_id=#{id};
</select>
<resultMap type="Grade" id="GradeMap">
<id property="id" column="g_id"/>
<result property="gname" column="g_name"/>
</resultMap>