看一个实例:
1.实体类:
package com.jadeon.mybatis.bean;
import java.io.Serializable;
import org.apache.ibatis.type.Alias;
@Alias("deptinfo")
public class Dept implements Serializable {
private static final long serialVersionUID = 1L;
private Integer deptno;
private String dname;
private String loc;
public Dept() {
super();
}
public Dept(Integer deptno,String dname, String loc) {
super();
this.deptno = deptno;
this.dname = dname;
this.loc = loc;
}
@Override
public String toString() {
return "Dept [deptno=" + deptno + ", dname=" + dname + ", loc=" + loc + "]";
}
public Integer getDeptno() {
return deptno;
}
public void setDeptno(Integer deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
}
2.Dao接口
方式1:
package com.jadeon.mybatis.dao;
import org.apache.ibatis.annotations.Param;
import com.jadeon.mybatis.bean.Dept;
public interface DeptMapper {
public Dept getByIdAndDname(@Param("deptno")Integer deptno,@Param("dname")String dname);
public Dept getById(Integer deptno);
public void addDept(Dept dept);
public void updateDeptById(Dept dept);
public void deleteDeptById(Integer deptno);
}
方式2:注解方式
package com.jadeon.mybatis.dao;
import org.apache.ibatis.annotations.Select;
import com.jadeon.mybatis.bean.Dept;
public interface DeptMapperAnnotation {
@Select("select * from dept where deptno = #{id}")
public Dept getById(Integer deptno);
@Select("insert into dept(dname,loc) values (#{dname},#{loc})")
public void add(Dept dept);
@Select("delete from dept where deptno = #{deptno}")
public void deleteById(Integer deptno);
@Select("update dept set dname=#{dname},loc=#{loc} where deptno=#{deptno}")
public void updateById(Dept dept);
}
3.DBHeper帮助类
package com.jadeon.mybatis.util;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class DBHelper {
static String resource;
static InputStream inputStream ;
static SqlSessionFactory sqlSessionFactory;
static SqlSession sqlSession;
public static SqlSession openSqlSession() throws Exception{
//1.获得xml文件
resource = "mybatis-config.xml";
//2.获取InputStrean流读取xml文件
inputStream = Resources.getResourceAsStream(resource);
//3.获取SQLSessionFactory对象
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//4.打开SQLSession
if (sqlSession == null )
sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
//测试
public static void main(String[] args) throws Exception {
System.out.println(openSqlSession());
}
}
4接口类Mapper.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="com.jadeon.mybatis.dao.DeptMapper">
<!--
namespace: 指定为实现类接口的全类名
deptno: 唯一标识
resultType: 返回值类型
#{id}: 从传递过来的参数中取deptno值
id: 接口的方法名
public Dept getById(Integer deptno);
databaseId: 所使用的数据库id
-->
<!-- public Dept getByIdAndDname(@Param("deptno")Integer deptno,@Param("dname")String dname); -->
<select id="getByIdAndDname" resultType="com.jadeon.mybatis.bean.Dept"
databaseId="oracle">
select * from dept where deptno = #{deptno} and dname=#{dname}
</select>
<select id="getById" resultType="com.jadeon.mybatis.bean.Dept"
databaseId="oracle">
select * from dept where deptno = #{id}
</select>
<select id="getById" resultType="com.jadeon.mybatis.bean.Dept"
databaseId="mysql">
select * from dept where deptno = #{id}
</select>
<!-- public void addDept(Dept dept);
mysql支持自增主键;自增主键的获取,mybatis也是利用statement.getGeneratedKeys()
要想前台获取添加的数字,添加两个属性
useGeneratedKeys="true": 使用自增主键获取主键值
keyProperty: 对应的主键属性,也就是mybatis获取到主键值以后,将这个值封装给javaBean的哪个属性
-->
<insert id="addDept" useGeneratedKeys="true" keyProperty="deptno" databaseId="mysql" >
insert into dept(dname,loc) values (#{dname},#{loc});
</insert>
<!--Oracle不支持 自增;Oracle使用序列序列来模拟自增;
每次插入的数据的主键是从序列中拿到的值:如歌获取到这个值?
-->
<insert id="addDept" databaseId="oracle" >
<!-- keyProperty:查出的主键封装给JavaBean的哪个属性
order="BEFORE":当前SQL在插入之前运行
AFTER:当前SQL在插入之后运行
resultType: 查出数据的返回值类型
BEFORE运行顺序:
先运行selectKey查询id的sql;查出id的值封装给javaBean的id属性
再运行插入的SQL;就可以取出id属性对应的值
AFTER:
先 运行插入的SQL(从序列中取出新值作为id)
再运行selectKey查询id的sql
-->
<selectKey keyProperty="deptno" order="BEFORE" resultType="Integer">
<!-- 编写查询主键的SQL语句 -->
<!-- BEFORE:-->
SELECT seq_deptno.nextval FROM dual
<!-- AFTER:
SELECT seq_deptno.currval FROM dual
-->
</selectKey>
<!-- 插入时的主键是从序列中拿到的 -->
<!-- BEFORE: -->
insert into dept(deptno,dname,loc)
values (#{deptno},#{dname},#{loc})
<!-- AFTER:
insert into dept(deptno,dname,loc)
values (seq_deptno.nextval,#{dname},#{loc})
-->
</insert>
<!-- public void updateDeptById(Dept dept); -->
<update id="updateDeptById">
update dept
set dname=#{dname},loc=#{loc}
where deptno=#{deptno}
</update>
<!-- public void deleteDeptById(Integer deptno); -->
<delete id="deleteDeptById">
delete from dept where deptno = #{deptno};
</delete>
</mapper>
5.数据库配置文件.propertites
orcl.driver=oracle.jdbc.OracleDriver
orcl.url=jdbc:oracle:thin:localhost:1521:orcl
orcl.username=scott
orcl.password=tigermysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/world
mysql.username=root
mysql.password=root
6.mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--
properties:引入配置信息文件
resource:类路劲(有包用com/.../...)
url:网址或者磁盘路劲
-->
<properties resource="config.properties" />
<!-- settings:重要标签,可以使用很多参数
setting:一个setting对应一个参数
mapUnderscoreToCamelCase:是否启用驼峰命名规则(默认为false)
-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- typeAliases:别名处理器 ,可以为我们的Java类型起别名
别名不区分大小写
-->
<typeAliases>
<!-- 别名默认为类名小写 -->
<!-- <typeAlias type="com.jadeon.mybatis.bean.Dept" alias="dept"/> -->
<!-- 批量起别名,使用@Alias注解某个类型指定新的别名 -->
<!-- <package name="com.jadeon.mybatis" /> -->
</typeAliases>
<!--
environments:可以连接多种数据库
environment:配置一个数据库
id: 唯一标识
transactionManager: 事务管理器
dataSource: 数据资源
-->
<environments default="dev_oracle">
<environment id="dev_oracle">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${orcl.driver}" />
<property name="url" value="${orcl.url}" />
<property name="username" value="${orcl.username}" />
<property name="password" value="${orcl.password}" />
</dataSource>
</environment>
<environment id="dev_mysql" >
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}" />
<property name="url" value="${mysql.url}" />
<property name="username" value="${mysql.username}" />
<property name="password" value="${mysql.password}" />
</dataSource>
</environment>
</environments>
<!--
databaseIdProvider: 支持多数据库厂商
type:DB_VENDOR|
-->
<databaseIdProvider type="DB_VENDOR">
<!-- 为不同的数据厂商取名字 -->
<property name="MySQL" value="mysql"/>
<property name="Oracle" value="oracle" />
<property name="SQL Server" value="sqlserver"/>
</databaseIdProvider>
<!--
mapper: 注册SQL映射
注册配置问件
resource: 引用类路径下的SQL映射文件
com/jadeon/mybatis/mapper/DeptMapper.xml
url: 引用网络路径或者磁盘路劲下的SQL映射文件
file:///var/mappers/AuthorMapper.xml
注册接口
class: 引用(注册接口)
1.有SQL映射文件,映射文件名必须和接口同名,并且放在与接口同一目录下
2.没有SQL映射文件,所有的SQL都是利用注释写在接口上
推荐:
1.比较重要的,复杂的Dao接口我们写SQL映射文件
2.不重要的,简单的Dao为了快速开发可以使用注释
-->
<mappers>
<!-- <mapper resource="com/jadeon/mybatis/mapper/DeptMapper.xml" /> -->
<!-- <mapper class="com.jadeon.mybatis.dao.DeptMapperAnnotation"/> -->
<!--
批量注册:使用包路径
1.有SQL映射文件,映射文件名必须和接口同名,并且放在与接口同一目录下
2.没有SQL映射文件,所有的SQL都是利用注释写在接口上
-->
<package name="com.jadeon.mybatis.dao"/>
</mappers>
</configuration>
最后:测试类
package com.jadeon.mybatis.test;
import org.apache.ibatis.session.SqlSession;
import com.jadeon.mybatis.bean.Dept;
import com.jadeon.mybatis.dao.DeptMapper;
import com.jadeon.mybatis.dao.DeptMapperAnnotation;
import com.jadeon.mybatis.util.DBHelper;
public class Test {
@org.junit.Test
public void test01() throws Exception {
SqlSession sqlSession = DBHelper.openSqlSession();
try {
//获取接口的实现类对象
//会为接口自动创建一个代理对象,代理对象去执行增删改查操作
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
System.out.println(deptMapper.getClass());
Dept dept = deptMapper.getById(10);
System.out.println(dept);
} finally {
sqlSession.close();
}
}
@org.junit.Test
public void test02() throws Exception {
SqlSession sqlSession = DBHelper.openSqlSession();
try {
//获取接口的实现类对象
//会为接口自动创建一个代理对象,代理对象去执行增删改查操作
DeptMapperAnnotation deptMapperAnnotation = sqlSession.getMapper(DeptMapperAnnotation.class);
System.out.println(deptMapperAnnotation.getClass());
Dept dept = deptMapperAnnotation.getById(10);
System.out.println(dept);
} finally {
sqlSession.close();
}
}
/**
* 测试增删改
*
* 1.mybatis允许增删改直接定义一下返回类型
* Integer 、Long、Boolean、void
* 2.我们需要提交数据
* sqlSessionFactory.openSession();=====>>手动提交
* sqlSessionFactory.openSession(true);=====>>自动提交
* @throws Exception
*/
@org.junit.Test
public void test03() throws Exception {
//获取到的数据不会自动提交
SqlSession sqlSession = DBHelper.openSqlSession();
try {
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
//增
Dept deptadd = new Dept(null,"Java","Java");
deptMapper.addDept(deptadd);
System.out.println(deptadd.getDeptno());
//改
//Dept deptupdate = new Dept(17,"人力资源部1","大理");
//deptMapper.updateDeptById(deptupdate);
//删
//deptMapper.deleteDeptById(17);
sqlSession.commit();
} finally {
sqlSession.close();
}
}
@org.junit.Test
public void test04() throws Exception {
SqlSession sqlSession = DBHelper.openSqlSession();
try {
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
Dept dept = deptMapper.getByIdAndDname(10, "ACCOUNTING");
System.out.println(dept);
} finally {
sqlSession.close();
}
}
}
参数处理问题:
单个参数:mybatis不会做特殊处理
#{参数名}:取出参数值
多个参数:mybatis会做特殊处理
多个参数会被封装成一个map
key:param1...paramN或者参数的索引也可以
value:传入的参数的值
#{}就是从map中获取指定的key的值
异常:
org.apache.ibatis.binding.BindingException:
Parameter 'id' not found.
Available parameters are [0, 1, param1, param2]
操作:
方法:public Dept getByIdAndDname(Integer deptno,String dname);
取值:#{deptno},#{dname}
命名参数:明确指定封装参数是map的key:@Param("deptno")Integer deptno
public Dept getByIdAndDname(@Param("deptno")Integer deptno,@Param("dname")String dname);
多个参数会被封装成一个map
key:使用@Param注释指定的值
value: 参数值
#{指定的key}取出对应的参数值