mybatis的熟练运用以及反射知识讲解

2023-11-16

JSP常用设计模式MVC模式——Mybatis

mybatis的使用

我们在写项目的时候必定要写DAO,写DAO的时候不难发现对每张表的DAO都差不多,只是sql语句不同,DAO中的每个方法其实也差不多,所以直接用JDBC写DAO是在太麻烦,今天我们就介绍一种很实用的框架——mybatis,这个框架能让我们更愉快地写DAO。

3集 :mybatis使用步骤

第一步:先创建一个xml的配置文件来说明和数据库的连接,一般在项目的src下创建。下面的代码是基本的mybatis语句,懒得每个标签写注释了,自己去查帮助文档吧,都有;

<?xml version="1.0" encoding="UTF-8"?>

<!--下面这句话作用就是限制xml文件按照某种语法来进行编辑,有了这句话,我们在联网的状态下编辑这个xml文件时就会有代码提示  -->

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

<properties resource="jdbc.properties"/><!-- 导入配置文件jdbc.properties 中的内容-->

<environments default="development"><!--此时,默认使用的环境是名为development的环境-->

<environment id="development">

<transactionManager type="JDBC"/><!--设置事务管理模式为JDBC-->

<dataSource type="POOLED">

<property name="driver" value="${driver}"/>

        <property name="url" value="${url}"/>

        <property name="username" value="${user}"/>

        <property name="password" value="${password}"/>

</dataSource>

</environment>

</environments>

</configuration>

jdbc.properties中的内容

user=phoenix

password=123

url=jdbc:mysql://localhost:3306/myshop

driver=com.mysql.jdbc.Driver

第二步:连接完成了,接下来我们就要根据我们建好的数据库的表创建实体类,比如说我创建了一个用户User的实体类,为了省空间咱就把GET和SET方法去了;

public class User {

private int id;

private String username;

private String password;

private String nickname;

private boolean type;

}

第三步:创建mapper文件完成对实体类的映射,该文件同样是xml文件,比如说我们创建一个User的mapper文件User.xml;

<?xml version="1.0" encoding="UTF-8"?>

<!--下面这句话是加入mapperdtd文件,和之前的连接配置文件已经不同了  -->

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="model.User"><!--这个namespace我们可以自定义一个名称-->

<!--下面的程序就是往数据库添加User记录的语句-->

<insert id="add" parameterType="model.User"><!--id是名称的意思,parameterType意思是传入参数的类型,我们这里插入的是User类型的记录,所以parameterType的值是model.User  -->

     <!--下面的语句中#{}中的内容就是model包中User类的属性名,mybatis会调用花括号中的属性名的getter方法来获取传入的User类型的参数的对应属性值,从而添加到数据库中-->

