学习mybatis及Springmvc的一些笔记

来源:互联网 发布:网络打鱼刷分教程 编辑:程序博客网 时间:2024/05/22 00:40

Mybatis:

一个基本配置文件

 Configuration.xml 主要是用来配置mybatis的行为以及数据库的连接信息

Mappers是映射器,基本上是写一个实体类就有一个相应的sql操作xml文档,所以也就是多个映射器。

Environment是环境id,默认的环境和环境 ID 是一目了然的。随你怎么命名,只要保证默认环境要匹配其中一个环境ID。

 

映射的sql文档

ParameterType可以省略

#{id} 当id的值被传入这个sql语句时把id当成一个?号,#把id的值自动加上双引号,并进行预编译相当于执行prepareStatement()语句,#{} 的参数替换是发生在 DBMS 中,而 ${} 则发生在动态解析过程中。

 

使用

 

 

Mybatis返回一个list记录所有结果

xml映射

<mappernamespace="com.yihaomen.mybatis.models.UserMapper">

         <resultMap type="User"id="UserList">
                   <resultproperty="id" column="id" />
                  <resultproperty="userName" column="userName"/>
                   <resultproperty="userAge" column="userAge" />
                   <resultproperty="userAddress" column="userAddress"/>
         </resultMap>


    <selectid="selectUserByID" resultMap="UserList">
        select * from `user`
    </select>

</mapper>

首先说一下sqlSession.selectOne()函数,它只能查询一条数据,如果表中的记录多于一条就会报错,空数据不会报错,也就是说当表中有一条或者没有数据时都会正常执行。

但如果想查询多条结果呢,就需要指定resultMap了,不仅要添加resultMap,还要在下面的sql具体语句中将resultType给改为resultMap

使用;

 java.util.List<User>L = session.selectList("com.yihaomen.mybatis.models.UserMapper.selectUserByID");
        for (User u : L) {
                System.out.println(u.getId()+u.getUserName()+u.getUserAge()+u.getUserAddress());}

 

 

mybatis使用接口编程

1.     通过在接口中添加注解的方式

   package com.yihaomen.mybatis.inter;

importorg.apache.ibatis.annotations.Select;

import com.yihaomen.mybatis.model.User;;

public interface IUserOperation {

         @Select("select* from User where id=#{id}")

         public UserselectUserByID(int id);

}

*一个xml映射似乎只能放一个映射器mapper,mappers只能在mybatis的基本配置Configuration中出现,不能在xml映射中出现。

添加完成注解后,

</mapper>

         <mappernamespace="com.yihaomen.mybatis.inter.IUserOperation"></mapper>

</mappers>

Xml映射如上,就没有了sql语句,调用时正常调用就行

IUserOperation iUserOperation = session.getMapper(IUserOperation.class);

     User u =iUserOperation.selectUserByID(1);

 System.out.println(u.getUserName()+u.getUserAddress());

2.  通过xml+dao的方式

Dao层代码:只实现了方法名不需要方法体

package com.yihaomen.mybatis.inter;

import org.apache.ibatis.annotations.Select;

import com.yihaomen.mybatis.model.User;;

public interface IUserOperation {

         public UserselectUserByID(int id);

}

 

Xml:select id需要与接口里的方法一致

<mappernamespace="com.yihaomen.mybatis.inter.IUserOperation" >

         <selectid="selectUserByID" resultType="User">

        select *from `user` where id = #{id}

    </select>

         </mapper>

调用无变化

 

增删改

Insert:

Xml映射文档insert和update中有useGeneratedKeys、keyProperty、keyColumn,如果表中的有数据是自增的,使用useGeneratedKeys来设定为true,keyProperty是指定自增的列名,keyColumn是当第一个字段不是自增是使用。

 

Xml映射文档:

<mappernamespace="com.yihaomen.mybatis.inter.IUserOperation">

    <selectid="selectUserByID"resultType="User">

        select * from `user` where id = #{id}

    </select>

   

    <insertid="insertUser"parameterType="User">

    insertinto user (id,userName,userAge,userAddress) values(#{id},#{userName},#{userAge},#{userAddress})

    </insert>

    </mapper>

Dao层:

import com.yihaomen.mybatis.model.User;;

public interface IUserOperation {

    public UserselectUserByID(intid);

    public void insertUser(User u);

}

 

调用时需要注意,sqlsession有一个commit()函数,需要提交一下:,增加后,必须提交事务,否则不会写入到数据库.

public static void main(String[] args) {

        SqlSession session = sqlSessionFactory.openSession();

        try{

      

        IUserOperation iUserOperation =session.getMapper(IUserOperation.class);

        User u =iUserOperation.selectUserByID(1);

        System.out.println(u.getUserName()+u.getUserAddress());

       

        User u1 = newUser();

        u1.setId(14);

        u1.setUserAddress("aaa");

        u1.setUserAge("42");

        u1.setUserName("12wq");

        iUserOperation.insertUser(u1);

        session.commit();

                } finally{

        session.close();

        }

}

 

 

Update:也需要commit()

Xml配置文件:

    <updateid="updateUser"parameterType="User">

         updateUser set UserName = #{userName} where id=#{id}

</update>

Dao层:

public void updateUser(User u);

调用:

  User u2 = newUser();

        u2.setId(14);

        u2.setUserName("qqqq");

       iUserOperation.updateUser(u2);

    session.commit();

 

delete:与上面类似

 

多表查询:多对一,例如有用户表和文章表,一个用户可以发表多个文章。

这个时候就需要resultMapassociation来结合使用了。文章表中有用户的id,这个时候虽然文章表中只有用户的属性,在建立实体类封装时依然要给文章这个类存入User,而不是Userid

多表查询xml映射有两种配置方法:

(1)将一的result写入association中,把association放入多的resultMap

 

这里存在一个问题,如果数据库中的文章表的字段和用户的字段一样的(如上面的id),mybatis就只能查出第一条数据,怎么解决呢?在xml的映射中resultMap里把column设置成别名,在下面的select的sql的语句里相应部分也给设成别名。如下面的xml映射就将article的id设置了别名(另:property应该是数据库或者实体类中的字段名,column可以修改应该是mybatis映射的字段名):

<mappernamespace="com.yihaomen.mybatis.inter.IUserOperation">

    <resultMap type="Article"id="resultMapList">

        <idproperty="id"column="aid"/>

        <resultproperty="title"column="title"/>

        <resultproperty="content"column="content"/>

        <associationproperty="user"javaType="User">

         <idproperty="id"column="id"/>

         <resultproperty="userName"column="userName"/>

          <resultproperty="userAge"column="userAge"/>

           <resultproperty="userAddress"column="userAddress"/>

        </association>

    </resultMap>

    <selectid="selectArticleUser"resultMap="resultMapList">

        select user.userName,user.userAddress,article.id aid fromuser,article

        where user.id=article.userid ;

    </select>

</mapper>

 

(2)xml映射的第二种写法:

将一的内容写入resultMap中,放在多的内容外,多的内容除了写多的内容,只加入association,而association中不用再加入内容,但是需要在association中多设置一个resultmap指向刚设置好的一的resultmapid

<resultMapid="usermap"type="User">

        <resultproperty="id"column="id"/>

        <resultproperty="userName"column="userName"/>

        <resultproperty="userAge"column="userAge"/>

        <resultproperty="userAddress"column="userAddress"/>

    </resultMap>

   

    <resultMaptype="Article"id="articleMap">

        <resultproperty="id"column="aid"/>

        <resultproperty="title"column="title"/>

        <resultproperty="content"column="content"/>

        <associationproperty="user"javaType="User"resultMap="usermap"/>

    </resultMap>

    <selectid="selectArticleUser"resultMap="articleMap">

        select user.userName,user.userAddress,article.id aid fromuser,article

        where user.id=article.userid ;

</select>

 

两种映射的比较,第二种方法相当于把association里面的内容给抽取出来了,这样别的resultMap也可以使用

 

 

 

Dao层:publicList<Article> selectArticleUser();

调用:

        List<Article> articles =iUserOperation.selectArticleUser();

        for(Articlearticle:articles){

            System.out.println(

                      "名字:"+article.getUser().getUserName()+""+"地址:"+article.getUser().getUserAddress()

                  +"文章内容:"+article.getContent()+articles.size());

        }

 

 

另:需要注意一点,如果调用时打印出在xml映射的selectsql中没有查的字段会打印出null,如上面articlecontent就是null

 

Mybatis 与 Spring的集合

在配置Spring的配置文件时遇到一个很恶心的事情,因为xml中的priperty配置时少些了一个斜杠,老是报

Caused by: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 18 in XML document from class path resource[config/applicationContext.xml] is invalid; nested exception isorg.xml.sax.SAXParseException; lineNumber: 18; columnNumber: 45;cvc-complex-type.2.4.a:发现了以元素 'property' 开头的无效内容。应以 '{"http://www.springframework.org/schema/beans":description,"http://www.springframework.org/schema/beans":meta,"http://www.springframework.org/schema/beans":bean,"http://www.springframework.org/schema/beans":ref,"http://www.springframework.org/schema/beans":idref,"http://www.springframework.org/schema/beans":value,"http://www.springframework.org/schema/beans":null,"http://www.springframework.org/schema/beans":array,"http://www.springframework.org/schema/beans":list,"http://www.springframework.org/schema/beans":set,"http://www.springframework.org/schema/beans":map,"http://www.springframework.org/schema/beans":props, WC[##other:"http://www.springframework.org/schema/beans"]}'之一开头。

    at

这样的错误,一直以为是xml的头文件的引用错误,找了半天,最后终于发现了是少了一个斜杠引起的。

首先需要一个spring配置文件

<?xmlversion="1.0"encoding="utf-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xmlns:aop="http://www.springframework.org/schema/aop"

   xmlns:tx="http://www.springframework.org/schema/tx"

   xmlns:context="http://www.springframework.org/schema/context"

   xsi:schemaLocation=

           http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd 

           http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.0.xsd 

           http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsd 

           http://www.springframework.org/schema/jeehttp://www.springframework.org/schema/jee/spring-jee-3.0.xsd 

            http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.0.xsd" 

            default-autowire="byName"default-lazy-init="false">

 

<beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource">

     <propertyname="driverClassName"value="com.mysql.jdbc.Driver"/>

     <propertyname="url"value="jdbc:mysql://127.0.0.1:3306/test"/>

    <propertyname="username"value="root"/> 

     <propertyname="password"value="root"/>

  </bean>

 

  <beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean">

     <!--dataSource属性指定要用到的连接池-->

     <propertyname="dataSource"ref="dataSource"/>

     <!--configLocation属性指定mybatis的核心配置文件-->

     <propertyname="configLocation"value="config/Configuration.xml"/>

  </bean>

 

  <beanid="userMapper"class="org.mybatis.spring.mapper.MapperFactoryBean">

     <!--sqlSessionFactory属性指定要用到的SqlSessionFactory实例-->

     <propertyname="sqlSessionFactory"ref="sqlSessionFactory"/>

     <!--mapperInterface属性指定映射器接口,用于实现此接口并生成映射器对象-->

     <propertyname="mapperInterface"value="com.yihaomen.mybatis.inter.IUserOperation"/>

  </bean></beans>

 

 

这里以applicationContext-mybatis.xml来体现,配置了如下信息:

 

注册数据源,常见的有JDBCJNDI,根据具体情况择一。

注册sqlSessionFactory

sqlSessionFactory是用来生产sqlSession以操作数据库的,所以,需指定sqlSessionFactory所引用的数据源

指定相应的SQL Mapper文件在哪里。我们自命名“_mapper后缀的xml文件”,主要用来定义SQL;“_resultmap后缀的xml文件”,则主要用来定义DB字段与应用程序实体属性的映射。

指定相应的应用程序实体在哪里,并自动注册不包含package名的别名

在哪些package下扫描Mapper接口,即DAO接口

 

调用:

private static ApplicationContext ctx;

   

    static{

        ctx = new ClassPathXmlApplicationContext("config/applicationContext.xml");

        //mybatis里这一步是加载configuration.xml,而在这里这一步变成了加载Spring的配置文件

    }

   

    public static void main(String []args){

        IUserOperation mapperIUserOperation = (IUserOperation) ctx.getBean("userMapper");

        //mybatis里这一步是使用sqlsessiongetMapper来加载接口的class文件,而在这却是使用Springxml配置的bean来找到那个接口

        System.out.print("--------------\n");

               

List<Article> arList =mapperIUserOperation.selectArticleUser();

       

        for (Article article :arList){

        System.out.println("--"+article.getContent()+"--"+article.getTitle()+"--"+article.getId()+"--"+article.getUser().getUserName());

           

        }

}

 

 

 

Mybatis与Spring与Springmvc的集合

Web.xml的配置信息

包含Spring的基本配置文档

包含Springmvc的分发器的基本文档

<context-param>

          <param-name>contextConfigLocation</param-name>

          <param-value>

              classpath*:config/applicationContext.xml

         </param-value>

     </context-param>

     <!-- 配置Spring上下文监听器,它的作用就是在启动WEB容器时,就会自动装在我们applicationContext.xml配置-->

     <listener>

         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

     </listener>

 

 

<servlet>

    <servlet-name>mvc-dispatcher</servlet-name>

    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <init-param>

            <param-name>contextConfigLocation</param-name>

            <param-value>classpath:config/springmvc-servlet.xml</param-value>

    </init-param>

    <load-on-startup>1</load-on-startup>

  </servlet>

  <servlet-mapping>

    <servlet-name>mvc-dispatcher</servlet-name>

    <url-pattern>/</url-pattern>

  </servlet-mapping>

 

Spring的Applicationcontext.xml文档

包含数据库的配置

包含一些service层的注册bean

包含sqlsession工厂的配置

包含与Spring集合的mybatis的基本文档信息

包含接口的注册bean

<beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource"

        destroy-method="close"p:driverClassName="com.mysql.jdbc.Driver"

        p:url="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8"

        p:username="root"p:password="root"

        >

</bean>

<context:component-scanbase-package="com.test.service"/>

 

 

<beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean">

     <!--dataSource属性指定要用到的连接池-->

     <propertyname="dataSource"ref="dataSource"/>

     <!--configLocation属性指定mybatis的核心配置文件-->

     <propertyname="configLocation"value="classpath:config/Configuration.xml"/>

 

<!-- 所有配置的mapper文件 通过ClassPathXmlApplicationContextgetbean()时传入小写的接口名 -->

     <propertyname="mapperLocations"value="classpath*:com/test/mapper/*.xml"/>

  </bean>

 

Mybatis的配置信息

包含实体类的别名配置

<configuration>

    <typeAliases>

        <typeAliasalias="User"type="com.test.model.User"/>

        <typeAliasalias="Article"type="com.test.model.Article"/>

    </typeAliases>

</configuration>

映射Xml

 

 

调用:

@Controller

@RequestMapping("/mvc")

public class UserController {

    @Autowired

 

    ArticleInter art;

    @RequestMapping("/list")

    @ResponseBody

    public void show (HttpServletRequest request,HttpServletResponse response)throwsIOException{

       

        PrintWriter pw = response.getWriter();

           List<Article>list = art.getListArticle();

           for(Article article : list) {

        System.out.println(article.getId()+"--"+article.getTitle()+article.getContent()+"--"+article.getUser().getUserAddress());

        pw.write(article.getId()+"--"+article.getTitle()+article.getContent()+"--"+article.getUser().getUserAddress());

           

       

        pw.write("123");

    }

}

}

 

遇到一个问题,在运行时一直报接口的方法的空指针的错误,调试之后发现接口的值为空,

十一月 16, 2017 1:23:44 下午 org.apache.catalina.core.StandardWrapperValve invoke
严重: Servlet.service() for servlet [mvc-dispatcher] in context with path [/TheNewTest] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at com.test.controller.UserController.show(UserController.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:100)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:604)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:565)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1457)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

