Java框架之Mybatis(一)

一、Mybatis 简介

Mybatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为Mybatis  , 2013年11月迁移到Github , iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)Mybatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。Mybatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。Mybatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

二、Mybatis 的执行框架

1) SqlMapConfig.xml 文件 //名称不一定是这个名称 类似hibernate中的主配置文件

主配置文件 配置数据源,事务等运行环境,配置映射文件 (xxXmapper.xml... 多个)

2) SessionFactory

会话工厂,它是根据配置文件创建的,用来创建  SqlSession

3) SqlSession

会话 ,是一个接口,面向用户的接口,主要用来进行数据库操作

4) Executor

执行器,是底层封装的一个对象,是一个接口(底层有两个实现,基本执行器,缓存执行器)事实上 SqlSession 的内部就是通过该接口来执行sql语句的

5) MappedStatement 底层封装的对象,封装sql ,输入参数,输出结果类型等

三、第一个hello world 程序

1) 导包

asm-3.3.1.jar

cglib-2.2.2.jar

commons-logging-1.1.1.jar

javassist-3.17.1-GA.jar

log4j-1.2.17.jar

log4j-api-2.0-rc1.jar

log4j-core-2.0-rc1.jar

Mybatis-3.2.6.jar

slf4j-api-1.7.5.jar

slf4j-log4j12-1.7.5.jar

2) 在config里建一个配置文件(数据库相关的) mydbconfig.properties , 内容如下

db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/shop
db.username=admin
db.password=root

3) 建立 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>
                <properties resource="mydbconfig.properties" />

                <environments default="development">
                    <environment id="development">
                        <transactionManager type="JDBC" />
                        <dataSource type="POOLED">  //POOLED指的是org.apache.ibatis.datasource.pooled.PooledDataSource, 一个数据源的实现类
                            <property name="driver" value="${db.driver}" />
                            <property name="url" value="${db.url}" />
                            <property name="username" value="${db.username}" />
                            <property name="password" value="${db.password}" />
                        </dataSource>
                    </environment>
                </environments>

                 <mappers>
                    <mapper resource="sqlmap/UserInfo.xml" />
                </mappers>
            </configuration>   

4) 编写映射文件 (其实就是bean 对应的映射文件 相当于 hibernate 中的 UsesrInfo.hbm.xml 之类的 )

命名规则 :

== UserInfo.xml  //过去的ibatis中

== 如果使用了mapper 代理  命名规则变为  UserInfoMapper.xml

 //UserInfo.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="test">
                    <select id="getuser_byid"  parameterType="int" resultType="cat.beans.UserInfo" >
                        select * from userInfo where id=#{id}  //如是简单类型,id可以写成任意名字
                    </select>
</mapper>

说明: namespace 是命名空间,用来对sql进行隔离 ,注意,如果使用mapper代理的方式开发,它就有特殊的作用

-- <select id="getuser_byid" ... > 这个id 就是sql的标识,其实将来要封装到 MappedStatement 中

-- #{ } 代表占位

--  如是参数是简单类型,{} 中的名字可以任意

--  resultType 表示返回的java对象的类型,表示要将查询结果映射成什么样的java对象

5) 在主配置文件中引入这个映射文件

主配置文件中加入

<mappers>
         <mapper resource="sqlmap/UserInfo.xml" />
</mappers>
//上面的主配置文件中其实已经加入了

6)测试

static void test(){
//加载主配置文件
            InputStream in=Test.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");
            //InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");    //Resources是mhybatis 提供的

            SqlSessionFactory factor=new SqlSessionFactoryBuilder().build(in);
            SqlSession session =factor.openSession();

                                                   //第一个参数,是sql的id (是映射文件中的statement的id) = 名称空间+sql的id名称 ,
            UserInfo user=session.selectOne("test.getuser_byid",1); //注意,这里的1 不能定成 "1"
            System.out.println(user);
            session.close();
            }

在上例的基础上,再添一个模糊查询的例子

在 UserInfo.xml 中 加入