insert into t_user (username,password,nickname) value

                          (#{username},#{password},#{nickname})

 <!--mybatis#{}的取值方式和PreparedStatement中的?是一样的,如果传入的是字符串,会自动带上单引号加到SQL语句中;mybatis还有一种取值方式就是${},这种就是原样导入,不加任何修饰,当我们要对提取结果按某个字段排序时就要用到order by后面跟字段名,此时就需要这种原样导入方式来导入字段名-->

 <!--每个sql标签中我们只能有一个传入参数,当传入参数是基本数据类型或String时,此时标签中的sql语句只可能有一个待传参数,所以此时#{}中的内容可以任意设置,反正只有一个传入参数和一个待传参数,跑不了;那我们想传入多个基本参数怎么办呢,那就传入一个Map类型的参数,将要传入的基本类型参数塞进Map中,#{}中的内容必须和Map中的key一致;当传入参数是一个对象时比如User,此时#{}中的内容就必须是User的属性名。-->

</insert>

</mapper>

对于上面的insert标签中,只要我们传入的参数是model包中的User类,就必须让parameterType属性的值为model.User,很麻烦。其实我们可以将下面的话添加到mybatis-config.xml文件中,注意,必须添加到properties标签后面,这些标签是有顺序的

<typeAliases>

<typeAlias type="model.User" alias="User"/><!--为类型model.User定义一个别名为User,这里这么做是为了在mapper文件中写DAO时某传入参数如果是model.User就可以简写成User-->

</typeAliases>

此时我们就能将parameterType的值写成User。

可是我的model包中有很多类,如果懒得一条一条添加映射,可以这么写:

<typeAliases>

<package name="model"/>

</typeAliases>

这样程序就会把model包中的所有类遍历一遍,只要在这个包中的所有类作为传入参数时就都不用写包名。

第四步:首先我们先把mapper文件加入到配置文件中,于是原来的mybatis-config文件就变成了如下;

<?xml version="1.0" encoding="UTF-8"?>

<!--下面这句话作用就是限制xml文件按照某种语法来进行编辑,有了这句话,我们在联网的状态下编辑这个xml文件时就会有代码提示  -->

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

<properties resource="jdbc.properties"/><!-- 导入配置文件jdbc.properties 中的内容-->

<environments default="development">

<environment id="development">

<transactionManager type="JDBC"/><!--设置事务管理为JDBC-->

<dataSource type="POOLED">

<property name="driver" value="${driver}"/>

        <property name="url" value="${url}"/>

        <property name="username" value="${user}"/>

        <property name="password" value="${password}"/>

</dataSource>

</environment>

</environments>

<!--将mapper文件加入到配置文件中  -->

<mappers>

<mapper resource="model/User.xml"/>

</mappers>

</configuration>

然后我们创建SQLSession,并且通过SQLSession完成对数据库的操作;

import java.io.IOException;

import java.io.InputStream;

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class Test {

public static void main(String[] args) {

try {

//1、创建配置文件的输入流

InputStream is=Resources.getResourceAsStream("mybatis-config.xml");

//2、创建SQLSessionFactory

SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is);

//3、创建SQLSession

SqlSession session=factory.openSession();

//4、调用mapper文件插入数据(调用之前要将mapper文件加入到mybatis-config.xml配置文件之中)

User u=new User();

u.setUsername("李白");u.setPassword("123");u.setNickname("诗仙");

session.insert("model.User.add", u);//第一个参数是User的mapper文件中的namespace的值和insert的Id值为了使不把程序写死,第一个参数也可以写成User.class.getName()+.add

session.commit();//提交事务

session.close();//提交完关闭事物

} catch (IOException e) {

e.printStackTrace();

}

}

}

 

还有一种方法可以完成对数据库的操作——基于mapper的访问方式:

首先我们创建一个名为UserMapper的Interface,Interface中的方法名必须和User.xml中mapper中的方法标签中的id属性完全一样

public interface UserMapper {

public void add(User u);

public void delete(int id);

public void update(User u);

public User load(int id);

}

然后修改User的mapper文件User.xml,mapper标签的namespace属性必须修改成上面接口的路径,如果上面的UserMapper在Interface包中,那么我们就修改成:

<mapper namespace="Interface.UserMapper">

接着在用SqlSession调用添加方法的时候就可以这么调用

session.getMapper(UserMapper.class).add(u);

 

在这种调用方式下,我们介绍一种超级牛逼的操作——基于Annotation的数据库操作,我们可以直接对UserMapper接口进行如下改写:

public interface UserMapper {

@Insert("insert into t_user (username,password,nickname) value (#{usename},#{password},#{nickname})")

public void add(User u);

 

@Delete("delete from t_user where id=#{id}")

public void delete(int id);

 

@Update("update t_user set username=#{username},password=#{password},nickname=#{nickname} where id=#{id}")

public void update(User u);

 

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

public User load(int id);

 

@Select("select * from t_user")

public List<User> list();

}

然后修改mybatis-config.xml文件,将原来导入配置文件的mapper全部删掉,然后将mappers标签改成如下:

<mappers>

<mapper class="Interface.UserMapper"/>

</mappers>

调用方法的时候就用上面介绍的SqlSession调用增删改查方法。这种方式直接省去了为每一个类创建mapper文件的麻烦,直接创建接口,在接口上添加sql语句就行。

 

