Mybatis及其使用

Mybatis及其使用

一、MyBatis的基础用法

mybatis-3.4.4.jar

https://github.com/mybatis/mybatis-3/releases

    MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old JavaObjects,普通的 Java对象)映射成数据库中的记录。

1.1、从 XML 中构建 SqlSessionFactory

    每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以通过SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。从 XML 文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。但是也可以使用任意的输入流(InputStream)实例,包括字符串形式的文件路径或者 file:// 的 URL 形式的文件路径来配置。MyBatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,可使从 classpath 或其他位置加载资源文件更加容易。
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

1.2、从 SqlSessionFactory 中获取 SqlSession

     既然有了 SqlSessionFactory ,顾名思义,我们就可以从中获得 SqlSession 的实例了。SqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
SqlSession session = sqlSessionFactory.openSession();
try {
  Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
} finally {
  session.close();
}

1.3、示例

1、全局配置文件
<?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>  
        <typeAlias type="com.data.UserDao" alias="UserDao" />  
    </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://10.108.171.181:3306/mybatis?characterEncoding=GBK" />  
                <property name="username" value="root" />  
                <property name="password" value="www1234" />  
            </dataSource>  
        </environment>  
    </environments>  
      
    <!-- 配置mappers -->  
    <mappers>  
        <mapper resource="conf/userdao.xml" />  
    </mappers>  
      
</configuration>
2、Mapper文件
<?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.data.UserDao">
    <select id="getUser" parameterType="int" resultType="UserDao">
        select * from users where age = #{age}
    </select>
    <insert id="insert" flushCache="true" parameterType="UserDao">
	    insert into users (id, name, age) values (
	    	#{id}, #{name}, #{age}
	    )
	</insert>
	<!-- 对应userDao中的updateUser方法 -->
   <update id="update" parameterType="UserDao">
           update users set name = #{name}, age = #{age} where id = #{id};
   </update>
    
   <!-- 对应userDao中的deleteUser 方法 --> 
   <delete id="delete" parameterType="int">
           delete from users where id = #{id};
   </delete>
</mapper>
3、应用实现
public class Main {
	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		System.out.println(System.getProperty("user.dir"));
		String resource = "conf/mybatis-config.xml";  
	    Reader reader = Resources.getResourceAsReader(resource);  
	    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();  
	    SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(reader); 
	    SqlSession session = sqlSessionFactory.openSession();
//	    String statement0 = "com.data.UserDao.insert";
//	    UserDao user0 = new UserDao(5,"www9527",30);
//	    session.insert(statement0, user0);
//	    session.commit();
//	    String statement1 = "com.data.UserDao.update";
//	    UserDao user1 = new UserDao(5,"www2759",30);
//	    session.update(statement1, user1);
//	    session.commit();
	    
	    String statement1 = "com.data.UserDao.delete";
	    session.update(statement1, 5);
	    session.commit();
	    
	    String statement3= "com.data.UserDao.getUser";
	    //UserDao user = session.selectOne(statement);
	    List<UserDao> users = new ArrayList<UserDao>();
        users = session.selectList(statement3,30);
        System.out.println(users);
	}

}

二、原始dao和代理Mapper

2.1、原始dao

2.1.1、编程步骤

1、  根据需求创建po类

2、  编写全局配置文件

3、  根据需求编写映射文件

4、  加载映射文件

5、  编写dao接口

6、  编写dao实现类

7、  编写测试代码

2.1.2、原始Dao实现

1、编写dao接口
public interface UserDao {  
    // 1、 根据用户ID查询用户信息  
    public User findUserById(int id) throws Exception;  
  
    // 2、 根据用户名称模糊查询用户列表  
    public List<User> findUsersByName(String name) throws Exception;  
  
    // 3、 添加用户  
    public void insertUser(User user) throws Exception;  
  
}
2、dao接口实现
public class UserDaoImpl implements UserDao {  
  
    // 依赖注入  
    private SqlSessionFactory sqlSessionFactory;  
        //使用构造方法来初始化SqlSessionFactory  
    public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {  
        this.sqlSessionFactory = sqlSessionFactory;  
    }  
  