<select id="getuser_biname" parameterType="string" resultType="cat.beans.UserInfo">
//select * from userInfo where userName  like #{value}   //不行,  它会拼成like ‘张三‘
select * from userInfo where userName like  ‘%${value}%‘  // ${value} 表示会把传过来的值,直接拼到串上,有可能有sql注入问题,而且
// 如果parameterType 是简单类型,则${ } 中间的必须写成 value
</select>
static void test() throws IOException{
                    InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
                    SqlSessionFactory factor=new SqlSessionFactoryBuilder().build(in);
                    SqlSession session =factor.openSession();

                    UserInfo user=session.selectOne("test.getuser_byid",1); //注意,这里的1 不能定成 "1"
                    System.out.println(user);

                    session.close();

                }

总结:

#{} Mybatis 将  #{} 解释为jdbc PreparedStatement  的一个参数标记  // 就是 select * from t where id= ? 中的 ?

${} 将它直接解释为字符串

理解这两者的区别是很有用的, 因为在某些SQL语句中并不能使用参数标记(parameter markers)。

那如果有like查询要怎么办呢? 可以这样sql写成第一种 #{} ,传参的时候如下

"%张三%"
selectOne   //返回一个对象
selectList  //返回一组对象 两者 resultType="cat.beans.UserInfo" 都正常

在上例的基础上,再增加一个添加用户的功能