动态SQL语句:

直接上例子,这里是常用的,其它只是直接找帮助文档

<select id="find" parameterType="map" resultType="User">

select * from t_user

<where><!--where语句中的内容-->

<if test="name!=null">username like #{name}</if>

<if test="type!=null">and type=#{type} </if><!--如果前面的name为空,而这里的type不为空,这里的sql语句会自动去掉and -->

</where>

        <!-- 上面这一段还可以这样写,这种写法很聪明,要记住

         select * from t_user where 1=1

<if test="type!=null">and type=#{type}</if>

<if test="name!=null">and name like #{name}</if> -->

<if test="sort!=null">

 order by ${sort}

 <choose>

  <when test="order!=null">${order}</when>

  <otherwise>asc</otherwise><!--这个就相当于if else-->

 </choose>

 </if>

limit #{pagerOffset},#{dataCount}

</select>

 

resultMap的讲解:

在我们的shop01项目中,我们在数据库中创建了一个表t_Address,表的创建信息如下:

create table t_address(

id int(11) primary key auto_increment,

name varchar(255),

phone varchar(100),

postcode varchar(100),

user_id int(11),

constraint foreign key (user_id) references t_user(id)

);

相对应的,我们也创建了一个Address的类,类信息如下(为了方便咱就把getset方法省略了):

public class Address {

private int id;

private String name;

private String phone;

private String postcode;

private User user;

}

这个时候,我们在Address的Mapper文件中写了一个loadById的方法:

<select id="loadById" parameterType="int" resultType="Address">

select * from t_address where id=#{id}

</select>

语句很简单,就是传入参数是int类型,然后返回值是Address。那么,mybatis是怎么把sql语句搜索到的结果返回成一个Address对象呢?

其实mybatis背地里干了这么一件事:它看到搜索结果中有id字段,那就去Address中去找有没有setId方法,有就把id字段的值通过setId方法赋给Address的id属性,接着看到有name字段,就去找有没有setName方法,这样以此类推。这是一种依赖注入的赋值方式,其实id字段的值能不能赋出去,关键看有没有setId方法,而无关乎Address是否有个名为id的属性,但我们一般情况下还是不要调皮,好好设置属性,使用编辑器的GetSet功能就行,一定要让属性名和GetSet方法的名称一一对应。

那此时我将数据表中的postcode字段改成post_code后再来运行loadById,mybatis就会去找有没有setPost_code方法,而此时Address中根本没有setPost_code方法,于是post_code的值就给不了。

这只是我们自己编编的小项目,到大项目的时候数据表的字段名几乎不可能和类名中的属性名一致,那怎么办呢?解决办法有两种:

第一种就是直接对搜索结果的字段名重命名

<select id="loadById" parameterType="int" resultType="Address">

select *,post_code as ‘postcode’ from t_address where id=#{id}

</select>

还有一种就是我们要讲的resultMap

<resultMap id="addressResultMap" type="Address"><!--type是字段名要映射到的类的类名 -->

<!--这里的result标签是为普通字段设置映射用的,column是字段名,property是要映射的类中的属性名 。还有一种专为主键设置映射用的标签,就是id标签,设置主键的映射使用这个标签会提高整体效能-->

<result column="post_code" property="postcode"/>

</resultMap>

<select id="loadById" parameterType="int" resultMap="addressResultMap"><!--这里的resultMap的值就是上面resultMap的id值  -->

select * from t_address where id=#{id}

</select>

我们知道,上面的Address类中是没有user_id属性的,只有User类型的user属性,而搜索结果中只有user_id字段,那么用resultMap的association标签就能帮我们通过user_id字段的值来获得整个User

<resultMap id="addressResultMap" type="Address"><!--type是字段名要映射到的类的类名 -->

<!--property是Address类的某个要关联的属性名,column是数据表中的字段名,javaType是设置将选择结果封装成什么类型,select是选用哪个mapper中的哪个方法 -->

