Spring Mybatis与普通方式JDBC获取数据库的方式。

概念 

MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。

  1. 简化JDBC的开发
  2. 能够更好的完成ORM(对象关系映射)

 Spring mybatis的使用方式:

第一步:创建核心配置文件,配置全局文件,数据库,映射文件,加载驱动,合并了配置的相关信息。

//核心映射文件

<?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">
<!-- mybatis的核心配置文件,配置了事务管理,数据源 -->
<configuration>
    <!--environments可以配置多个数据库的连接信息,default指定默认的环境-->
    <environments default="test">
        <environment id="test">
            <!--使用的事务管理器-->
            <transactionManager type="JDBC"></transactionManager>        
            <!--配置了数据源-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>      //加载JDBC驱动
                <property name="url" value="jdbc:mysql://localhost:3306/mybatisdb?characterEncoding=utf8&amp;serverTimezone=Asia/Shanghai" />               //设置访问的数据库
                <property name="username" value="root"/>                  //配置数据库的账号
                <property name="password" value="root"/>                  //配置数据库的密码
            </dataSource>
        </environment>
    </environments>

    <!--引入映射文件-->                            //加载映射文件
    <mappers>
                          映射文件的文件地址
        <mapper resource="UserMapper.xml"></mapper>
    </mappers>

</configuration>

对应的普通JDBC编写方式:

//普通JDBC的编写方式
Class.forName("com.mysql.jdbc.Driver")

String URL = "JDBC:mysql://localhost:3306/mybatisdb?
characterEncoding=utf8&amp;serverTimezone=Asia/Shanghai";

Connection c = DriverManager.getConnection(URL,user,password);

第二步:建立映射文件

<!--映射文件-->

<?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">

<!--这个文件是映射文件,写SQL的,namespace用来作为一个mapper.xml文件的唯一标识-->
<mapper namespace="userMapper">
	<!-- 查id=1的用户信息
        id是这条SQL的唯一标识,名称尽量描述该语句的效果
        resultType的值用来封装查到的结果,ORM-->
	<select id="getById" resultType="cn.tedu.pojo.User">
        select * from user id=1
    </select>
    <!-- 查所有的的用户信息-->
    <select id="getUser" resultType="cn.tedu.pojo.User">
        select * from user
    </select>
</mapper>

对应部分的普通JDBC编写方式:

//普通JDBC的编写方式
String sql="sql语句"
PreparedStatement ps = c.prepareStatement(sql);
        ps.setObject(1,条件1);
        ps.setObject(1,条件2);
        ps.setObject(1,条件3);
        ....

第三步,第四步:建立会话工厂,进行会话,并展示数据

//加载配置文件
InputStream in =  Resources.getResourceAsStream("mybatis-config.xml");

//建立会话工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);

//使用会话工厂建立会话
SqlSession session = factory.openSession();

//使用会话窗口进行会话
Object o = session.selectOne("userMapper.getById");            
//查询需要填入的内容为MXL文件名+查询方法的id值
List<User> list = session.selectList("userMapper.getUser");

//展示数据
System.out.println(o);                            //展示单个数据
System.out.println(list);                         //展示多个数据
for(User u:list){                                 //使用for循环单行展示多个数据
    System.out.println(u);
}

查询需要填入的内容为MXL文件名.查询方法的id值

 Object o = session.selectOne("userMapper.getById"); 

对应部分的普通JDBC编写方式:

//对应部分的普通JDBC编写方式:
ResultSet r = ps.executeQuery();                    //发起查询并返回数据
ps.executeUpdate();                                 //发起增删改数据请求

//展示单个数据
 if(r.next())                                                
        {
            int rId = r.getInt(1);
            String rname = r.getString(2);
            String rAddr = r.getString(3);
            int rAge = r.getInt(4);
        }