后来发现是少了@Autowired,它的作用是对于bean当中引用的其他bean不需要我们自己去配置它该使用哪个类,Spring 的自动装配可以帮助我们完成这些工作。

 



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果充电不开机怎么办 三星note4摔黑屏怎么办 手机屏慢慢黑屏怎么办 华为手机外屏坏了怎么办 手机屏幕摔开了怎么办 iphone完全坏了怎么办 苹果屏幕盖不严怎么办 苹果手机频幕摔坏了怎么办 平板触屏不灵怎么办 小米触屏不灵怎么办 6s屏幕不灵怎么办 苹果6sp变弯后怎么办 苹果关不了机怎么办 小米手机屏幕乱点怎么办 iphone6s卡屏了怎么办 苹果手机屏幕动不了怎么办 苹果手机滑不动怎么办 升级失败白苹果怎么办 6s屏幕不准怎么办 苹果4s充不进电怎么办 苹果4sbi锁怎么办 乐视pro3充电慢怎么办 手机屏幕触碰不灵敏怎么办 手机换屏幕失灵怎么办 手机图标有重影怎么办 苹果屏幕太灵敏怎么办 5s触摸不灵敏怎么办 导航触屏失灵怎么办 汽车导航触摸屏失灵怎么办 爱丽舍导航仪触屏失灵怎么办 手机要开机很久怎么办 小米手机屏失灵怎么办 5s手机屏幕松动怎么办 手机按钮不灵了怎么办 手机触摸屏不灵了怎么办 mac触摸板失灵怎么办 苹果屏幕触摸失灵怎么办 三星手机屏幕没反应怎么办 手机开机定屏怎么办 手机触摸局部失灵怎么办 苹果手机屏幕按键失灵怎么办