<association property="user" column="user_id" javaType="User" select="model.User.loadById"></association>

</resultMap>

使用这个方法mybatis实际上是发出了两条sql语句,一条搜索t_address,一条搜索t_user。所以使用这种方法不好的地方就是效率不高,所以我们一般使用下面的方法得到User对象:

<resultMap id="addressResultMap" type="Address" autoMapping="true">

<!--resultMap中如果有association标签的话,resultMap中未声明映射的字段就不会自动匹配类中的属性 ,所以这里就必须设置autoMapping为true。然而association标签中为声明映射的字段依然不会自动匹配,所以我们不得不手动设置映射-->

<id column="a_id" property="id"/>

<association property="user" javaType="User">

<id column="id" property="id"/>

<result column="username" property="username"/>

<result column="password" property="password"/>

<result column="nickname" property="nickname"/>

<result column="type" property="type"/>

</association>

</resultMap>

<select id="loadById" parameterType="int" resultMap="addressResultMap"><!--这里的resultMap的值就是上面resultMap的id值  -->

select *,t_address.id as 'a_id'

from t_address left join t_user on (t_address.id=t_user.id)

where t_address.id=#{id}

</select>

当然也可以这么干,这样就有了一个公用的User的resultMap

<resultMap id="addressResultMap" type="Address" autoMapping="true">

<id column="a_id" property="id"/>

<association property="user" javaType="User" resultMap="UserMap">

</association>

</resultMap>

<resultMap id="UserMap" type="User">

<id column="id" property="id"/>

<result column="username" property="username"/>

<result column="password" property="password"/>

<result column="nickname" property="nickname"/>

<result column="type" property="type"/>

</resultMap>

<select id="loadById" parameterType="int" resultMap="addressResultMap">

select *,t_address.id as 'a_id'

from t_address left join t_user on (t_address.id=t_user.id)

where t_address.id=#{id}

</select>

 

工厂模式——反射知识

以前我们创建一个实例都是很简单地new就行了,今天我们讲一个很牛逼的新的实例创建模式。首先我们创建一个User类,getset方法就省略了:

public class User {

private int id;

private String name;

 public void show(String str){

 System.out.println(str+","+this.id+", "+this.name);

 }

 

 public static void say(String str, int num){

 System.out.println("天上的"+str+"有"+num+"颗");

 }

}

接着我们就直接Test(catch实在太多了,我们也省了):