//对于添加这类方法,是没有resultType的
<insert id="add_user" parameterType="cat.beans.UserInfo"  >
        insert into userInfo (userName,password,note) values (#{userName},#{password}, #{note} ) //后面不要写上分号
</insert>
        tatic void test3() throws IOException{

                        InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
                        SqlSessionFactory factor=new SqlSessionFactoryBuilder().build(in);
                        SqlSession session =factor.openSession();

                        UserInfo user=new UserInfo();
                        user.setUserName("陈鹏飞");
                        user.setPassword("admin");
                        user.setNote("这是备注");

                        int result=session.insert("test.add_user",user); 

// 对于inser,虽然没有为sql声明反回类型,但也能正确的取到反回值的,它是整型

                        session.commit(); //不要忘了提交事务
                        System.out.println(result); //能得到正确的值  1

                        session.close();
                    }

在上面的基础上,再添加删除的和修改的功能

<delete id="deluser_byid" parameterType="int" >
                    delete from userInfo where id=#{id}
                </delete>

                <update id="update_user" parameterType="cat.beans.UserInfo" > <!-- 传过来的userInfo对象中要有id -->
                   update userInfo set userName= #{userName},password= #{password}, note =#{note} where id= #{id}
                </update>
//修改
                    static void test4() throws IOException{

                        InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
                        SqlSessionFactory factor=new SqlSessionFactoryBuilder().build(in);
                        SqlSession session =factor.openSession();

                        UserInfo user=session.selectOne("test.getuser_byid",1);
                        user.setUserName("english");
                        user.setPassword("englishxxx");
                        user.setNote("englishxxx");
                      int result= session.update("test.update_user",user);
                      session.commit();
                      System.out.println("修改成功: " + result);

                        session.close();
                    }

                 //删除
                    static void test5() throws IOException{
                        InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
                        SqlSessionFactory factor=new SqlSessionFactoryBuilder().build(in);
                        SqlSession session =factor.openSession();
                        int result= session.delete("test.deluser_byid",10);
                        session.commit();
                        System.out.println("删除成功: " + result);
                        session.close();
                    }

四、返回自增主键

mysql 有一个函数 last_insert_id() 可以调用它得到最后一条插入语句生成的自增主键。

在上面的用户添加的例子上

<insert id="add_user" parameterType="cat.beans.UserInfo"  >
        <selectKey order="AFTER" keyProperty="id" resultType="int">   //resultType 必填 keyProperty的id 就是userInfo.id
                      select  last_insert_id()
                     //elect new uuid();  //这是mysql生成uui的写法 (32位数字或字母,4位是 -)  如果这样,上面的AFTER要改成before
                     //select 序列名.nextval 这是oracle中的写法
       </selectKey>
                insert into userInfo (userName,password,note) values (#{userName},#{password}, #{note} )
</insert>

说明:

order="AFTER" 指的是 要在这条语句执行之后取得生成的主键,它还有另一个取值 BEFORE

非自增主键,想取得,要用BEFORE,但生成主键的方式应该是上面的红色的注起来的方式。

注意,如果用的是后面的方式,则下面的sql要写上id

例子:生成 uuid型的主键

 <insert id="add_user_new" parameterType="cat.beans.UserInfo"  >
                <selectKey order="BEFORE" keyProperty="id" resultType="string">   //注意返回类型,注意前面要写成 BEFORE
                    select  uuid()
                </selectKey>
                insert into userInfo (id,userName,password,note) values (#{id},#{userName},#{password}, #{note} )
                //注意要把id这列也写上
            </insert>

                UserInfo user=new UserInfo();
            //user.setId() 不用写了,因为主键由Mybatis生成

                user.setUserName("郑某某");
                user.setPassword("admin");
                user.setNote("这是备注");

                session.insert("test.add_user_new",user);
                session.commit(); 

                System.out.println(user.getId());  //可以取到主键 369010c6-e631-1033-b927-e281dfdaa6b0

五、dao层的开发

SessionFactory 可以做成单例 (未来会交给Spring管理)

SqlSession  是线程不安全的, 用的时候,要在方法体内 , 这样它就是一个局部变量,千万不要把它写成类成员

Mybatis 开发DAO 有两种方式

原始的方式 ,手写dao 和实现类

//接口 :
public interface IUserDao {
                    int addUser(UserInfo user);
                    UserInfo getUserById(int id);
                }

//实现类
public class UserDaoImplTest {
                    private IUserDao _dao ;
                    @Before
                    public void setUp() throws Exception {
                        InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
                        SqlSessionFactory factor=new SqlSessionFactoryBuilder().build(in);
                        _dao=new UserDaoImpl(factor);
                    }

                    @Test
                    public void testAddUser() {
                        UserInfo user=new UserInfo();
                        user.setUserName("周周");
                        user.setPassword("admin");

                        int result=_dao.addUser(user);
                        System.out.println("ok"+result);
                    }

                    @Test
                    public void testGetUserById() {
                        UserInfo user=_dao.getUserById(2);
                        System.out.println(user);
                    }

                }

测试用例

使用 mapper 代理的方式  ,只需要mapper接口 (相当于dao接口)

public class UserDaoImpl implements IUserDao {
                private SqlSessionFactory _factory;

                public UserDaoImpl(SqlSessionFactory factory){
                    this._factory=factory;  //由外界注入 SqlSessionFactory
                }

                //添加用户
                public int addUser(UserInfo user) {
                    SqlSession s =_factory.openSession();
                    int result=s.insert("test.add_user",user);
                    s.commit();
                    return result;
                }

                //查询用户
                public UserInfo getUserById(int id) {
                    SqlSession s =_factory.openSession();
                    UserInfo user=s.selectOne("test.getuser_byid",id);
                    s.commit();
                    return user;
                }

            }

配置文件

<mapper namespace="test">
                <select id="getuser_byid"  parameterType="int" resultType="cat.beans.UserInfo" >
                    select * from userInfo where id=#{id}
                </select>

                <insert id="add_user" parameterType="cat.beans.UserInfo"  >
                    <selectKey order="AFTER" keyProperty="id" resultType="int">
                        select  last_insert_id()
                    </selectKey>
                    insert into userInfo (userName,password,note) values (#{userName},#{password}, #{note} )
                </insert>

                 ... 其他的略

            </mapper>

原文地址:https://www.cnblogs.com/1693977889zz/p/8227416.html

时间: 2024-11-08 23:06:27

Java框架之Mybatis(一)的相关文章

Java框架篇---Mybatis 入门

一.Mybatis介绍 MyBatis是一款一流的支持自定义SQL.存储过程和高级映射的持久化框架.MyBatis几乎消除了所有的JDBC代码,也基本不需要手工去设置参数和获取检索结果.MyBatis能够使用简单的XML格式或者注解进行来配置,能够映射基本数据元素.Map接口和POJOs(普通java对象)到数据库中的记录. 二.MyBatis工作流程 (1)加载配置并初始化 触发条件:加载配置文件 配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个个M

Java框架之Mybatis(二)

本文主要介绍 Mybatis(一)之后剩下的内容: 1 mybatis 中 log4j的配置 2 dao层的开发(使用mapper代理的方式) 3 mybatis的配置详解 4 输入输出映射对应的类型 ( parameterType 和 resultType ) 5 mybatis 动态 sql 6 mybatis 中的一级缓存 7 mybatis 中的二级缓存 8 mybatis 和 缓存框架的整合 9 mybatis 中二级缓存使用时注意的问题 10 mybatis 和 spring 整合

java框架之mybatis

一.简介 1.概念 mybatis 是一个半自动轻量级的一个 orm 框架 2.作用 将 java 与 sql 分离,解决了 jdbc 的硬编码问题,方便 sql 的修改: sql 由开发人员控制,更加方便 sql 的调优: 3.快速开始 (1)原始方法 建一个全局配置文件,里面是数据源等运行环境的信息: 建立一个sql 的映射文件,并将这个文件注册到全局的配置中: 根据全局的配置文件获得一个 sqlsessionfactory: 通过 factory 获得 sqlsession(非线程安全),

Java框架之MyBatis 06-全局配置-mapper映射-分步查询

MyBatis MyBatis是Apache的一个开源项目iBatis, iBatis一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架. iBatis  提供的持久层框架包括SQL Maps和Data Access Objects(DAO) Mybatis 是一个 半自动的ORM(Object   Relation  Mapping)框架 sql和java编码分开,功能边界清晰,一个专注业务.一个专注数据 MyBatis全局配置 MyBatis全局配置文件结

Java框架之MyBatis 07-动态SQL-缓存机制-逆向工程-分页插件

MyBatis 今天大年初一,你在学习!不学习做什么,斗地主...人都凑不齐.学习吧,学习使我快乐!除了诗和远方还有责任,我也想担当,我也想负责,可臣妾做不到啊,怎么办?你说怎么办,为啥人家能做到你做不到,因为人家比你多做了那么一点点.哪一点点?就那么一点点,只要你也多做那么一点点,不就做到了!...就那么一点点呀,我回顾SE去了.万丈高楼平地起,基础打的牢,怕什么狂风暴雨 MyBatis 动态SQL MyBatis为了解决通过一些不确定性的条件进行SQL语句的拼接操作的问题, 提供了动态SQL

Java框架篇---Mybatis 构建SqlSessionFactory

从 XML 中构建 SqlSessionFactory 基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的.SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得.而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例. 从 XML 文件中构建 SqlSessionFactory

Java开发之Mybatis框架

mybasits配置文件书写1.configer文件配置<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><

javaEE 后台框架 SpringMVC Mybatis Shiro Bootstrap HTML

升级报捷:通过服务于服务之间调用,生成二维码,可直接用户手机app(详细查看截图) 框架集成lucene搜索引擎,使您的信息在毫秒内抓取(详细查看截图) 1.  创建.初始化索引.统一搜索入口.搜索结果展现--内容.标题高亮.关键词搜索 2.  高级搜索:高级搜索增加多入口查询(精确查询.模糊查询.前缀查询等),每页显示条数自定义.索引结果数据设置.选择索引文档类型等 3. 通过A系统调用B系统的Rest服务,生成相关的二维码,可以直接用户手机app ----------------------

[Java面试七]Mybatis总结以及在面试中的一些问题.

1.JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的? ① 数据库链接创建.释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题. 解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接. ② Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码. 解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离. ③ 向sql语句传参数麻烦,因为sql语句的where条件不