01 mybatis简介以及简单案例
1、Mybatis简介
-
MyBatis本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。
-
MyBatis是一个优秀的持久层框架,使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
注:MyBatis和Ibatis是同一个框架。MyBatis把sql语句交给xml进行管理。
2、一个简单的mybatis案例
①导入mybatis相关jar包
②写一个sqlMapConfig.xml
提供mybatis的核心配置文件sqlMapConfig.xml,并放在项目的src目录下。此文件中配置了数据库的基本连接参数和sql映射文件等相关信息。我们可以从mybatis安装包中提供的官方文档(mybatis-3.1.1.pdf)中获得此文件的模板。
sqlMapConfig.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>
<environments default ="development" >
<environment id ="development" >
<transactionManager type ="JDBC" />
<dataSource type ="POOLED" >
<property name ="driver" value="com.mysql.jdbc.Driver" />
<property name ="url" value="jdbc:mysql:///mybatis" />
<property name ="username" value="root" />
<property name ="password" value="sorry" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource ="cn/itcast/mybatis/domain/User.xml" />
</mappers>
</configuration>
③创建数据库Mybatis和数据表user
创建与数据表user对应的java实体类User.java
User.java
public class User {
private String id ;
private String name ;
private Integer age ;
private String address ;
public String getId() {
return id ;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name ;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age ;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address ;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [address=" + address + ",name=" + name + ",age=" + age + ",address" + address + "]" ;
}
}
④创建映射文件
提供User实体的sql映射文件User.xml,并和User实体放在同一个包中,此文件的模板同样可以从mybatis的官方文档(mybatis-3.1.1.pdf)中获得。
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 ="cn.itcast.mybatis.domain.User" >
<!--id:sql的唯一标识,只要在本xml中不重名即可,parameterType:参数类型 resultType:结果类型-->
<select id ="selectUserById" parameterType="string" resultType="cn.itcast.mybatis.domain.User" >
select * from user where id = #{id}
</select>
</mapper>
⑤执行代码
MybatisTest.java
public class MybatisTest {
//根据id查询user
@Test
public void test1() throws IOException{
String resource = "sqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
//参数1:命名空间+sqlId类唯一锁定要执行的sql
//参数2:sql语句所需要的参数
User user = (User)session.selectOne( "cn.itcast.mybatis.domain.User.selectUserById" ,"1" );
System. out.println(user);
session.close();
}
}
⑥执行结果:
(注:mybatis在生成实体对象的时候实际上调用了set方法。)
3、显示执行的sql语句
为了更加直观的看到mybatis执行的sql语句,可以在项目的src目录下加入log4j.properties文件,将程序执行的sql输出到控制台。
02 模拟框架将查询到的数据通过反射包装成指定对象
1、代码
public class MybatisTest {
@Test
public void test2() throws Exception {
String className = "cn.itcast.mybatis.domain.User" ;
Object object = Class. forName(className).newInstance();
Class. forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/mybatis", "root","sorry" );
String sql = "select * from user where id = ?" ;
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, "1");
ResultSet rs = ps.executeQuery();
while(rs.next()){
ResultSetMetaData data = rs.getMetaData();
int count = data.getColumnCount();
for(int i = 1; i <= count; i++){
String columnName = data.getColumnName(i);
String setMethodName = buildSetMethod(columnName);
String typeName = data.getColumnTypeName(i);
if(typeName.equals("VARCHAR" )){
String value = rs.getString(columnName);
Method method = object.getClass().getMethod(setMethodName, String.class);
method.invoke(object, value);
} else if (typeName.equals("INT")){
int value = rs.getInt(columnName);
Method method = object.getClass().getMethod(setMethodName, Integer.class);
method.invoke(object, value);
}
}
User user = (User)object;
System. out.println(user);
}
}
public String buildSetMethod(String cName){
String c1 = "set";
String c2 = cName.substring(0,1).toUpperCase();
String c3 = cName.substring(1);
return c1 + c2 + c3;
}
}
2、执行结果
03 Mybatis基础代码
sqlMapConfig.xml
<?xml version ="1.0" encoding="UTF-8" ?> <!-- 配置别名 -->
<typeAliases>
<typeAlias type ="cn.itcast.mybatis.domain.User" alias="User" />
</typeAliases>
<environments default ="development" >
<environment id ="development" >
<transactionManager type ="JDBC" />
<dataSource type ="POOLED" >
<property name ="driver" value="com.mysql.jdbc.Driver" />
<property name ="url" value="jdbc:mysql:///mybatis" />
<property name ="username" value="root" />
<property name ="password" value="sorry" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource ="cn/itcast/mybatis/domain/User.xml" />
</mappers>
User.xml
<?xml version ="1.0" encoding="UTF-8" ?> <!--通过resultMap可以解决字段名和属性名冲突的情况-->
<resultMap type ="User" id= "userMap">
<id property ="id" column="id" />
<result property ="name" column="name" />
<result property ="age" column="age" />
<result property ="address" column="address" />
</resultMap>
<!-- 当字段很多的时候,可以通过下面这种方式抽取字段 -->
<sql id ="allColumns" >
id,name,age,address
</sql>
<!-- 如果在sqlMapConfig.xml中配置了别名,那么这里的resultType就可以直接写User -->
<select id ="selectUserById" parameterType="string" resultMap="userMap" >
select
<include refid ="allColumns" />
from user where id = #{id}
</select>
<!-- bean的属性名和数据库中的字段名不一致,那么将会出现取出来的属性值为null情况,这时候可以通过取别名的方式解决 -->
<select id ="selectUserById2" parameterType="string" resultType="User" >
select id,name as userName,age,address from user where id = #{id}
</select>
<!-- 查询所有的用户 -->
<select id ="selectAllUser" resultType="cn.itcast.mybatis.domain.User" >
select <include refid ="allColumns" /> from user
</select>
<!-- 根据用户的id删除用户 -->
<delete id ="deleteUserById" parameterType="string" >
delete from user where id = #{id}
</delete>
<!-- 插入一条用户数据 -->
<insert id ="insertUser" parameterType="cn.itcast.mybatis.domain.User" >
insert into user(id,name,age,address) values(#{id},#{name},#{age},#{address})
</insert>
<!-- 根据id修改数据 -->
<insert id ="updateUserById" parameterType="cn.itcast.mybatis.domain.User" >
update user set name=#{name},age=#{age},address=#{address} where id=#{id}
</insert>
<!-- 利用动态sql语句更新user数据 -->
<insert id ="updateUserByCondition" parameterType="cn.itcast.mybatis.domain.User" >
update user
<set>
<if test ="name!=null" >
name = #{name}
</if>
<if test ="age!=null" >
age = #{age}
</if>
<if test ="address!=null" >
address = #{address}
</if>
</set>
where id=#{id}
</insert>
<!-- 动态seql语句查询用户 -->
<select id ="selectUserByCondition" parameterType="cn.itcast.mybatis.domain.User" resultType="cn.itcast.mybatis.domain.User" >
select * from user where 1 = 1
<if test ="id!=null" >
and id = #{id}
</if>
<if test ="name!=null" >
and name = #{name}
</if>
<if test ="age!=null" >
and age = #{age}
</if>
<if test ="address!=null" >
and address = #{address}
</if>
</select>
<!-- 动态seql语句查询用户方式2 -->
<!-- 这种方式会自动根据是否有id,如果有没有id,那么第一个条件将不加and -->
<select id ="selectUserByCondition2" parameterType="cn.itcast.mybatis.domain.User" resultType="cn.itcast.mybatis.domain.User" >
select * from user
<where>
<if test ="id!=null" >
id = #{id}
</if>
<if test ="name!=null" >
and name = #{name}
</if>
<if test ="age!=null" >