public class Test {

public static void main(String[] args) {

String str="itta.zttc.model.User";

try {

Class cla=Class.forName(str);

User u=(User)cla.newInstance();

u.setId(1);u.setName("新的创建对象方式");

u.show("hello");//正常输出

//新的函数调用方式

Method method=cla.getMethod("show", String.class);//第一个参数是函数名称的字符串,第二个参数是函数的参数,个数可以是1个或无限多个

//第一个参数是调用这个函数的对象,第二个参数是传入参数,就相当于u.show("hello2");

method.invoke(u, "hello2");//正常输出

//还可以调用静态函数,调用的时候invoke方法的第一个参数必须写类的Class形式

method=cla.getMethod("say",String.class,int.class);

method.invoke(cla, "星星",5);//正常输出

}

}

 

工厂1:

架构图

 

DAOFactory程序:

public class DAOFactory {

public static UserDAOInterface getUserDAO(){

return UserDAO.getUserDAO();

}

public static AddressDAOInterface getAddressDAO(){

return AddressDAO.getAddressDAO();

}

}

在程序中要用到DAO时,就通过DAOFactory来获得,要换针对不同数据库的DAO就直接在DAOFactory中改就行了。

工厂2:

架构图:

 

DAOFactoryUtil的getFactory程序:

public static IDAOFactory getFactory(){

IDAOFactory factory=null;

try {

Class cla=Class.forName(p.getProperty("factory"));

Method method=cla.getMethod("getDAOFactory");//这里提取的方法是目标DAOFactory的获取单例的方法

factory=(IDAOFactory)method.invoke(cla);

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (NoSuchMethodException e) {

e.printStackTrace();

} catch (SecurityException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

}

return factory;

}

在程序中要用到DAO 时,我们需要通过DAOFactoryUtil的getFactory方法来获得我们想要的DAOFactory,然后通过得到的DAOFactory得到相应的DAO,然后运用DAO的某个方法。举个例子:DAOFactoryUtil.getFactory().getUserDAO().add(user);

工厂3:

架构图:

 

DAOFactory中的getDAO方法程序:

private static Map<String,Object> params=new HashMap<String,Object>();

public static Object getDAO(String name){

Properties p=PropertiesUtil.getProperties();

Object obj=null;

try {

String str=p.getProperty(name);

if(params.containsKey(str)){

return params.get(str);

}

Class cla=Class.forName(str);

obj=cla.newInstance();

params.put(str,obj);

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

return obj;

}

程序中的params是为了实现单例,所以其实架构图中的UserDAO和AddressDAO可以不用单例。如果UserDAO和AddressDAO中用了单例,那就必须在这里获取到他们的单例获取方法才行。

在程序中要用到某个DAO时,我们就可以这么用:

IUserDAO uDAO=(IUserDAO)DAOFactoryUtil.getFactory().getDAO(“UserDAO”);

依赖注入:

当一个项目有很多数据表时,我们就必须建立很多对应的DAO,这些DAO都继承于BaseDAO。当我们对某个数据表执行某个操作时,可能必须先对另一个数据表执行操作,例如我们在留言项目中遇到过删除留言之前必须先删除留言的评论才行,这种情况下就必须在留言DAO中创建一个评论的DAO。

我们一般的创建方法就是在留言DAO中创建一个ICommentDAO,然后用上面的方法得到相应的ICommentDAO,然后在留言DAO的增删改查方法中用到评论DAO时就用这个ICommentDAO就行了。

但是我们要介绍一种新方式去给ICommentDAO赋值,就是在留言DAO中先private ICommentDAO commentDAO;,然后创建这个属性的set方法。

接着我们创建一个Annotation(下面的UserDAO就看成CommentDAO就行,懒得改了):

/*

 * 我们使用这个Annotation来标注需要进行依赖注入的方法

 * 如果方法上面是@shopAnnotation("userDAO")就说明应该注入UserDAO对象

 * 如果方法上面是@shopAnnotation就说明该方法使用setXXX来注入,如果方法是setUserDAO表示注入UserDAO对象

 * */

@Retention(RetentionPolicy.RUNTIME)//这句话表示在运行时刻执行Annotation,没有这句话的话程序只会在编译的时候检测这个Annotation,运行时刻是不会检测的

public @interface shopAnnotation {

/*

 * 表示为这个Annotation加上了一个名为str的属性,default ""表示这个属性默认值为"",如果没有default,那必须在使用这个Annotation的时候这样定义

 * @shopAnnotation(str="hello")

 * */

String str() default "";

/*

 * value是Annotation唯一的默认属性,在定义value的值的时候可以直接这样定义@shopAnnotation("hello")

 * 特别注意:当要为两个以上的属性赋值的时候,默认属性的直接定义特权就不起作用了,也就是说@shopAnnotation("hello",str="world")是会报错的

 * */

String value() default "";

}

 

接着我们在BaseDAO中创建一个构造方法:

public BaseDAO(){

Method[] methods=this.getClass().getDeclaredMethods();

for(Method method:methods){

if(method.isAnnotationPresent(shopAnnotation.class)){//判断方法头上是否有某个Annotation的约束,没有我们预设的Annotation那就不用理这个方法

shopAnnotation sA=method.getAnnotation(shopAnnotation.class);

String value=sA.value();

if(value==null||"".equals(value.trim())){//判断方法上的Annotation是不是有value值

if(method.getName().startsWith("set")){

value=method.getName().substring(3);

}

}

if(value!=null){

Object obj=DAOFactory.getDAO(value);

try {

method.invoke(this, obj);//这里的传入参数我有点问题

} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {

e.printStackTrace();

}

}

}

}

}

然后我们在留言DAO中的setCommentDAO()方法上面加上我们的Annotation,可以为value赋值为CommentDAO,也可以不赋值。这样当留言DAO的单例初始化的时候,就会调用setCommentDAO方法为ICommentDAO赋值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mybatis的熟练运用以及反射知识讲解 的相关文章

  • Java简单加密

    我想加密存储在磁盘上的文本 配置 文件 尝试使用DES http en wikipedia org wiki Data Encryption Standard加密 我在客户端计算机上遇到了致命错误 后来我发现该算法无法处理重音字符 我怀疑这
  • 如何更改 JComboBox 下拉列表的宽度?

    我有一个可编辑的JComboBox其中包含单个字母值的列表 因此 组合框非常小 每个字母都有特殊的含义 对于很少使用的字母 有时用户并不清楚 因此我创建了一个自定义ListCellRenderer显示下拉列表中每个字母的含义 不幸的是 这个
  • 在游戏框架中编写功能测试的正确方法

    在为基于 play1 2 4 的 web 应用程序编写功能测试时 我对如何正确编码感到有点困惑 困惑在于所涉及的事务边界 我在某处读到每个测试都有自己的事务 在我的应用程序中 用户可以登录并向购物车添加一些商品 然后他可以提供一个地址 以便
  • Java - 了解 PrintWriter 和刷新的需要

    好吧 首先我对所有代码表示歉意 但我觉得代码太多总比代码不够好 我正在制作一个简单的聊天客户端和印刷机 尤其是我正在努力解决的问题 使用现在的代码 它将与服务器类交互 并且完美地打印我想要打印的内容 但是 当我删除 writer flush
  • ORMLite - join where 子句中的括号

    我想使用连接三个表QueryBuilder join and QueryBuilder joinor但我想在 where 子句中添加括号 如下所示 WHERE first table where AND second table where
  • BigDecimal 中 Divide 方法的 Scale()

    new BigDecimal 37146555 53880000 divide new BigDecimal 1000000 scale 这返回10 但根据API divide method 返回一个 BigDecimal 其值为 这个 除
  • Eclipse 内容协助无法在枚举常量参数列表中工作

    使用 eclipse 当我输入以下内容时 public enum Foo A Integer private final Integer integer private Foo Integer integer this integer in
  • java模拟自定义对象

    public class MainClass public void makeCall CustomObject obj new CustomObject obj testMethod 我想进行单元测试makeCall 所以我必须嘲笑Cus
  • IntelliJ Idea,如何从控制台删除java文件目录?

    当您运行文件时 它会打开控制台窗口 并且一直在顶部显示该文件所在的目录 这非常令人恼火 因为现在 为了将其他行与目录混合分开 我必须在启动任何 System out println 命令之前使用 n C Program FILEs 我想摆脱
  • 在Tomcat中设置环境变量TESSDATA_PREFIX

    我们正在使用名为 Tess4J 的 Tesseract OCR Java 库 如果作为独立应用程序运行 它可以正常工作 它需要一个名为 TESSDATA PREFIX 的变量 其中包含 tessdata 配置和其他字符集相关文件 它也可以与
  • JavaFX 动画使用循环?

    我正在尝试制作一款类似太空侵略者的游戏 我画了一个正方形 我想通过使用循环逐步向下移动它thread sleep 然而 正方形立即被绘制出来 我知道有可以使用的动画路径 但我想保持低水平并仅使用坐标系 有没有办法使用这样的循环来制作时间轴动
  • Java中的运算符重载和覆盖

    运算符重载和运算符重写有什么区别 它们在继承和控制台程序中是否相同 Java 不支持运算符重载和重写 检查以下引用自的描述 http java sun com docs white langenv Simple doc2 html http
  • 酷还是傻? Catch(异常[NamingException, CreateException] e)

    我正在编写一些代码 我注意到异常处理中的一种模式让我思考 try do stuff throws JMS Create and NamingException catch NamingException e log1 e rollback
  • 在 JSF 自定义验证器中区分 ajax 请求和完整请求

    我的验证器需要知道它是完整请求还是 ajax 请求 在我当前的解决方案中 我检查 http 请求标头X Requested With元素 public void validate FacesContext context UICompone
  • 不想保留一对一的实体

    假设我有两节课Employee and Department In Employee我已经写了 OneToOne fetch FetchType EAGER cascade CascadeType ALL JoinColumn name d
  • org.apache.catalina.core.JreMemoryLeakPreventionListener 中急切调用 URLConnection 的 setDefaultUseCaches(false) 是什么原因

    这个问题可能有点难以找到答案 这是一个系列中的问题考虑使用 Policy getPolicy 的原因是什么 因为它将保留对上下文的静态引用并可能导致内存泄漏 https stackoverflow com questions 7057421
  • JavaFX 中的 MVC 模式与场景生成器

    我是 JavaFX 新手 根据我当前的设置 正在努力创建合适的 MVC 架构 我使用 Scene Builder 单击了一个 UI 并指定了一个 Controller 类 Startup public class Portal extend
  • 如何使用 Kafka 发送大消息(超过 15MB)?

    我发送字符串消息到Kafka V 0 8使用 Java Producer API 如果消息大小约为 15 MB 我会得到MessageSizeTooLargeException 我尝试过设置message max bytes到 40 MB
  • Java分数计算器

    我对 Java 编程还很陌生 我的 AP 计算机编程课程有作业要完成 所以请耐心等待 我必须弄清楚如何将两个分数相乘 我想知道是否有任何方法可以在方法内部声明变量并在该方法外部使用它 我在介绍方法中的 while 循环 谢谢您 希望这不会令
  • Java:如何检测(并更改?)System.console 的编码?

    我有一个在控制台上运行的程序 其变音符号和其他特殊字符在 Mac 上以 的形式输出 这是一个简单的测试程序 public static void main String args System out println h h System

随机推荐

  • 蓝桥杯经验分享

    作为已经入码坑的一员 在开始接触的时候一窍不通 老师讲完之后自己再写一遍都写不出来的那种 很是沮丧 失落 后来到了大二 逐渐的找到了感觉 在学习了诸如C C java python之后 感觉诸多编程语言殊途同归 编者观点 学习编程语言入手最
  • IDEA文件右键创建New没有Create New Servlet的解决办法

    Author codepig16 interesting wtsb7 1 问题描述 创建了一个Javaweb项目但是在src中右键创建中 没有Servlet选项 如下图所示 2 解决方案 解决方案分为三步 笔者本人是在第三步有问题 估计大部
  • Qt中左侧列表与右侧窗口关联

    左边列表选项与右边窗体关联 QListWidget list new QListWidget this list gt insertItem 0 tr Window1 list gt insertItem 1 tr Window2 QLab
  • C++ 多线程学习(二) 互斥锁std::mutex

    在多线程中经常会遇到多个线程同时修改同一个变量的情况 这个时候如果不对线程进行一定约束 很可能会导致意想不到的结果 例如有两个线程1和线程2 线程2的输入是线程1的结果 很显然如果在主线程中同时开启了线程1和线程2 它们是同时运行的 会直接
  • 华为机考108题(c++)(52-61)

    HJ52 计算字符串的编辑距离 描述 Levenshtein 距离 又称编辑距离 指的是两个字符串之间 由一个转换成另一个所需的最少编辑操作次数 许可的编辑操作包括将一个字符替换成另一个字符 插入一个字符 删除一个字符 编辑距离的算法是首先
  • 顺序表详解 —— 初始化、销毁、打印、增加、删除、查找、修改

    文章目录 顺序表介绍 初始化顺序表 销毁顺序表 打印顺序表 增加数据 头插 尾插 指定下标位置插入 删除数据 头删 尾删 指定下标位置删除 查找数据 修改数据 顺序表介绍 顺序表是在计算机内存中以数组的形式保存的线性表 线性表的顺序存储是指
  • Spark基础知识(个人总结)

    声明 1 本文为我的个人复习总结 并非那种从零基础开始普及知识 内容详细全面 言辞官方的文章 2 由于是个人总结 所以用最精简的话语来写文章 3 若有错误不当之处 请指出 一 Spark概述 Spark模块 Core SQL Streami
  • js字符串转数字

    1 通过Number 函数传入一个合法的字符串参数 可以把字符串转换成一个十进制整数 十进制字符串可以带小数 其它进制我试过都不能有小数 否则返回NaN 11 其实也是调用的Number 11 进行减 乘 除运算时 字符串的自动转换也是调用
  • Redis数据类型常用命令

    Redis数据类型常用命令 Redis Key String 字符串 List 列表 Set 集合 Hash 哈希 Zset 有序集合 三种特殊数据类型 Geospatial地理位置 Hyperloglog 基数 Bitmap 位图 位存储
  • R语言-ggplot2柱状堆叠图

    导入数据 load D R futures user 2 dat 提取需要画图的数据 a futures user 2 c 1 2 5 对部分错误的数据进行修改 a province which a province 广西桂林 lt 广西
  • Node 16版本和 node-sass 兼容性问题

    我电脑上的node版本是16 13 1 运行刚克隆下来的项目时 npm install 报错 gyp err 百度之后确定是node sass版本兼容性问题 项目的package json文件版本如下 devDependencies nod
  • str.charAt(i);的作用

    在java中 有 String str leetcode 则 str charAt 0 为 l str charAt 1 为 e str charAt 2 为 e
  • 拉格朗日插值

    直接上公式 简单的讲 这个玩意就是在给你若干个 f xi yi 的结果 算出f k 的结果 最朴素的实现方法 验证下这个公式的结果 include
  • 【利用Python module计算程序运算时间】

    本文简介如何利用Python module来计算程序运算时间 内容概览 为什么要计算程序的运行时间 方法一 time module 方法二 timeit module 为什么要计算程序的运行时间 编写程序时 为了比较各种算法或优化算法 需要
  • Typescript 装饰器和反射

    装饰器 装饰器 也叫注解 对一个类 方法 属性 参数的装饰 它是对这一系列代码的增强 并且通过自身描述了被装饰的代码可能存在行为改变 装饰器是一种特殊类型的声明 它能够被附加到类声明 方法 访问符 属性或参数上 装饰器使用 expressi
  • 一篇博文教你SpringMVC中JSON注解&异常处理的使用

    目录 一 JSON数据返回 1 2 Jackson的介绍 1 3 3 案例演示 二 异常处理 2 4 1 异常处理方式 2 4 2 异常处理方式 2 4 3 异常处理方式 一 JSON数据返回 1 1 1 2 Jackson的介绍 1 2
  • steam创客教育

    社会竞争日益激烈 为了让子女将来能 成龙成凤 父母们都非常重视孩子的教育 格物斯坦小坦克看到这样普遍的现象 为了让自己的孩子不输在起跑线上 在各种各样兴趣班盛行的当下 很多家长常常盲目跟风 看到别的孩子学着还不错或升学考试需要 也给自己孩子
  • oracle中sqlload,oracle----sqlldr用法(转)

    SQL LOADER是ORACLE的数据加载工具 通常用来将操作系统文件迁移到ORACLE数据库中 SQL LOADER是大型数据 仓库选择使用的加载方法 因为它提供了最快速的途径 DIRECT PARALLEL 现在 我们抛开其理论不谈
  • elasticsearch 2.3.4 java API 连接,ik分词器,设置集群节点,创建index,mapping的几种方式...

    1 默认集群连接 Client client TransportClient builder build addTransportAddress new InetSocketTransportAddress InetAddress getB
  • mybatis的熟练运用以及反射知识讲解

    JSP常用设计模式MVC模式 Mybatis mybatis的使用 我们在写项目的时候必定要写DAO 写DAO的时候不难发现对每张表的DAO都差不多 只是sql语句不同 DAO中的每个方法其实也差不多 所以直接用JDBC写DAO是在太麻烦