//单行展示多个数据
    List<Object> list = null;
    while(r.next())
        {
            for(int i=1;list.add(r.getString(i);i++);
        }
        System.out.println(list);

 Spring mybatis的优点:

后续维护方便:

        1. 与JDBC相比,减少了50%以上的代码量。准备框架的时候需要其他文件作为配置,但是后续只需要修改映射文件即可解决大部分的添加任务,不必重复添加驱动及连接数据库。

        2. MyBatis相当灵活,不会对应用程序或者数据库的现有设计强加任何影响,SQL写在XML里,从程序代码中彻底分离,降低耦合度,便于统一管理和优化,并可重用,维护方便

        3.提供XML标签,支持编写动态SQL语句。

        4.提供映射标签,支持对象与数据库的ORM字段关系映射。

Spring mybatis后续映射文件内sql任务的添加:

<!--sql任务的添加-->

    <!--查询name="sayhi"的所有数据-->
	<select id="getSayhi" resultType="cn.tedu.pojo.User">
        select * from user where name="sayhi"
    </select>
    对应的查询命令:Object sayhi = session.selectOne("userMapper.getsayhi");


    <!--查询user="sayhi"的密码-->
    <select id="getSayhiPass" resultType="cn.tedu.pojo.User">
        select password from user where user="sayhi"
    </select>
    对应的查询命令:Object o = session.selectOne("userMapper.getSayhiPass");

    <!--查询所有的用户名-->
	<select id="getAllUser" resultType="cn.tedu.pojo.User">
        select * from user
    </select>
    对应的查询命令:List<User> list = session.selectList("userMapper.getAllUser");
    //查询到的结果较多,使用selectList来获取一个列表,多个数据,而不是selectOne获取单个数据

    <!--查询特定id的用户信息-->
	<select id="getById" resultType="cn.tedu.pojo.User">
        select * from user where  id=#{id}
    </select>
    对应的查询命令:Object o = session.selectOne("userMapper.getById",2);//查询id=2的用户信息

    <!--查询特定用户的用户信息-->
	<select id="getUser" resultType="cn.tedu.pojo.User">
        select * from user where name=#{name}
    </select>
    对应的查询命令:Object user = session.selectOne("userMapper.getUser","sayhi");
        //查询用户名为sayhi的用户信息

SQL中有特殊字符

当SQL中有特殊字符,mybatis不能正常解析时,

用<![CDATA[ ?? ]]>括起来就解决了 <![CDATA[ and age<=#{age} ]]>

<![CDATA[and age<=#{age}]]>

SQL中的$,¥和#

在须输入查询目标的查询中可以使用$,¥来代替#,但是¥输入的是目标值的本身,不会主动为输入目标添加“”。所以少用或不用$或¥尽量用#

为目标对象添加别名:

为了避免输入别名时出现错误,可以在配置文件中设置别名。简化输入,减少错误

//为目标对象添加别名
    <typeAliases>
        <typeAlias type="cn.tedu.pojo.User" alias="User"/>
         <!--typeAlias type="目标所在的地址" alias="别名"-->
    </typeAliases>

使用接口开发:

为优化SQL的字符串拼接过程,namepase的地方可以采用id的值。

在调用session的方法的时候,都会传入要调用的SQL的namespace+id名称,这不是必须的。可以只传入id即可。但是,如果在mybatis的环境中有多个相同id的映射名称,就会报错。所以,一般情况下,调用方法最好还是使用namespace+id。但是,namespace+id的使用方式很容易报错,因为是string类型的,没有检查。所以,mybatis提供了一种非常好的设计方式来避免这种问题,即Mapper接口。

 <!--使用接口开发-->
<mapper namespace="接口的全路径">
    <!-- 查id=1的部门信息
    id是这条SQL的唯一标识
    resultType的值用来封装查到的结果,ORM
    -->
    <select id="接口的方法" resultType="Dept">
        select * from dept where id=1
    </select>

</mapper>
//接口文件
public interface 接口文件名字{
    返回类型 getById();
}
//查询    命令     
    接口文件名字mapper = session.getMapper(接口文件名字.class);    //获取接口的文件
    Object o = mapper.getById();                           //通过接口调用指定方法
    System.out.println(o);

使用命令获取接口的文件 DeptMapper mapper = session.getMapper(DeptMapper.class); 

mapper 接口文件的对象,DeptMapper.class接口文件

通过接口文件使用接口的方法,通过接口的方法获取值。Object o = mapper.getById();  

        o:最终需要查询的对象,

        mapper.getById():获取对象中的方法

        getById()方法:

         <mapper namespace="接口的全路径">
                <select id="接口的方法" resultType="Dept">
                        select * from dept where id=1
               </select>

         </mapper>

1. 使用接口查询所有的用户名

2.查询特点id的用户名

用户名name,接口文件名为UserMapper,接口方法为getAllUser()

XmL文件:
<mapper namespace="cn.tedu.Dao.UserMapper">
    <!-- 查id=1的部门信息
    id是这条SQL的唯一标识
    resultType的值用来封装查到的结果,ORM
    -->
    <select id="getAllUser" resultType="User">      //id为接口名  resultType为别名
        select name from User                        //sql语句
    </select>
    <select id="getUser" resultType="User">      //id为接口名  resultType为别名
        select name from User where id=#{id}                     //sql语句
    </select>
</mapper>
//接口文件
public interface DeptMapper {            //接口文件名
    List getAllUser();                   //接口方法
    User getUser(int id);                //接口方法
}
//查询语句
   public void get() throws IOException {

        //加载配置文件
        InputStream input = Resources.getResourceAsStream("mybatis-config.xml");

        //建立会话工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(input);

        //建立会话
        SqlSession session= factory.openSession();  
                    
        //加载接口文件
        UserMapper mapper = session.getMapper(UserMapper.class);      

        //使用接口查询  
        List<Object> list = mapper.getAllUser();
        Object o = mapper.getUser();

        //输出查询结果
        System.out.println(list);
        System.out.println(o);
    }

添加数据库的增删改方法

//映射文件
     <insert id="save">
        insert into dept value(#{id},#{dname},#{loc})
    </insert>
    <insert id="add">
        insert into dept value(null,#{dname},#{loc})
    </insert>
 //在接口文件中添加接口
    void save(Dept dept);
    void add(String dname,String loc);
//提交命令     
        Dept dept = new Dept();                                //给与固定的id值插入数据
        dept.setDname("java培训部").setLoc("杭州").setId(100);
        mapper.save(dept);

        mapper.add("java","西安");                           //给与空的id值,让数据库自增添加
        session.commit();//对数据库的增删改都需要自己提交事务!!!!

注意错误1:

org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '10' for key 'PRIMARY'
### The error may exist in DeptMapper.xml
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: insert into dept value(?,?,?)
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '10' for key 'PRIMARY'

原因:id是主键,主键10已有数据,无法重复提交!

注意错误2:提交命令无报错但是数据库不添加数据

提交数据后一定要加入session.commit();

对数据库的增删改都需要自己提交事务!!!

动态SQL

概述:动态sql指利用mybatis框架的一些标签完成SQL的拼接写出更通用,更有效的SQl语句

常用标签:

sql,提取SQL片段

include:引入指定的sql片段

if:满足条件拼接sql,不满足跳过

where:

修改映射文件,实现动态SQL(SQl拼接)

    /*<sql>截取select语句*/
    <sql id="cols">                    /*截取select id,dname,loc from   id值为cols 
       select id,dname,loc from
    </sql>

    <select id="getDname" resultType="Dept">
         //插入截取id值为cols的sql语句:select id,dname,loc from 
        <include refid="cols"></include>      
             dept
        <where>                                    //拼接if并去掉条件中可能多余的and或者or:
        <if test="id!=null">where id=#{id}</if>    //如果id!=null则加入where id=#{id}
        <if test="dname!=null">where dname=#{id}</if>    //如果id!=null则加入where id=#{id}
        </where>
    </select>

方法接口的重载:

在使用动态sql的技术之下,可以做到查询某一个用户与全部用户共用一条语句

    /*<sql>截取select语句*/
    <sql id="cols">                    /*截取select id,name,loc from   id值为cols 
       select id,name,loc from
    </sql>

    <select id="getName" resultType="Dept">
         //插入截取id值为cols的sql语句:select id,name,loc from 
        <include refid="cols"></include>      
             dept
        <where>                                    //拼接if并去掉条件中可能多余的and或者or:
        <if test="id!=null">where id=#{id}</if>    //如果id!=null则加入where id=#{id}
        <if test="dname!=null">where name=#{id}</if>    //如果id!=null则加入where id=#{id}
        </where>
    </select>

此时若是有输入值,则查询对应要求的结果,若是无输入值则查询全部结果,因此延伸出多个接口

getName(Integer id,String name,String loc);

getName(Integer id);

getName(String name);

getName(String loc);

getName();

此时表现得就是接口的重载,虽然输入参数不同,但最终执行的都是同一个select模块。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sayhitoloverOvO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值