    @Override  
    public User findUserById(int id) throws Exception {  
        // 通过工厂在方法内部获取sqlsession,这样可以避免线程安全问题  
        SqlSession sqlSession = sqlSessionFactory.openSession();  
        // 调用SqlSession的增删改查方法  
        // 第一个参数:表示statement的唯一标示  
        User user = sqlSession.selectOne("test.findUserById", id);  
        System.out.println(user);  
        // 关闭资源  
        sqlSession.close();  
        return user;  
    }  
  
    @Override  
    public List<User> findUsersByName(String name) {  
        // 创建SqlSession  
        SqlSession sqlSession = sqlSessionFactory.openSession();  
  
        // 调用SqlSession的增删改查方法  
        // 第一个参数:表示statement的唯一标示  
        List<User> list = sqlSession.selectOne("test.findUsersByName", name);  
        System.out.println(list);  
        // 关闭资源  
        sqlSession.close();  
        return list;  
    }  
  
    @Override  
    public void insertUser(User user) {  
        // 创建SqlSession  
        SqlSession sqlSession = sqlSessionFactory.openSession();  
  
        // 调用SqlSession的增删改查方法  
        // 第一个参数:表示statement的唯一标示  
        sqlSession.insert("test.insertUser", user);  
  
        System.out.println(user.getId());  
        // 提交事务  
        sqlSession.commit();  
        // 关闭资源  
        sqlSession.close();  
    }  
  
}
3、Test
public class UserDaoTest {  
  
    //声明全局的SqlSessionFactory  
    private SqlSessionFactory sqlSessionFactory;  
      
    @Before  
    public void setUp() throws Exception {  
        // 1、读取配置文件  
        String resource = "SqlMapConfig.xml";  
        InputStream inputStream = Resources.getResourceAsStream(resource);  
        // 2、根据配置文件创建SqlSessionFactory  
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  
    }  
  
    @Test  
    public void testFindUserById() {  
        //构造UserDao对象  
        UserDao userDao = new UserDaoImpl(sqlSessionFactory);  
        //调用UserDao对象的方法  
        User user = userDao.findUserById(1);  
          
        System.out.println(user);  
    }  
  
    @Test  
    public void testFindUsersByName() {  
        //构造UserDao对象  
        UserDao userDao = new UserDaoImpl(sqlSessionFactory);  
        //调用UserDao对象的方法  
        List<User> list = userDao.findUsersByName("小明");  
          
        System.out.println(list);  
    }  
  
    @Test  
    public void testInsertUser() {  
        //构造UserDao对象  
        UserDao userDao = new UserDaoImpl(sqlSessionFactory);  
        //构造User对象  
        User user = new User();  
        user.setUsername("东哥3");  
        user.setAddress("清河宝盛西里3");  
          
        //调用UserDao对象的方法  
        userDao.insertUser(user);  
          
        System.out.println(user.getId());  
    }  
  
} 

4、问题总结

原始dao开发存在一些问题:

存在一定量的模板代码。比如:通过SqlSessionFactory创建SqlSession;调用SqlSession的方法操作数据库;关闭Sqlsession。

存在一些硬编码。调用SqlSession的方法操作数据库时,需要指定statement的id,这里存在了硬编码。

2.2、Mapper代理开发方式

2.2.1、开发规范

1、  mapper接口的全限定名要和mapper映射文件的namespace的值相同。

2、  mapper接口的方法名称要和mapper映射文件中的statement的id相同;

3、  mapper接口的方法参数只能有一个,且类型要和mapper映射文件中statement的parameterType的值保持一致。

4、  mapper接口的返回值类型要和mapper映射文件中statement的resultType值或resultMap中的type值保持一致;

2.2.2、编程步骤

1、  根据需求创建po类

2、  编写全局配置文件

3、  根据需求编写映射文件

4、  加载映射文件

5、  编写mapper接口

6、  编写测试代码

2.2.3、实现

