MyBatis 1.MyBatis是一个优秀的持久层框架,对jdbc的操作数据库的过程进行了封装,使开发者只需要关注SQL本身。 而不用花费精力去处理例如注册驱动,创建connection,创建statement,手动设置参数,结果集等jdbc繁杂的过程。 2.MyBatis配置: SQLMapConfig.xml 全局配置文件,配置了mybatis的运行环境等信息。 mapper.xml sql映射文件,配置了操作数据库的sql语句。需要在SqlMapConfig.xml里边加载。
3.需要的jar包
4.配置文件:放在config目录下 log4j.properties(日志文件)
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
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>
<!-- 批量导入缩写名字 名字为类名 -->
<typeAliases>
<package name="com.edu.xiaoniu.pojo"/>
</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://localhost:3306/mybatis?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<mappers>
<!-- <mapper resource="mapper/UserMapper.xml" /> -->
<!--这种方式会自动检索包下的所有类,检索到的名字为类的名字-->
<package name="com.edu.xiaoniu.mapper"/>
</mappers>
</configuration>
一、第一种方式 5.SQL映射文件: 在config下的sqlmap目录下创建sql映射文件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">
<!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用,后面会讲 -->
<mapper namespace="test">
</mapper>
6.加载映射文件 将User.xml添加在SqlMapConfig.xml
<mappers>
<mapper resource="mapper/UserMapper.xml" />
</mappers>
7.在User.xml里边添加 ‘增删改查’ 操作
<mapper namespace="test">
<!--通过ID进行查找-->
<!--parameterType是参数类型 resultType是返回类型-->
<select id="queryUserById" parameterType="Integer" resultType="com.edu.xiaoniu.pojo.User">
SELECT * FROM USER WHERE ID = #{id}
</select>
<!--通过名字模糊查询-->
<select id="queryUserByName2" parameterType="String" resultType="com.edu.xiaoniu.pojo.User">
select * from user where username like '%${value}%'
</select>
<!--插入新的User 并返回ID-->
<insert id="insetUser" parameterType="com.edu.xiaoniu.pojo.User">
<selectKey keyColumn="id" keyProperty="id" order="AFTER" resultType="int">
select LAST_INSERT_ID()
</selectKey>
insert into `user` (username ,birthday,sex ,address) VALUES (#{username},#{birthday},#{sex},#{address});
</insert>
<!--更新操作-->
<update id="updateUserById" parameterType="com.edu.xiaoniu.pojo.User">
update user set address = #{address} where id = #{id}
</update>
<!--删除操作-->
<delete id="deleteUserById" parameterType="int">
delete from user where id = #{id}
</delete>
</mapper>
8.测试程序
public class MybatisTest {
SqlSessionFactory sessionFactory = null;
@Before
public void init() {
// TODO Auto-generated method stub
try {
SqlSessionFactoryBuilder sessionFactoryBuilder = new SqlSessionFactoryBuilder();
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");//加载配置文件
sessionFactory = sessionFactoryBuilder.build(inputStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void testQueryUserById() throws Exception {
SqlSession session = sessionFactory.openSession();
User user = session.selectOne("queryUserById", 1); //selectOne返回一个查询结果
System.out.println(user);
session.close();
}
@Test
public void testQueryUserByName2() {
SqlSession session = sessionFactory.openSession();
List<User> list = session.selectList("queryUserByName2", "王五"); //selectList是返回一个列表
for (User user : list) {
System.out.println(user);
}
session.close();
}
@Test
public void insetUser() {
// TODO Auto-generated method stub
SqlSession sqlSession = sessionFactory.openSession();
User user = new User("赵小虎",new Date(),'2',"蜀国");
sqlSession.insert("insetUser",user);
sqlSession.commit();
System.out.println(user);
sqlSession.close();
}
@Test
public void updateUserById() {
// TODO Auto-generated method stub
SqlSession sqlSession = sessionFactory.openSession();
User user = new User();
user.setId(26);
user.setAddress("刘家窑");
sqlSession.update("updateUserById", user);
sqlSession.commit();
sqlSession.close();
}
@Test
public void deleteUserById() {
// TODO Auto-generated method stub
SqlSession sqlSession = sessionFactory.openSession();
sqlSession.delete("deleteUserById",31);
sqlSession.commit();
sqlSession.close();
}
}
第二种方式 9.Mapper动态代理方式 Mapper接口开发方法只需要程序员编写Mapper接口 规范: 1、Mapper.xml文件中的namespace与mapper接口的类路径相同。 2、Mapper接口方法名和Mapper.xml中定义的每个statement的id相同 3、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同 4、Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
10.在src下创建mapper包,将userMapper.xml 和 (接口)UserMapper.java 放在一起。
UserMapper.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">
<!-- namespace:命名空间,用于隔离sql -->
<!-- 还有一个很重要的作用,使用动态代理开发DAO,1. namespace必须和Mapper接口类路径一致 -->
<mapper namespace="com.edu.xiaoniu.mapper.UserMapper">
<select id="queryUserByQueryVo" parameterType="com.edu.xiaoniu.pojo.QueryVo" resultType="User">
SELECT * FROM USER WHERE username like '%${user.username}%'
</select>
</mapper>
UserMapper.java
public interface UserMapper {
List<User> queryUserByQueryVo(QueryVo queryVo);
}
11.配置SqlMapConfig.xml
<mappers>
<package name="com.edu.xiaoniu.mapper"/>
</mappers>
12.mapper测试类
public class userMapperTest {
private SqlSessionFactory sqlSessionFactory = null;
@Before
public void init() {
// TODO Auto-generated method stub
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
InputStream inputStream;
try {
inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
sqlSessionFactory = builder.build(inputStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void queryUserByQueryVo() {
// TODO Auto-generated method stub
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
QueryVo queryVo = new QueryVo();
User user = new User();
user.setUsername("刘");
queryVo.setUser(user);
List<User> list = mapper.queryUserByQueryVo(queryVo);
for (User user2 : list) {
System.out.println(user2);
}
sqlSession.close();
}
}
13.自定义别名
<typeAliases>
<!-- 单个别名定义 -->
<typeAlias alias="user" type="cn.itcast.mybatis.pojo.User" />
<!-- 批量别名定义,扫描整个包下的类,别名为类名(大小写不敏感) -->
<package name="cn.itcast.mybatis.pojo" />
<package name="其它包" />
</typeAliases>
14.resultMap resultType可以指定将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。 如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 , resultMap实质上还需要将查询结果映射到pojo对象中。
<resultMap type="order" id="orderResultMap">
<!-- 定义主键 ,非常重要。如果是多个字段,则定义多个id -->
<!-- property:主键在pojo中的属性名 -->
<!-- column:主键在数据库中的列名 -->
<id property="id" column="id" />
<!-- 定义普通属性 -->
<result property="userId" column="user_id" />
</resultMap>
15.动态sql maper.xml:
<select id="queryOrderById" parameterType="int" resultMap="orderResultMap">
SELECT <include refid="queryOrderByIdSql"/> FROM orders
<!-- 动态设置查询条件 -->
<where>
<!--普通类型要写成 _parameter-->
<if test=" _parameter != null">
<!-- 普通输入变量需改为_parameter -->
id = #{ _parameter}
</if>
</where>
</select>
16.Sql片段 Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。
<!-- 声明sql片段 -->
<sql id="userFields">
id, username, birthday, sex, address
</sql>
<!-- 使用include标签加载sql片段;refid是sql片段id -->
<select>
SELECT <include refid="userFields" /> FROM `user`
</select>
17.foreach标签 向sql传递数组或List,mybatis使用foreach解析
<select id="queryUserByIds" parameterType="queryVo" resultType="user">
SELECT * FROM `user`
<where>
<!-- foreach标签,进行遍历 -->
<!-- collection:遍历的集合,这里是QueryVo的ids属性 -->
<!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致 -->
<!-- open:在前面添加的sql片段 -->
<!-- close:在结尾处添加的sql片段 -->
<!-- separator:指定遍历的元素之间使用的分隔符 -->
<foreach collection="ids" item="item" open="id IN (" close=")"
separator=",">
#{item}
</foreach>
</where>
</select>
18.关联查询 两个表联合查询 (1)使用resultType 创建一个新的pojo,属性为需要查询的结果属性。 (2)使用resultType 在 Order 类中加入 User属性(将整个User类当做一个属性)
<resultMap type="order" id="orderUserResultMap">
<id property="id" column="id" />
<result property="userId" column="user_id" />
<result property="number" column="number" />
<result property="createtime" column="createtime" />
<result property="note" column="note" />
<!-- association :配置一对一属性 -->
<!-- property:order里面的User属性名 -->
<!-- javaType:属性类型 -->
<association property="user" javaType="user">
<!-- id:声明主键,表示user_id是关联查询对象的唯一标识-->
<id property="id" column="user_id" />
<result property="username" column="username" />
<result property="address" column="address" />
</association>
</resultMap>