1、Mapper映射文件
<?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:此时用mapper代理方式,它的值必须等于对应mapper接口的全限定名  -->  
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">  
  
    <!-- 根据用户ID,查询用户信息 -->  
    <!--   
        [id]:statement的id,要求在命名空间内唯一    
        [parameterType]:入参的java类型,可是是简单类型、POJO、HashMap  
        [resultType]:查询出的单条结果集对应的java类型  
        [#{}]: 表示一个占位符?  
        [#{id}]:表示该占位符待接收参数的名称为id。注意:如果参数为简单类型时,#{}里面的参数名称可以是任意定义  
     -->  
    <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">  
        SELECT * FROM USER WHERE id = #{id}  
    </select>  
      
      
    <!-- 根据用户名称模糊查询用户信息列表 -->  
    <!--   
        [${}]:表示拼接SQL字符串,即不加解释的原样输出  
        [${value}]:表示要拼接的是简单类型参数。  
         注意:  
        1、如果参数为简单类型时,${}里面的参数名称必须为value   
        2、${}会引起SQL注入,一般情况下不推荐使用。但是有些场景必须使用${},比如order by ${colname}  
    -->  
    <select id="findUsersByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">  
        SELECT * FROM USER WHERE username LIKE '%${value}%'  
    </select>  
      
    <!-- 添加用户之自增主键返回(selectKey方式) -->  
    <!--   
        [selectKey标签]:通过select查询来生成主键  
        [keyProperty]:指定存放生成主键的属性  
        [resultType]:生成主键所对应的Java类型  
        [order]:指定该查询主键SQL语句的执行顺序,相对于insert语句,此时选用AFTER  
        [last_insert_id]:MySQL的函数,要配合insert语句一起使用  
     -->  
    <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">  
        <selectKey keyProperty="id" resultType="int" order="AFTER">  
            SELECT LAST_INSERT_ID()  
        </selectKey>  
        INSERT INTO USER(username,sex,birthday,address) VALUES (#{username},#{sex},#{birthday},#{address})  
    </insert>  
      
</mapper>
2、加载映射文件
在SqlMapConfig.xml文件中:
<!-- 加载mapper -->  
<mappers>  
    <mapper resource="sqlmap/User.xml"/>  
    <mapper resource="mapper/UserMapper.xml"/>  
</mappers>
3、编写UserDao接口一样
public interface UserMapper {  
    //根据用户ID来查询用户信息  
    public User findUserById(int id);  
    //根据用户名称来模糊查询用户信息列表  
    public List<User> findUsersByName(String username);  
    //添加用户  
    public void insertUser(User user);  
}
4、测试类
public class UserMapperTest {  
  
    // 声明全局的SqlSessionFactory  
    private SqlSessionFactory sqlSessionFactory;  
  
    @Before  
    public void setUp() throws Exception {  
        // 1、读取配置文件  
        String resource = "SqlMapConfig.xml";  
        InputStream inputStream = Resources.getResourceAsStream(resource);  
        // 2、根据配置文件创建SqlSessionFactory  
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  
    }  
  
    @Test  
    public void testFindUserById() {  
        // 创建SqlSession  
        SqlSession sqlSession = sqlSessionFactory.openSession();  
        // 通过SqlSession,获取mapper接口的动态代理对象  
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);  
        // 调用mapper对象的方法  
        User user = userMapper.findUserById(1);  
  
        System.out.println(user);  
        // 关闭SqlSession  
        sqlSession.close();  
  
    }  
  
    @Test  
    public void testFindUsersByName() {  
        // 创建SqlSession  
        SqlSession sqlSession = sqlSessionFactory.openSession();  
        // 通过SqlSession,获取mapper接口的动态代理对象  
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);  
        // 调用mapper对象的方法  
        List<User> list = userMapper.findUsersByName("小明");  
  
        System.out.println(list);  
        // 关闭SqlSession  
        sqlSession.close();  
    }  
  
    @Test  
    public void testInsertUser() {  
        // 创建SqlSession  
        SqlSession sqlSession = sqlSessionFactory.openSession();  
        // 通过SqlSession,获取mapper接口的动态代理对象  
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);  
          
        //构造User对象  
        User user = new User();  
        user.setUsername("东哥4");  
        user.setAddress("清河宝盛西里4");  
          
        // 调用mapper对象的方法  
        userMapper.insertUser(user);  
  
        System.out.println(user.getId());  
          
        //执行SqlSession的commit操作  
        sqlSession.commit();  
        // 关闭SqlSession  
        sqlSession.close();  
    }  
  
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值